====== OSA : Counting semaphores ======
===== Intro =====
A counting semaphore is a system variable of type //unsigned char//, //unsigned int// or //unsigned long// (depending on the [[en:osa:ref:appendix:configuration|OS_CSEM_SIZE]] constant). To use counting semaphores in your program you must define [[en:osa:ref:appendix:configuration|OS_ENABLE_CSEM]] in ##[[en:osa:ref:appendix:configuration|OSAcfg.h]]##
The general difference between counting and [[en:osa:ref:services:binary_semaphores|binary]] semaphores is that counting semaphores can take any value in the range from 0 to the maximum value of the type (255, 65535,
4294967295).
===== Definition =====
Here is an example of defining a counting semaphore variable:
OST_CSEM mycsem;
For **HT-PICC16** counting semaphores may only be allocated in **bank0** and **bank1**.
===== Usage =====
To use a counting semaphore variable it must be created by the service ##[[en:osa:ref:allservices:OS_Csem_Create|OS_Csem_Create]]##. After creation, the semaphore is zeroed. The value of a counting semaphore can be changed with any service of the **management** group (see below). When a task is waiting for a counting semaphore, it will be put in wait mode while the semaphore is zero. Once its value becomes non-zero, the task will be switched to ready mode. After the task gets control, the semaphore's value will be decremented by 1.
Note that there are two groups of services to change a semaphore's value:
* within a task
* within an interrupt service routine (these services have the suffix **_I**)
In order to call the services from an interrupt, the constant [[en:osa:ref:appendix:configuration|OS_ENABLE_INT]] should be defined in ##[[en:osa:ref:appendix:configuration|OSAcfg.h.]]##
A few words about the service ##[[en:osa:ref:allservices:OS_Csem_Signal|OS_Csem_Signal]]##. This service increases a semaphore's value by 1. If the semaphore is already set at its maximum, then its value will **remain unchanged** and the **bEventError** flag will be set.
~~UP~~
===== Services =====
^ Service ^ Arguments ^ Description ^ Properties ^
| **Creating** ||||
| ##[[en:osa:ref:allservices:OS_Csem_Create|OS_Csem_Create]]## | ''(csem)'' | Create and zero counting semaphore | {{osa:ref:attr_call_not_int.png|Not allowed in interrupt}} |
| **Management** ||||
| ##[[en:osa:ref:allservices:OS_Csem_Signal|OS_Csem_Signal]]## | ''(csem)'' | Increase counting semaphore's value by 1 (wait if overflow) | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}} |
| ##[[en:osa:ref:allservices:OS_Csem_Signal_Now|OS_Csem_Signal_Now]]## | ''(csem)'' | Increase counting semaphore's value by 1 (don't wait if overflow) | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| ##[[en:osa:ref:allservices:OS_Csem_Set|OS_Csem_Set]]## | ''(csem)'' | Set counting semaphore's value to 1 | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| ##[[en:osa:ref:allservices:OS_Csem_SetValue|OS_Csem_SetValue]]## | ''(csem, value)'' | Set counting semaphore's value to a given //value// | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| ##[[en:osa:ref:allservices:OS_Csem_Reset|OS_Csem_Reset]]## | ''(csem)'' | Zero counting semaphore | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| **Checking** ||||
| ''bool ''\\ ##[[en:osa:ref:allservices:OS_Csem_Check|OS_Csem_Check]]## | ''(csem)'' | Check if counting semaphore is set (non-zero) | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| ##[[en:osa:ref:allservices:OS_Csem_Accept|OS_Csem_Accept]]## | ''(csem)'' | Accept counting semaphore. Decrease its value by 1 | {{osa:ref:attr_call_can_int.png|Has alternate service for use in ISR (suffix "_I")}} |
| **Waiting** ||||
| ##[[en:osa:ref:allservices:OS_Csem_Wait|OS_Csem_Wait]]## | ''(csem)'' | Wait for counting semaphore. Then decrease its value by 1 | {{osa:ref:attr_call_task.png|Allowed only in task}}{{osa:ref:attr_call_ct_sw.png|Switches context}} |
| ##[[en:osa:ref:allservices:OS_Csem_Wait_TO|OS_Csem_Wait_TO]]## | ''(csem, timeout)'' | Wait for counting semaphore. Then decrease its value by 1. 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}} |
~~UP~~