Semaphores in GeMRTOS #
The
semaphore
is a resource for preventing concurrent execution of code sections. GeMRTOS is capable of using either
binary
or
counting
semaphores. While counting semaphores set the starting count to the number of enabled concurrent executions, binary semaphores set the initial count to 1. If a task requests a semaphore, it will only be allowed if the current count is more than or equal to 1, and if it is granted, it will decrease the current count. When a task that is granting the semaphore releases it, the current count is increased. As a result, the initial count of the semaphore will be equal to the maximum number of concurrent executions of a code section that is excluded by the semaphore.
The semaphore request function may be configured as blocking or non-blocking. It can be specified a timeout for the blocking alternative.
Semaphore related functions #
Creating and initializing a Semaphore #
The first step is to create a semaphore resource using:
G_RCB *gu_sem_create(int initial_count);
The gu_sem_create function creates a new semaphore resource. The semaphore is built using the G_RCB structure with some fields from the T_SEMAPHORE_RESOURCE structure appended. A waiting and a granted event list will be included in the newly constructed semaphore resource. Tasks requesting the semaphore link a waiting event in the waiting list if sempahore is already granted and the requests is a blocking one. The gu_sem_create can be called from either the main code or a task code. However, when it is executed within a task code, it must come before the execution of a request for or a release of function, or an error will be produced.
gu_sem_create
The semaphore is created and initilized with the following paramenters:
Name Description initial_count Initial count of the semaphore to allow simultaneous granted tasks. A value equal to 1 determines a binary semaphore.
Requesting on a Semaphore #
An existing semaphore is requested with the following function:
G_INT32 gu_sem_wait(G_RCB *presource, int blocking);
The gu_sem_wait function requests a semaphore resource. If the current count is greater than 1, then the semaphore is granted to the task executing the gu_sem_wait function, and the semaphore count is decreased. If the current semaphore count is equal to 0, then either (1) the task is suspended when the blocking parameter is equal to G_TRUE, or (2) the function returns G_FALSE without suspending the task. When the blocking parameter is equal to G_TRUE, the waiting priority is defined by the ready priority of the task.
The semaphore is requested with the following parameters:
Name Description presource It is the pointer to the semaphore resource returned by the gu_sem_create function when it was created. blocking If the blocking parameter is set to G_TRUE, then the function blocks the task waiting for the semaphore when it is not available. When the blocking parameter is set to G_FALSE, the function returns G_FALSE without blocking execution if the semaphore is not available.
Releasing a Semaphore #
A granted semaphore is released with the following function:
G_INT32 gu_sem_post(G_RCB *presource);
The gu_sem_post function releases the granted semaphore from the task executing the function (when semaphore was granted to the task). If a task is waiting for the semaphore on the waiting list, then the highest waiting priority task will be granted to the semaphore. If no task is waiting for the semaphore, the current count of the semaphore resource is increased.
gu_sem_post
The semaphore is released with the following parameters:
Name Description presource It is the pointer to the semaphore resource returned by the gu_sem_create function when it was created.
Semaphore resource related structure #
T_SEMAPHORE_RESOURCE #
The T_SEMAPHORE_RESOURCE is defined as the field "semaphore" in a G_RCB resource. So, the fields of the T_SEMAPHORE_RESOURCE structure should be addressed as: (G_RCB *)->semaphore.<field>
Structure fields #
Type | Field | Description |
---|---|---|
G_INT32 | SEM_Current_Count | It is the current count of the semaphore. If it is equal to 0, no more grants are allowed. It is initialized with the SEM_Maximum_Count when the semaphore is created with the gu_SemaphoreCreate function. |
G_INT32 | SEM_Maximum_Count | It is the initial value of the SEM_Current_Count field. It is defined for debugging purposes only, and it could be removed. |