FreeRTOS - Task Notifications
FreeRTOS - Task Notifications
Applications that use FreeRTOS are structured as a set of independent tasks, and that it is likely that these autonomous tasks will have to communicate with each other so that, collectively, they can provide useful system functionality. Tasks can communicate using communications objects like queues, event groups, and various different types of semaphore.
When a communication object is used, events and data are not sent directly to a receiving task, or a receiving ISR, but are instead sent to the communication object. Likewise, tasks and ISRs receive events and data from the communication object, rather than directly from the task or ISR that sent the event or data.
Task Notifications — Direct to Task Communication
‘Task Notifications’ allow tasks to interact with other tasks, and to synchronize with ISRs, without the need for a separate communication object. By using a task notification, a task or ISR can send an event directly to the receiving task.
- To include task notification functionality set configUSE_TASK_NOTIFICATIONS to 1 in FreeRTOSConfig.h.
- When configUSE_TASK_NOTIFICATIONS is set to 1, each task has a ‘Notification State’, which can be either ‘Pending’ or ‘Not-Pending’, and a ‘Notification Value’, which is a 32-bit unsigned integer.
Task Notification API Functions
Task notifications are a very powerful feature that can often be used in place of a binary semaphore, a counting semaphore, an event group, and sometimes even a queue.
The xTaskNotifyGive() API Function
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
xTaskNotifyGive() sends a notification directly to a task, and increments (adds one to) the receiving task’s notification value. Calling xTaskNotifyGive() will set the receiving task’s notification state to pending, if it was not already pending.
The vTaskNotifyGiveFromISR() API Function
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken );
vTaskNotifyGiveFromISR() is a version of xTaskNotifyGive() that can be used in an interrupt service routine.
The ulTaskNotifyTake() API Function
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
ulTaskNotifyTake() allows a task to wait in the Blocked state for its notification value to be greater than zero, and either decrements (subtracts one from) or clears the task’s notification value before it returns.
The xTaskNotify() and xTaskNotifyFromISR() API Functions
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
xTaskNotify() is a more capable version of xTaskNotifyGive() that can be used to update the receiving task’s notification value in any of the following ways:
- Increment (add one to) the receiving task’s notification value, in which case xTaskNotify() is equivalent to xTaskNotifyGive().
- Set one or more bits in the receiving task’s notification value. This allows a task’s notification value to be used as a lighter weight and faster alternative to an event group.
- Write a completely new number into the receiving task’s notification value, but only if the receiving task has read its notification value since it was last updated. This allows a task’s notification value to provide similar functionality to that provided by a queue that has a length of one.
- Write a completely new number into the receiving task’s notification value, even if the receiving task has not read its notification value since it was last updated. This allows a task’s notification value to provide similar functionality to that provided by the xQueueOverwrite() API function. The resultant behavior is sometimes referred to as a ‘mailbox’.
xTaskNotifyFromISR() is a version of xTaskNotify() that can be used in an interrupt service routine, and therefore has an additional pxHigherPriorityTaskWoken parameter.
The xTaskNotifyWait() API Function
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait);
xTaskNotifyWait() is a more capable version of ulTaskNotifyTake(). It allows a task to wait, with an optional timeout, for the calling task’s notification state to become pending, should it not already be pending.