Chris O'Byrne - YAVRTOS

task.c File Reference


Defines

#define semaphore_triggered(current, required)   ((current) - (required) >= 0)
 Has a semaphore been triggered?
#define YAVRTOS_TASK_STATE_STARTING   1
 Starting.
#define YAVRTOS_TASK_STATE_RUNNING   2
 Running.
#define YAVRTOS_TASK_STATE_WAITING_TO_STOP   3
 Waiting for the task to release all of its mutexes before stopping.
#define YAVRTOS_TASK_STATE_STOPPING   4
 Stopping.
#define YAVRTOS_TASK_STATE_CLEANING_UP   5
 Cleaning up.
#define YAVRTOS_TASK_STATE_STOPPED   6
 Stopped.
#define set_task_state(taskptr, req_state)   (taskptr)->status = (req_state)
 

For internal use only.

Set the state of a task - this macro makes it easier to put other information into task.status


#define get_task_state(taskptr)   ((taskptr)->status)
 

For internal use only.

Get the state of a task - this macro makes it easier to put other information into task.status


#define executing_isr()   (yavrtos_system.interrupted_task)
 

For internal use only.

Are we currently executing an ISR?


#define rtos_started()   (current_task)
 

For internal use only.

Has the RTOS been started?



Functions

void task_starter ()
 

For internal use only.

The entry point for all tasks


void task_stopper ()
 

For internal use only.

The entry point for all tasks that are stopping


yavrtos_result_t stop_task (task_t *t, uint8_t wait_for_mutexes)
 Stop a task.
task_treserve_task (uint16_t stacklen, uint8_t pri, mutex_t *memory_mutex)
 Tasks are kept in a linked list in memory - this function reserves an "empty" task on that list, ready to be subsequently utilised by a call to create_task().
task_tcreate_task (void(*proc)(void *), void(*cleanup)(), void *init_data, uint16_t stacklen, uint8_t pri, mutex_t *memory_mutex)
 Create a task, ready to be run.
int16_t get_semaphore_value (semaphore_t *s)
 Get the current value of a semaphore.
yavrtos_result_t perform_wait_on_semaphore (semaphore_t *p, int8_t is_increment, int16_t value, semaphore_t *timeout_semaphore, int8_t timeout_is_increment, int16_t timeout_value)
 

For internal use only.

Perform a wait on a semaphore (all "perform wait on semaphore" functions call this one - it keeps the stack usage down).


yavrtos_result_t wait_for_min_value (semaphore_t *p, int16_t value, semaphore_t *timeout_semaphore, int16_t timeout)
 Wait for a semaphore to reach at least a particular value.
yavrtos_result_t wait_for_min_value_timeout (semaphore_t *p, int16_t value, semaphore_t *timeout_semaphore, int16_t timeout_value)
 Wait for a semaphore to reach at least a particular value, but with a set value for the timeout, as opposed to an increment to the timeout semaphore value.
yavrtos_result_t wait_for_increment_of (semaphore_t *p, uint16_t amount, semaphore_t *timeout_semaphore, int16_t timeout)
 Wait for a semaphore to increment its value by a certain amount.
yavrtos_result_t wait_for_increment_of_timeout (semaphore_t *p, uint16_t amount, semaphore_t *timeout_semaphore, int16_t timeout_value)
 Wait for a semaphore to increment its value by a certain amount, but with a set value for the timeout, as opposed to an increment to the timeout semaphore value.
yavrtos_result_t lock_on (mutex_t *m, semaphore_t *timeout_semaphore, int16_t timeout)
 Lock on a mutex.
yavrtos_result_t lock_off (mutex_t *m)
 Unlock a mutex.
void switch_task ()
 

For internal use only.

Perform a task switch.


void increment_semaphore_by (semaphore_t *s, uint16_t amount)
 Increment the value of a semaphore by the given amount.
int16_t get_current_mbox_version (mailbox_t *m)
 Get the current version of a mailbox.
void * read_mbox (mailbox_t *m, int16_t *version)
 Read a mailbox.
void * read_mbox_min_version (mailbox_t *m, int16_t *version, semaphore_t *timeout_semaphore, int16_t timeout)
 Wait for a mailbox to reach at least a certain version, and then start reading from it.
mailbox_trelease_mbox_read ()
 Function to call when finished reading from a mailbox.
void initialise_mbox (mailbox_t *m, void *data, const int16_t version)
 Initialise a mailbox - this must be called on every mailbox before it is used.
int8_t mbox_is_empty (mailbox_t *m)
 Find out if a mailbox is "empty" (i.e. if there is no-one waiting to read it).
yavrtos_result_t write_mbox (mailbox_t *m, void *data, uint8_t wait_for_receivers, uint8_t wait_for_empty_nullify, semaphore_t *timeout_semaphore, int16_t timeout)
 Write to a mailbox.
yavrtos_result_t write_mbox_now (mailbox_t *m, void *data)
 Attempt to write to a mailbox.
yavrtos_result_t wait_for_receiver (mailbox_t *m, semaphore_t *timeout_semaphore, int16_t timeout)
 Wait for a task to be suspended while trying to read from a mailbox.
interrupt_store_t disable_interrupts ()
 Disable interrupts system-wide.
void restore_interrupts (interrupt_store_t interrupts)
 Restore the state of the system-wide interrupts.
void yield ()
 Stop executing the current task and try and execute a higher-priority task or another task of the same priority.
void task_switcher_start (void(*idle)(void *), void *idle_data, uint16_t idle_stacklen, uint16_t system_stacklen)
 Start the whole process running.

Variables

task_tcurrent_task = 0
 The current task.
struct yavrtos_system_struct yavrtos_system = {0}
 

For internal use only.

The system stack, and a flag indicating whether the CPU is currently processing an interrupt



Define Documentation

 
#define executing_isr (  )     (yavrtos_system.interrupted_task)

For internal use only.

Are we currently executing an ISR?

#define get_task_state ( taskptr   )     ((taskptr)->status)

For internal use only.

Get the state of a task - this macro makes it easier to put other information into task.status

 
#define rtos_started (  )     (current_task)

For internal use only.

Has the RTOS been started?

#define semaphore_triggered ( current,
required   )     ((current) - (required) >= 0)

Has a semaphore been triggered?

It is quite critical that this algorithm be correct, even when the semaphore values roll over

#define set_task_state ( taskptr,
req_state   )     (taskptr)->status = (req_state)

For internal use only.

Set the state of a task - this macro makes it easier to put other information into task.status


Function Documentation

int8_t mbox_is_empty ( mailbox_t m  ) 

Find out if a mailbox is "empty" (i.e. if there is no-one waiting to read it).

For internal use only.

Note that interrupts must be disabled before we enter

yavrtos_result_t perform_wait_on_semaphore ( semaphore_t p,
int8_t  is_increment,
int16_t  value,
semaphore_t timeout_semaphore,
int8_t  timeout_is_increment,
int16_t  timeout_value 
)

For internal use only.

Perform a wait on a semaphore (all "perform wait on semaphore" functions call this one - it keeps the stack usage down).

The arguments are

  • p - the semaphore to wait on
  • is_increment - true if the value is an increment to the semaphore value as opposed to an absolute value
  • value - either an increment to the semaphore value to wait for, or the absolute value to wait for
  • timeout_semaphore - a semaphore to use for timing out while waiting on the other semaphore, or 0 if no timeout should be performed
  • timeout_is_increment - true if the timeout_value is an increment to the timeout semaphore value as opposed to an absolute value
  • timeout_value - either an increment to the timeout semaphore value to time out on, or the absolute value of the timeout semaphore value to time out on.
The possible return values are

void switch_task (  ) 

For internal use only.

Perform a task switch.

Note that interrupts must be disabled before we enter. Note also that this function must be programmed so that it never uses the stack!

void task_starter (  ) 

For internal use only.

The entry point for all tasks

First, interrupts are enabled, so that the tick interrupt can happen. Then, the task procedure is executed. When the task procedure exits, if the task priority is zero, it is re-executed. If the task priority isn't zero, the task is shut down.

void task_stopper (  ) 

For internal use only.

The entry point for all tasks that are stopping

If this task is being stopped by a call to stop_task() with the wait_for_mutexes parameter set, then the task will continue to run as normal until the last mutex is released. When that happens, then this task stopper will start running on the task.

First, interrupts are enabled, then any mailbox being read is released

If the task has a cleanup procedure defined (the cleanup argument to create_task()), it is called

Then, the task state is set to stopped, all mutexes and mailboxes are released, the (internal) task stopping semaphore is signalled, and a task switch is executed.


Variable Documentation

For internal use only.

The system stack, and a flag indicating whether the CPU is currently processing an interrupt

For internal use only.

The system_struct used to hold the system stack and a flag indicating whether an ISR is currently being executed


YAVRTOS and YAVRTOS documentation Copyright © 2007-2009 Chris O'Byrne. Email - chris <at> obyrne <dot> com