Available Languages?:

This is an old revision of the document!


OSA : Tasks

Intro

Task in OSA is C-function. This function must contain infinite loop wich has inside at least one service that switchs task context. Simple task can looks like:

void SimpleTask (void)
{
    for (;;) {      // Inifinite loop
        OS_Yield(); // Unconditional context switching
    }
}

When using mikroC PRO you must tell to linker that function will be called indirrectly by adding #paragma directive, e.g.:

#pragma funcall main SimpleTask

Each task can be in one of five states:

  • not created
  • waiting
  • ready
  • running
  • paused

Every task has priority. There are eight priority levels from 0 (highest) to 7 (lowest). Priority can be changed in runtime.(More about priorities and states).

To work with tasks OSA reserves RAM for task descriptors. Number of tasks wich can be active at one time is set by constant OS_TASKS in OSAcfg.h.

Pointer to TCB

Most operations on the task are making through pointer to it's descriptor called tcb (Task Control Block). Task descriptors can not be accessed directly. Bu you can to define a global variable of type OST_TASK_POINTER, wich will point to the descriptor of task.

OST_TASK_POINTER tp_MyTask;

To control task through this variable we must to initialize it by service OS_GetCurTask. Inside task this service returns pointer to current task's descriptor. It is recommended to call this service in the begin of task-function.

void MyTask (void)
{
    tp_MyTask = OS_GetCurTask();
    for (;;) {
        /*...*/
    }
}

Also it is possible to control task by itself. In this case you can use system macro this_task (or service OS_GetCurTask) as the parameter.

void MyTask (void)
{
    for (;;) {
        /*...*/
        OS_Task_SetPriority(this_task, 0);     // set highest priority for current task
        /*...*/
    }
}

Task creation

Task is created by service OS_Task_Create. For example:

#include <osa.h>
 
void Task1 (void)
{
    for (;;)
    {
        OS_Yield()
    }
}
 
...
 
void main (void)
{
    OS_Init();
    OS_Task_Create(7, Task1);
    ...
    for (;;) OS_Sched();
}

In this example we created task from C-function Task1() with lowest priority. After this service worked, operating system will know that function Task1() is a task and will give control to it when it will be ready.

We must to provide service OS_Task_Create with priority even if priority mode disabled (constant OS_DESABLE_PRIORITY is defined in OSAcfg.h).

After OS_Task_Create() executed you can get a pointer to descriptor of created task with service OS_Task_GetCreated (it is usefull when one task will control other task):

    OST_TASK_POINTER  tp;
 
    OS_Task_Create(0, MyTask);
    if (!OS_IsError) tp = OS_Task_GetCreated();

When using CCS all function-tasks should be defined in main() by service OS_Task_Define

Task creation error

If before calling service OS_Task_Create there is no free task descriptor, then task will not be created and system flag OS_IsError will be set.

    OS_Task_Create(7, Task1);
    if (OS_IsError()) ...	;	//

If OS_Task_Create() exits with error then you need to increase constant OS_TASKS in OSAcfg.h and then re-build project. If it is supposed that there must be free decriptor, then you need to serach error in program (e.g. some task had to be stopped but still running).

Task deleting

To delete task (to delete it from list of active task and to free descriptor) you can use service OS_Task_Delete. Before deleting task you should be sure that task free all resources. It is recommended to deleting task by itself only (but OSA services aloows to delete task from any place in program).

Be sure that deleting task free all resources.

After calling OS_Task_Delete task descriptor will be free. If this service called to delete current task (with this_task perameter) then system automatically switchs context. After OS_Task_Delete(this_task) no operators will be executed.

    ...
    OS_Task_Delete(this_task);
    Counter ++;
    ...

In this example variable counter will not be increased.

To stop current task and to run another, first we must to create a new task and after that we can delete current. Elsewere new task will not be created.

    . . .
    OS_Task_Create(1, Task_NewTask);
    OS_Task_Delete(this_task);
    . . .

But this method has a lack: we must have at least one free task descriptor at all times. For example, program of dictaphone consist of several tasks: buttons, indication, recording, playing, battary checking. Here we have 2 tasks that can not be active at one time: recording and playing. Thus at one time only 4 tasks can be active. When we switching from recording task to playing task, first we must to create playing task and than to stop recording. Thus we must have 5 task descriptors for 4 active tasks.

void Task_Play (void)
{
    . . .
    OS_Task_Create(1, Task_Record);
    OS_Task_Delete(this_task);
    . . .
}

In this case several bytes of RAM (used by fifth task descriptor) are not used most of the time. To avoid this problem we can use service OS_Task_Replace:

This service will stop current task and create new in just released descriptor.

    . . .
    OS_Task_Replace(1, Task_Record);
    . . .

Task priority change

We can change priority of tasks in real-time. There are two services to work with task priority: OS_Task_GetPriority and OS_Task_SetPriority.

Task local variables

All active (created) tasks are parallel processes, and you should remember that their local variables may intersect. Thus local variable's value may be lost (rewritten by parallel task) after context switching. To avoid loss of variable's value, it must be declared as static. I.e.:

void Task1 (void)
{
  static char s_cCounter;  // This variable will remain unchanged after context switching
  char i, j;               // Theese variables are temporary. They can be used only within one task
                           // session (from getting control to context switching)
  . . .
}

Services

Service Arguments Description Properties
Creating/Deleting
OS_Task_Define (TaskName) For CCS: Tell to compiler that function Taskname is a task and it will be called indirrectly. This service called from main() only main
OS_Task_Create (priority, TaskName) Create task and add it to list of active tasks Not allowed in interrupt
OS_Task_Replace (priority, TaskName) Stop and delete current task and create new task Allowed only in task
OS_Task_Delete (tp) Delete task Switches contexts
Menagement
OST_TASK_POINTER
OS_Task_GetCur
Get pointer to currect task's descriptor Allowed only in task
OST_TASK_POINTER
OS_Task_GetCreated
Get pointer to just created task's descriptor
OS_Task_Pause (tp) Pause task Switches contexts
OS_Task_Continue (tp) Continue paused task
char
OS_Task_GetPriority
(tp) Get priority of task
OS_Task_SetPriority (tp, priority) Change task's priority
Checking
OS_Task_IsPaused (tp) Check for task s paused
 
en/osa/ref/services/tasks.1268225820.txt.gz · Last modified: 10.03.2010 15:57 by osa_chief
 
Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki