====== 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~~