Semaphores in Nucleus RTOS: Utility Services & Data Structures
View the RTOS Revealed series
This article continues the look at semaphores.
Semaphore Utility Services
Nucleus RTOS offers four API calls that provide essential utilities for semaphore management: reset a semaphore, retrieve detailed semaphore information, count the total number of semaphores in an application, and obtain pointers to all semaphore objects. The first three functions are fully implemented in Nucleus SE.
Resetting a Semaphore
Unlike most kernel objects, resetting a semaphore restores it to a specified initial count rather than simply reinitializing it to its compile‑time value. Any tasks blocked on the semaphore are immediately awakened and receive the return code NUSE_SEMAPHORE_WAS_RESET (or NU_SEMAPHORE_RESET in Nucleus RTOS).
Nucleus RTOS API Call for Resetting a Semaphore
Service call prototype:
STATUS NU_Reset_Semaphore(NU_SEMAPHORE *semaphore,
UNSIGNED initial_count);
Parameters:
semaphore – pointer to the semaphore control block supplied by the user.
initial_count – the value to which the semaphore’s counter should be set.
Returns:
NU_SUCCESS – the operation completed successfully.
NU_INVALID_SEMAPHORE – the semaphore pointer is not valid.
Nucleus SE API Call for Resetting a Semaphore
Service call prototype:
STATUS NUSE_Semaphore_Reset(NUSE_SEMAPHORE semaphore,
U8 initial_count);
Parameters:
semaphore – the index (ID) of the semaphore to reset.
initial_count – the value to which the semaphore’s counter should be set.
Returns:
NUSE_SUCCESS – the operation completed successfully.
NUSE_INVALID_SEMAPHORE – the semaphore index is not valid.
Nucleus SE Implementation of Semaphore Reset
The NUSE_Semaphore_Reset() routine validates its arguments and then writes the new count into the NUSE_Semaphore_Counter[] array. When blocking is enabled, it loops through the task table to locate any tasks suspended on the semaphore, marks them as ready, assigns the NUSE_SEMAPHORE_WAS_RESET return code, and finally triggers a reschedule if a priority scheduler is active.
while (NUSE_Semaphore_Blocking_Count[semaphore] != 0) {
U8 index;
for (index = 0; index < NUSE_TASK_NUMBER; index++) {
if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) &&
(HINIB(NUSE_Task_Status[index]) == semaphore)) {
NUSE_Task_Blocking_Return[index] = NUSE_SEMAPHORE_WAS_RESET;
NUSE_Task_Status[index] = NUSE_READY;
break;
}
}
NUSE_Semaphore_Blocking_Count[semaphore]--;
}
#if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER
NUSE_Reschedule(NUSE_NO_TASK);
#endif
All suspended tasks are therefore transitioned to the ready state with the appropriate return code. If the priority scheduler is active, NUSE_Reschedule() ensures that higher‑priority tasks can preempt lower‑priority ones.
Semaphore Information
This service call retrieves key details about a semaphore. In Nucleus SE, fewer fields are returned because object naming, suspend ordering, and task suspend may not be supported.
Nucleus RTOS API Call for Semaphore Information
Service call prototype:
STATUS NU_Semaphore_Information(NU_SEMAPHORE *semaphore,
CHAR *name, UNSIGNED *current_count, OPTION *suspend_type,
UNSIGNED *tasks_waiting, NU_TASK **first_task);
Parameters:
semaphore – pointer to the semaphore control block requested.
name – destination buffer for the semaphore’s name (8 characters plus null terminator).
current_count – receives the current semaphore counter value.
suspend_type – receives the suspend policy (e.g., NU_FIFO or NU_PRIORITY).
tasks_waiting – receives the number of tasks suspended on the semaphore.
first_task – receives a pointer to the first suspended task’s control block.
Returns:
NU_SUCCESS – the call completed successfully.
NU_INVALID_SEMAPHORE – the semaphore pointer is invalid.
Nucleus SE API Call for Semaphore Information
Service call prototype:
STATUS NUSE_Semaphore_Information(NUSE_SEMAPHORE semaphore,
U8 *current_count, U8 *tasks_waiting, NUSE_TASK *first_task);
Parameters:
semaphore – the index of the semaphore.
current_count – receives the current counter value.
tasks_waiting – receives the number of suspended tasks (if task suspend is enabled).
first_task – receives the index of the first suspended task (if task suspend is enabled).
Returns:
NUSE_SUCCESS – the call completed successfully.
NUSE_INVALID_SEMAPHORE – the semaphore index is invalid.
NUSE_INVALID_POINTER – one or more pointer arguments are invalid.
Nucleus SE Implementation of Semaphore Information
The implementation is concise: it enters a critical section, copies the counter value, and, if blocking is enabled, enumerates the task table to count waiting tasks and identify the first suspended task. Otherwise, the waiting count and first task are set to zero.
NUSE_CS_Enter();
*current_count = NUSE_Semaphore_Counter[semaphore];
#if NUSE_BLOCKING_ENABLE
*tasks_waiting = NUSE_Semaphore_Blocking_Count[semaphore];
if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) {
U8 index;
for (index = 0; index < NUSE_TASK_NUMBER; index++) {
if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) &&
(HINIB(NUSE_Task_Status[index]) == semaphore)) {
*first_task = index;
break;
}
}
} else {
*first_task = 0;
}
#else
*tasks_waiting = 0;
*first_task = 0;
#endif
NUSE_CS_Exit();
return NUSE_SUCCESS;
Obtaining the Number of Semaphores
This service returns the total count of semaphores defined in the application. In Nucleus RTOS the value can change at runtime; in Nucleus SE it is fixed at build time.
Nucleus RTOS API Call for Semaphore Count
Service call prototype:
UNSIGNED NU_Established_Semaphores(VOID);
Returns:
The number of semaphores created in the application.
Nucleus SE API Call for Semaphore Count
Service call prototype:
U8 NUSE_Semaphore_Count(void);
Returns:
The number of semaphores configured in the application.
Nucleus SE Implementation of Semaphore Count
The routine simply returns the value of the compile‑time constant NUSE_SEMAPHORE_NUMBER.
Continue to page two: “Data Structures” >>
Embedded
- Cloud vs. In‑House Servers: Choosing the Right Hosting Solution
- Microsoft Azure Announces Blockchain Tokenization & Data Management Services
- C++ Structures vs Classes: A Practical Guide for Embedded Developers
- Mailboxes in Nucleus SE: A Practical Guide to Configuration and Usage
- Semaphores in Nucleus SE: Overview, Configuration, and API Essentials
- Mastering Event Flag Groups: Utility Services & Data Structures in Nucleus RTOS/SE
- Partition Memory in Nucleus RTOS/SE: Utility Services and Data Structures
- Queues in Nucleus SE: Introduction and Core Service Calls
- Embedded C Structures: A Practical Guide to Definition, Usage, and Memory Optimization
- Java Data Structures: Exploring Core Classes & Collections Framework