This is an old revision of the document!
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 } }
#pragma funcall main SimpleTask
Each task can be in one of five states:
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.
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 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();
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).
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).
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); . . .
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.
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) . . . }
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 | |
OS_Task_Replace | (priority, TaskName) | Stop and delete current task and create new task | |
OS_Task_Delete | (tp) | Delete task | |
Menagement | |||
OST_TASK_POINTER OS_Task_GetCur | | Get pointer to currect task's descriptor | |
OST_TASK_POINTER OS_Task_GetCreated | | Get pointer to just created task's descriptor | |
OS_Task_Pause | (tp) | Pause task | |
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 |