CMSIS-RTOS
Version 1.03
Real-Time Operating System: API and RTX Reference Implementation.
|
Access shared resources simultaneously from different threads. More...
Macros | |
#define | osFeature_Semaphore 30 |
maximum count for osSemaphoreCreate function More... | |
#define | osSemaphoreDef(name) const osSemaphoreDef_t os_semaphore_def_##name = { 0 } |
Define a Semaphore object. More... | |
#define | osSemaphore(name) &os_semaphore_def_##name |
Access a Semaphore definition. More... | |
Functions | |
osSemaphoreId | osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) |
Create and Initialize a Semaphore object used for managing resources. More... | |
int32_t | osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) |
Wait until a Semaphore token becomes available. More... | |
osStatus | osSemaphoreRelease (osSemaphoreId semaphore_id) |
Release a Semaphore token. More... | |
osStatus | osSemaphoreDelete (osSemaphoreId semaphore_id) |
Delete a Semaphore that was created by osSemaphoreCreate. More... | |
Semaphores are used to manage and protect access to shared resources. Semaphores are very similar to Mutexes. Whereas a Mutex permits just one thread to access a shared resource at a time, a semaphore can be used to permit a fixed number of threads to access a pool of shared resources. Using semaphores, access to a group of identical peripherals can be managed (for example multiple DMA channels).
A semaphore object should be initialized to the maximum number of available tokens. This number of available resources is specified as parameter of the osSemaphoreCreate function. Each time a semaphore token is obtained with osSemaphoreWait, the semaphore count is decremented. When the semaphore count is 0, no semaphore token can be obtained. The thread that tries to obtain the semaphore token needs to wait until the next token is free. Semaphores are released with osSemaphoreRelease incrementing the semaphore count.
Follow these steps to create and use a semaphore:
Due to their flexibility, semaphores cover a wide range of synchronizing applications. At the same time, they are perhaps the most challenging RTOS object to understand. The following explains a use case for semaphores, taken from the book The Little Book Of Semaphores by Allen B. Downey which is available for free download.
Non-binary Semaphore (Multiplex)
A multiplex limits the number of threads that can access a critical section of code. For example, this could be a function accessing DMA resources which can only support a limited number of calls.
To allow multiple threads to run the function, initialize a semaphore to the maximum number of threads that can be allowed. The number of tokens in the semaphore represents the number of additional threads that may enter. If this number is zero, then the next thread trying to access the function will have to wait until one of the other threads exits and releases its token. When all threads have exited the token number is back to n. Ths following example shows the code for one of the threads that might access the resource:
#define osFeature_Semaphore 30 |
A CMSIS-RTOS implementation may support semaphores. The value osFeature_Semaphore indicates the maximum index count for a semaphore.
CMSIS-RTOS RTX Setting: osFeature_Semaphore is 65535
#define osSemaphore | ( | name | ) | &os_semaphore_def_##name |
Access to semaphore object for the functions osSemaphoreCreate.
name | name of the semaphore object. |
#define osSemaphoreDef | ( | name | ) | const osSemaphoreDef_t os_semaphore_def_##name = { 0 } |
Define a semaphore object that is referenced by osSemaphore.
name | name of the semaphore object. |
osSemaphoreId osSemaphoreCreate | ( | const osSemaphoreDef_t * | semaphore_def, |
int32_t | count | ||
) |
[in] | semaphore_def | semaphore definition referenced with osSemaphore. |
[in] | count | number of available resources. |
Create and initialize a Semaphore object that is used to manage access to shared resources. The parameter count specifies the number of available resources. The count value 1 creates a binary semaphore.
Code Example
osStatus osSemaphoreDelete | ( | osSemaphoreId | semaphore_id | ) |
[in] | semaphore_id | semaphore object referenced with osSemaphoreCreate. |
Delete a Semaphore object. The function releases internal memory obtained for Semaphore handling. After this call the semaphore_id is no longer valid and cannot be used. The Semaphore may be created again using the function osSemaphoreCreate.
osStatus osSemaphoreRelease | ( | osSemaphoreId | semaphore_id | ) |
[in] | semaphore_id | semaphore object referenced with osSemaphoreCreate. |
Release a Semaphore token. This increments the count of available semaphore tokens.
int32_t osSemaphoreWait | ( | osSemaphoreId | semaphore_id, |
uint32_t | millisec | ||
) |
[in] | semaphore_id | semaphore object referenced with osSemaphoreCreate. |
[in] | millisec | Timout Value or 0 in case of no time-out. |
Wait until a Semaphore token becomes available. When no Semaphore token is available, the function waits for the time specified with the parameter millisec.
The argument millisec specifies how long the system waits for a Semaphore token to become available. While the system waits the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:
The return value indicates the number of available tokens (the semaphore count value). If 0 is returned, then no semaphore was available.