Semaphores: utility services and data structures
This article continues the look at semaphores.
Semaphore Utility Services
Nucleus RTOS has four API calls which provide utility functions associated with semaphores: reset semaphore, return information about a semaphore, return number of semaphores in the application and return pointers to all semaphores in the application. The first three of these are implemented in Nucleus SE.
Resetting a Semaphore
This API call restores the semaphore to its initial, unused state. This API function is unusual, compared with that available for other kernel objects, as, although it is a reset, it does not simply initialize its counter to the start-up value; a new initial count is provided in the call. Any tasks which were suspended on the semaphore are resumed and receive a return code of NUSE_SEMAPHORE_WAS_RESET (in Nucleus SE, or NU_SEMAPHORE_RESET with 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 user-supplied semaphore control block
initial_count – the value to which the semaphore’s counter is to be set
Returns:
NU_SUCCESS – the call was completed successfully
NU_INVALID_SEMAPHORE – the semaphore pointer is not valid
Nucleus SE API Call for Resetting a Semaphore
This API call supports the key functionality of the Nucleus RTOS API.
Service call prototype:
STATUS NUSE_Semaphore_Reset(NUSE_SEMAPHORE semaphore,
U8 initial_count);
Parameters:
semaphore – the index (ID) of the semaphore to be reset
initial_count – the value to which the semaphore’s counter is to be set
Returns:
NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_SEMAPHORE – the semaphore index is not valid
Nucleus SE Implementation of Semaphore Reset
The main job of the NUSE_Semaphore_Reset() API function – after parameter checking – is to simply set the appropriate entry in NUSE_Semaphore_Counter[] to the provided initial value.
When blocking is enabled, further code is required to unblock tasks:
while (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; /* check whether any tasks are blocked */ /* on this semaphore */ 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
Each task suspended on the semaphore is marked as “ready” with a suspend return code of NUSE_SEMAPHORE_WAS_RESET. After this process is complete, if the Priority scheduler is in use, a call is made to NUSE_Reschedule(), as one or more higher priority tasks may have been readied and needs to be allowed to run.
Semaphore Information
This service call obtains a selection of information about a semaphore. The Nucleus SE implementation differs from Nucleus RTOS in that it returns less information, as object naming and suspend ordering are not supported and task suspend may not be enabled.
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 top the control block of the semaphore about which information is being requested
name - pointer to an 8-character destination area for the semaphore’s name; this includes space for the null terminator
current_count – a pointer to a variable, which will receive the current value of the semaphore counter
suspend_type - pointer to a variable that holds the task’s suspend type; valid task suspend types are NU_FIFO and NU_PRIORITY
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this semaphore
first_task – a pointer to a variable of type NU_TASK which will receive a pointer to the control block of the first suspended task
Returns:
NU_SUCCESS – the call was completed successfully
NU_INVALID_SEMAPHORE – the semaphore pointer is not valid
Nucleus SE API Call for Semaphore Information
This API call supports the key functionality of the Nucleus RTOS API.
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 about which information is being requested
current_count – a pointer to a variable, which will receive the current value of the semaphore counter
tasks_waiting – a pointer to a variable which will receive the number of tasks suspended on this semaphore (nothing returned if task suspend is disabled)
first_task – a pointer to a variable of type NUSE_TASK which will receive the index of the first suspended task (nothing returned if task suspend is disabled)
Returns:
NUSE_SUCCESS – the call was completed successfully
NUSE_INVALID_SEMAPHORE – the semaphore index is not valid
NUSE_INVALID_POINTER – one or more of the pointer parameters is invalid
Nucleus SE Implementation of Semaphore Information
The implementation of this API call is quite straightforward:
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;
The function returns the semaphore status. Then, if blocking API calls is enabled, the number of waiting tasks and the index of the first one are returned (otherwise these two parameters are set to 0).
Obtaining the Number of Semaphores
This service call returns the number of semaphores configured in the application. Whilst in Nucleus RTOS this will vary over time and the returned value will represent the current number of semaphores, in Nucleus SE the value returned is set at build time and cannot change.
Nucleus RTOS API Call for Semaphore Count
Service call prototype:
UNSIGNED NU_Established_Semaphores(VOID);
Parameters:
None
Returns:
The number of created semaphores in the application
Nucleus SE API Call for Semaphore Count
This API call supports the key functionality of the Nucleus RTOS API.
Service call prototype:
U8 NUSE_Semaphore_Count(void);
Parameters:
None
Returns:
The number of configured semaphores in the application
Nucleus SE Implementation of Semaphore Count
The implementation of this API call is almost trivially simple: the value of the #define symbol NUSE_SEMAPHORE_NUMBER is returned.
Continue to page two: "Data Structures" >>
Please confirm the information below before signing in.
{* #socialRegistrationForm *} {* firstName *} {* lastName *} {* displayName *} {* emailAddress *} {* addressCountry *} {* companyName *} {* ednembJobfunction *} {* jobFunctionOther *} {* ednembIndustry *} {* industryOther *}