Tasks

Functions

task_t * task_create (const char *name, void(*entry)(void *), pri_t priority, size_t stack_size, void *arg)
void task_delay (tick_t time)
task_t * task_find (const char *name)
void task_run (task_t *task)
task_t * task_self (void)
task_t * task_spawn (const char *name, void(*entry)(void *), pri_t priority, size_t stack_size, void *arg)
void task_start (task_t *task)
void task_stop (void)
void task_suspend (task_t *task)
void task_resume (task_t *task)
void task_priority_set (pri_t priority)
pri_t task_priority_get (void)
void task_show (void)

Function Documentation

task_t* task_create ( const char *  name,
void(*)(void *)  entry,
pri_t  priority,
size_t  stack_size,
void *  arg 
)

Allocates and initialises a task handle as well as stack space for the task. This function must be called before calling task_run(). The task_spawn() function calls this function automatically. See task_spawn() for further details.

Parameters:
name String describing task
entry The entry function of the task
priority The priority of the task
stack_size The size of the stack (number of bytes)
arg Sent as argument to task
Returns:
The task handle to be used in all subsequent operations on the task
void task_delay ( tick_t  time  ) 

Delays the calling task until the specified amount of ticks have occurred. Note that the next tick may occur soon after calling this function. In other words, if a delay of at least t ticks is required, call task_delay(t + 1).

Calling task_delay() with time set to 0 is equivalent to yielding the processor to another task of the same priority. The task will be swapped out if another task of the same priority is ready to execute.

Parameters:
time The amount of ticks to delay the task
task_t* task_find ( const char *  name  ) 

Finds the task with the given name. If more than one task has the same name, only the first one encountered will be returned.

Parameters:
name String to search for
pri_t task_priority_get ( void   ) 

Get the priority of the calling task.

Returns:
Priority of the calling task.
void task_priority_set ( pri_t  priority  ) 

Set the priority of the calling task.

Parameters:
priority New priority
void task_resume ( task_t *  task  ) 

Resume a task that was previously suspended by a call to task_suspend().

Parameters:
task Handle of the task to resume.
void task_run ( task_t *  task  ) 

Makes a task ready for execution. After calling this function the task will be scheduled for execution as appropriate. This function is called automatically by task_spawn().

Parameters:
task Task handle
task_t* task_self ( void   ) 

Returns the task handle of the calling task.

Returns:
Handle of the calling task.
void task_show ( void   ) 

Prints the task state to stdout using rprintp(). This may prove useful for debugging purposes. This function should not be called from application code, but may be called from e.g. uerror() or an exception handler.

task_t* task_spawn ( const char *  name,
void(*)(void *)  entry,
pri_t  priority,
size_t  stack_size,
void *  arg 
)

Allocates and starts a task in one go. Equivalent to calling task_create() followed by task_run().

Parameters:
name String describing task
entry Entry function of the task
priority Priority of the task
stack_size Size of the stack (number of bytes)
arg Sent as argument to task
Returns:
Task handle

Note that name must be a pointer to a static memory area. In order to save memory, rt-kernel does not make a local copy of the name.

The priority of the task is used when more than one task is ready to execute. The task with the highest priority will always be scheduled for execution first. The priority is a number between 0 and 31; higher numbers indicate higher priorities. In other words, 0 is the lowest priority and 31 is the highest. Note that priority level 0 is reserved for the idle task. Priority level 31 is reserved for time-triggered tasks and should not be used if such tasks exist in the system.

The stack_size parameter indicates the number of bytes available for the task stack. All variables and data with local scope are stored on the stack. Making the stack too small is a common source of hard to find bugs in real-time systems. rt-kernel is able to detect some stack overflows; if the stack has overflown when the task calls a kernel service that causes it to be swapped out then a system error function is called. Likewise, the kernel will call the system error function if the task is swapped out because another higher priority task becomes ready. rt-kernel does not detect temporary overflow of the stack in between such events. See Error Detection.

The arg parameter is sent as argument to the task entry function. It can be used to identify different instances of tasks sharing the same code. The argument should be cast as a void pointer, but can be any parameter. If more than one parameter is needed a struct can be used:

 struct myParams {
   int a;
   char * b;
 }

 void myTaskEntry (void * arg) {
   struct myParams * param = (struct myParams *)arg;

   for (;;)
   {
      // task main loop
   }
 }

 void foo() {
   static struct myParams1 = { 1, "1" };
   static struct myParams2 = { 2, "2" };
   task_t * myFirstTask;
   task_t * mySecondTask;

   myFirstTask = task_spawn ("myFirstTask", myTaskEntry, 10, 1024,
                             (void *)&myParams1);
   mySecondTask = task_spawn ("mySecondTask", myTaskEntry, 10, 1024,
                              (void *)&myParams2);
 }
void task_start ( task_t *  task  ) 

Puts another task in the READY state. Together with task_stop(), this function can be used to synchronise a task in response to external events. The effect is similar to using a semaphore but these functions do not require memory for keeping track of the synchronisation object (e.g. a semaphore handle).

Note that the task is not made READY if the number of calls to task_start() is not equal to the number of calls to task_stop().

A potential usage of task_start() is to signal a task from an ISR:

 void myISR()
 {
    // Clear interrupt source
    ....

    // Notify task that interrupt occurred
    task_start (theTask);
 }
Parameters:
task Handle of the task to be made READY.
void task_stop ( void   ) 

Puts the calling task in the WAITING state. Together with task_start(), this function can be used to synchronise a task in response to external events. The effect is similar to using a semaphore but these functions do not require memory for keeping track of the synchronisation object (e.g. a semaphore handle).

Note that the task is not made WAITING if task_start() has been called more times than task_stop().

A potential usage of task_start() is to synchronise with an ISR:

 void myTask (void * arg)
 {
    for (;;)
    {
       // Wait for interrupt
       task_stop();

       // Handle interrupt at task level
       ...
    }
 }
void task_suspend ( task_t *  task  ) 

Suspend a task. The task will not execute until task_resume() is called.

A suspended task that is delayed or waiting for a resource will leave the WAITING state when the delay expires or the resource becomes available, and will become READY once task_resume() is called.

This is a potentially unsafe operation. The task to be suspended may own resources that other tasks in the system depend upon. Suspension is primarily intended for debugging.

It is not possible to suspend the idle task or any time-triggered task.

Parameters:
task Handle of the task to suspend.

rt-kernel