====== OSA : System services ======
===== Common services =====
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Init|OS_Init]]()## |Initialize system variables| {{osa:ref:attr_call_not_int.png}} |
Clears all task descriptors, all binary semaphores and static timers. This service must be called before ##[[en:osa:ref:allservices:OS_Run|OS_Run]]##().
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]()## |Work with all timers | {{osa:ref:attr_call_to.png}} |
This service must be used if:
* any task uses ##[[en:osa:ref:allservices:OS_Delay|OS_Delay]]##();
* any task waits for events with timeout;
* static or dynamic timers are used in the program.
This service should be called from e.g. the TMR0 interrupt routine.
In this documentation we use the term __**system tick**__ to mean the period between calls to ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]##. All delay and timeout parameters in services are given in **system ticks**.
At every execution of ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]##() all active timers are increased by 1 (except 24-bit old style static timers which are increased by 1 per 256 ticks).
Example of usage:
void interrupt isr()
{
if (T0IE && T0IF) {
TMR0 -= 250;
T0IF = 0;
OS_Timer();
}
}
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Yield|OS_Yield]] ()## |Switch context| {{osa:ref:attr_call_task.png}}{{osa:ref:attr_call_ct_sw.png}} |
This service unconditionally switches context (returns to the scheduler) to allow other tasks to be executed.
~~UP~~
===== Wait services =====
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Delay|OS_Delay]] (##//delaytime//##)## |Delay current task by //delaytime// system ticks| {{osa:ref:attr_call_task.png}}{{osa:ref:attr_call_ct_sw.png}}{{osa:ref:attr_call_to.png}} |
Puts task in waiting state for the time given in parameter //delaytime//.
For example, a task indicates temperature to the LCD once per second. Let ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]## period = 10 ms. Task will look like:
void Task_Indicate (void)
{
for (;;) {
OS_Delay(100); // Delay = 100 * 10 ms = 1 sec
IndicateTemperature(); // Output data to LCD
}
}
Using this service you must remember that ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]## is discrete. So the resolution of all delays is **one system tick**. If the ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]## calling interval is 10 ms, then ##[[en:osa:ref:allservices:OS_Delay|OS_Delay]]##(1) may wait 10 ms, or may wait 0 ms (depending on what time within the ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]## period ##[[en:osa:ref:allservices:OS_Delay|OS_Delay]]## was called).
Therefore you should either be sure that the length of delay is not important or decrease the size of a system tick and increase the delay value. For example, you could reduce the size of a system tick to 1 ms and call ##[[en:osa:ref:allservices:OS_Delay|OS_Delay]]##(10). Here we can be sure that delay will last for 9-10 ms.
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Wait|OS_Wait]] (##//condition//##)## |Wait for condition to become true| {{osa:ref:attr_call_task.png}}{{osa:ref:attr_call_ct_sw.png}} |
Puts task in waiting state while condition is false. The condition is any expression of boolean type. When the condition becomes true, the task becomes ready to execute.
...
OS_Wait(m_nInPulseCounter >= 10 || m_bButtonPressed);
...
In this example //m_nInPulseCounter// and //m_bButtonPressed// are external variables that can be set anywhere in the program. The task will be in waiting state while m_nInPulseCounter is less than 10 and the button is not pressed.
\\
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_Wait_TO|OS_Wait_TO]] (##//condition, timeout//##)## |Same as ##[[en:osa:ref:allservices:OS_Wait|OS_Wait]]##() with exit if timeout expired | {{osa:ref:attr_call_task.png}}{{osa:ref:attr_call_ct_sw.png}}{{osa:ref:attr_call_to.png}} |
Puts task in wait state while condition is false and timeout has not expired. Timeout value is given in system ticks.
...
OS_Wait_TO(m_bButtonPressed, 100);
if (OS_IsTimeout()) ...;
...
Here we wait for a button event within 100 system ticks. After exiting the wait, we check if there was a timeout or not by using the service ##[[en:osa:ref:allservices:OS_IsTimeout|OS_IsTimeout]]##.
~~UP~~
===== System state =====
All services that check system state return 0 or 1 depending on system state flags.
^ Service ^ Description ^ Properties ^
|##//bool// [[en:osa:ref:allservices:OS_IsTimeout|OS_IsTimeout]] ()## |Check if exit from wait was due to timeout| {{osa:ref:attr_call_task.png}}{{osa:ref:attr_call_to.png}} |
This service can be used after waiting for some event with timeout, to check why the exit occurred. If it returns 1 then the timeout expired and event did not occur. If it returns 0 then the event occurred and there was no timeout.
^ Service ^ Description ^ Properties ^
|##//bool// [[en:osa:ref:allservices:OS_IsError|OS_IsError]] ()## |Check if system error| |
System errors are:
* Task creation error (there is no free descriptor)
^ Service ^ Description ^ Properties ^
|##//bool// [[en:osa:ref:allservices:OS_IsEventError|OS_IsEventError]] ()## |Check if event error | |
Event errors are:
* Increasing counting semaphore when it already has maximum value
* Sending message when it already exists
* Sending message via queue that is already full
^ Service ^ Description ^ Properties ^
|##//bool// [[en:osa:ref:allservices:OS_IsInCriticalSection|OS_IsInCriticalSection]] ()## |Returns 1 if any task is in critical section| |
~~UP~~
===== Interrupt control services =====
^ Service ^ Description ^ Properties ^
|##[[en:osa:ref:allservices:OS_EnterInt|OS_EnterInt]] ()## | For **PICC16** and **PICC18**: should be called at the beginning of interrupt routine (saves FSR value)| {{osa:ref:attr_call_int.png}} |
|##[[en:osa:ref:allservices:OS_LeaveInt|OS_LeaveInt]] ()## | For **PICC16** and **PICC18**: should be called at the end of interrupt routine (restores FSR value)| {{osa:ref:attr_call_int.png}} |
A call to ##[[en:osa:ref:allservices:OS_EnterInt|OS_EnterInt]]## should be inserted at the start of an interrupt routine, just after definition of local variables. A call to ##[[en:osa:ref:allservices:OS_LeaveInt|OS_LeaveInt]]##() should be inserted at the end of an interrupt routine, just before the closing '}'.
void interrupt int_routine (void)
{
char var1, var2;
int var3;
OS_EnterInt();
... //
... //
OS_LeaveInt();
}
^ Service ^ Description ^ Properties ^
|##//char// [[en:osa:ref:allservices:OS_DI|OS_DI]] ()## |Disable interrupts. Returns current GIEx value| {{osa:ref:attr_call_not_int.png}} |
|##[[en:osa:ref:allservices:OS_EI|OS_EI]] ()## |Enable all interrupts| {{osa:ref:attr_call_not_int.png}} |
|##[[en:osa:ref:allservices:OS_RI|OS_RI]] (##//char//##)## |Restore GIEx value saved by ##[[en:osa:ref:allservices:OS_DI|OS_DI]]##()| {{osa:ref:attr_call_not_int.png}} |
Service ##[[en:osa:ref:allservices:OS_RI|OS_RI]]## restores only "1" bits, not "0" bits. If before ##[[en:osa:ref:allservices:OS_DI|OS_DI]]##() flag GIE == 0, and after ##[[en:osa:ref:allservices:OS_DI|OS_DI]]##() GIE was set by ##[[en:osa:ref:allservices:OS_EI|OS_EI]]##(), then ##[[en:osa:ref:allservices:OS_RI|OS_RI]]##() will not restore zero value of GIE.
Here is an example of using these services to generate a pulse of 5 cycles:
{
char gie_temp;
...
gie_temp = OS_DI();
RB0 = 1;
NOP();
NOP();
NOP();
NOP();
RB0 = 0;
OS_RI(gie_temp);
...
}
~~UP~~
===== All system services =====
^ Service ^ Arguments ^ Description ^ Properties ^
| **System** ||||
| ##[[en:osa:ref:allservices:OS_Sched|OS_Sched]]## | '''' | Scan all tasks, select ready task with the highest priority and run it | |
| ##[[en:osa:ref:allservices:OS_Run|OS_Run]]## | '''' | Run operating system's kernel. Calls ##[[en:osa:ref:allservices:OS_Sched|OS_Sched]]##() in infinite loop | |
| ##[[en:osa:ref:allservices:OS_Init|OS_Init]]## | '''' | Initialize system variables | {{osa:ref:attr_call_not_int.png|Not allowed in interrupt}} |
| ##[[en:osa:ref:allservices:OS_Timer|OS_Timer]]## | '''' | Increase all active timers | |
| **Waiting** ||||
| ##[[en:osa:ref:allservices:OS_Yield|OS_Yield]]## | '''' | Return to the scheduler | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}} |
| ##[[en:osa:ref:allservices:OS_Delay|OS_Delay]]## | ''(delaytime)'' | Delay current task for //delaytime// system ticks | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}}{{osa:ref:attr_call_to.png|Service uses system timer}} |
| ##[[en:osa:ref:allservices:OS_Wait|OS_Wait]]## | ''(condition)'' | Wait for condition to become true | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}} |
| ##[[en:osa:ref:allservices:OS_Wait_TO|OS_Wait_TO]]## | ''(condition, timeout)'' | Wait for condition to become true. Exit if timeout expired | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}}{{osa:ref:attr_call_to.png|Service uses system timer}} |
| **Checking** ||||
| ''bool ''\\ ##[[en:osa:ref:allservices:OS_IsTimeout|OS_IsTimeout]]## | '''' | Return true if timeout occurred in previous wait service | {{osa:ref:attr_call_to.png|Service uses system timer}} |
| ''bool ''\\ ##[[en:osa:ref:allservices:OS_IsError|OS_IsError]]## | '''' | Check if error after task creation | |
| ''bool ''\\ ##[[en:osa:ref:allservices:OS_IsEventError|OS_IsEventError]]## | '''' | Check if error after using events | |
| ''bool ''\\ ##[[en:osa:ref:allservices:OS_IsInCriticalSection|OS_IsInCriticalSection]]## | '''' | Return true if any task is in critical section | |
| **Interrupts** ||||
| ##[[en:osa:ref:allservices:OS_EnterInt|OS_EnterInt]]## | '''' | For **PICC16** and **PICC18**: save FSR at the beginning of an ISR function | {{osa:ref:attr_call_int.png|Only inside interrupt}} |
| ##[[en:osa:ref:allservices:OS_LeaveInt|OS_LeaveInt]]## | '''' | For **PICC16** and **PICC18**: restore saved FSR at the end of an ISR function | {{osa:ref:attr_call_int.png|Only inside interrupt}} |
| ''char ''\\ ##[[en:osa:ref:allservices:OS_DI|OS_DI]]## | '''' | Disable all interrupts and save previous state of GIEx flags | {{osa:ref:attr_call_not_int.png|Not allowed in interrupt}} |
| ##[[en:osa:ref:allservices:OS_EI|OS_EI]]## | '''' | Enable all interrupts | {{osa:ref:attr_call_not_int.png|Not allowed in interrupt}} |
| ##[[en:osa:ref:allservices:OS_RI|OS_RI]]## | ''(char)'' | Restore GIEx flags previously saved by ##[[en:osa:ref:allservices:OS_DI|OS_DI]]## service | {{osa:ref:attr_call_not_int.png|Not allowed in interrupt}} |
| ##[[en:osa:ref:allservices:OS_EnterCriticalSection|OS_EnterCriticalSection]]## | '''' | Enter critical section | {{osa:ref:attr_call_task.png|Allowed only in task}} |
| ##[[en:osa:ref:allservices:OS_LeaveCriticalSection|OS_LeaveCriticalSection]]## | '''' | Leave critical section | {{osa:ref:attr_call_task.png|Allowed only in task}} |
~~UP~~