| Task Notification API Function | Description |
|---|---|
| xTaskNotify() | Sends a notification to a task and updates its notification value using the specified action |
| xTaskNotifyFromISR() | Sends a task notification safely from an ISR |
| xTaskNotifyGive() | Increments a task's notification value and unblocks it if waiting |
| vTaskNotifyGiveFromISR() | Increments a task’s notification value from an ISR |
| xTaskNotifyAndQuery() | Sends a notification and returns the task’s previous notification value |
| xTaskNotifyAndQueryFromISR() | Performs notify-and-query safely from an ISR |
| ulTaskNotifyTake() | Waits for a notification count, then clears or decrements it |
| xTaskNotifyWait() | Waits for a notification and optionally clears selected notification bits |
Task notifications enable direct communication between tasks without requiring separate kernel objects such as queues, semaphores, or event groups.
- Pending: When a task receives a notification, its notification state is set to pending.
- Not pending: When the task processes the notification, its notification state is cleared to not pending.
Advantages: Faster than using queues, semaphore and event groups to perform an equivalent operation. Requires significantly less RAM than using a queue, semaphore or an event group.
Limitations: Unlike queues, semaphores and event groups, task notifications cannot be used to send events or data from a task to an ISR, although they can be used to send events or data from an ISR to a task. Unlike queues, semaphores and event groups, task notifications cannot be sent to multiple tasks.
// FreeRTOSConfig.h
#define configUSE_TASK_NOTIFICATIONS 1 xTaskNotify() sends a task notification to another task and updates the receiving task’s notification value according to the selected eNotifyAction. It can set specific bits, increment the value, overwrite the existing value, update it only when no unread notification is pending, or generate a notification event without modifying the value. If the receiving task is blocked waiting for the notification, it is moved to the Ready state. The function normally returns pdPASS; however, when eSetValueWithoutOverwrite is used, it returns pdFAIL if a previous notification is still pending.
BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction)
// ---------------------- Example ----------------------
TaskHandle_t ReceiverTask_Handler;
uint8_t keyState;
BaseType_t err;
err = xTaskNotify((TaskHandle_t ) ReceiverTask_Handler,
(uint32_t ) keyState,
(eNotifyAction) eSetValueWithOverwrite);xTaskNotifyFromISR() is the interrupt-safe version of xTaskNotify(). It supports the same notification actions and includes the pxHigherPriorityTaskWoken parameter, which is set to pdTRUE if the notification unblocks a task with a higher priority than the currently running task. This variable must be initialized to pdFALSE before the function is called. If it is set to pdTRUE, portYIELD_FROM_ISR() should be called before exiting the ISR to request an immediate context switch.
BaseType_t xTaskNotifyFromISR(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
BaseType_t * pxHigherPriorityTaskWoken)
TaskHandle_t EventGroupTask_Handler;
#define EVENTBIT_0 (1 << 0)
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR((TaskHandle_t ) EventGroupTask_Handler,
(uint32_t ) EVENTBIT_0,
(eNotifyAction) eSetBits,
(BaseType_t* ) &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);xTaskNotifyGive() increments the target task’s notification value by one and marks the notification as pending. It is equivalent to calling xTaskNotify() with the eIncrement action and is typically paired with ulTaskNotifyTake(). Together, these functions provide a lightweight alternative to a binary or counting semaphore when an event needs to be delivered to a single specific task. xTaskNotifyGive() must be called from task context; use vTaskNotifyGiveFromISR() when sending the notification from an ISR.
BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify)
// ---------------------- Example ----------------------
TaskHandle_t SemapGiveTask_Handler;
xTaskNotifyGive(SemapTakeTask_Handler);
printf("TaskNotifyGive!\r\n");vTaskNotifyGiveFromISR() safely increments a task’s notification value from an interrupt service routine and marks the notification as pending. It is commonly used to unblock a task responsible for deferred interrupt processing, such as handling received data or processing a completed DMA transfer. The pxHigherPriorityTaskWoken parameter indicates whether the notification unblocked a task with a higher priority than the interrupted task. If it is set to pdTRUE, portYIELD_FROM_ISR() should be called before exiting the ISR to request an immediate context switch.
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskHandle,
BaseType_t * pxHigherPriorityTaskWoken)
// ---------------------- Example ----------------------
TaskHandle_t DataProcess_Handler;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(DataProcess_Handler, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);xTaskNotifyAndQuery() performs the same notification and value-update operation as xTaskNotify(), while also returning the target task’s previous notification value through pulPreviousNotifyValue. The previous value is captured atomically before the selected eNotifyAction modifies it. This is useful when the sending task needs to inspect and update the notification value in a single operation, such as checking previously set event bits or reading a counter before incrementing or overwriting it. The function must be called from task context.
BaseType_t xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue)xTaskNotifyAndQueryFromISR() is the interrupt-safe version of xTaskNotifyAndQuery(). It sends a notification to the target task, updates its notification value according to the selected eNotifyAction, and returns the value that existed before the update through pulPreviousNotifyValue. The pxHigherPriorityTaskWoken parameter indicates whether the notification unblocked a higher-priority task, allowing the ISR to request an immediate context switch with portYIELD_FROM_ISR(). The function normally returns pdPASS; however, when eSetValueWithoutOverwrite is used, it returns pdFAIL if an unread notification is already pending.
BaseType_t xTaskNotifyAndQueryFromISR(
TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t * pulPreviousNotificationValue
BaseType_t * pxHigherPriorityTaskWoken)ulTaskNotifyTake() allows the calling task to block until its notification value becomes nonzero or the specified timeout expires. When a notification is received, setting xClearCountOnExit to pdTRUE clears the notification value to zero, providing binary-semaphore behavior. Setting it to pdFALSE decrements the value by one, providing counting-semaphore behavior. The function returns the notification value before it is cleared or decremented, or 0 if the wait period expires without a notification.
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit,
TickType_t xTicksToWait)
// ---------------------- Example ----------------------
uint32_t NotifyValue;
NotifyValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);xTaskNotifyWait() blocks the calling task until a notification becomes pending or the specified timeout expires. It can clear selected bits in the task’s notification value before waiting and clear additional bits after the received value has been copied to pulNotificationValue. This makes it well suited for receiving event flags or a 32-bit mailbox value sent through xTaskNotify(). The function returns pdTRUE when a notification is received and pdFALSE if the wait period expires without one.
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t * pulNotificationValue,
TickType_t xTicksToWait)
// ---------------------- Example ----------------------
uint32_t NotifyValue;
BaseType_t err;
err = xTaskNotifyWait((uint32_t ) 0x00, // Clear no bits before waiting
(uint32_t ) ULONG_MAX, // Clear all bits after receiving
(uint32_t* ) &NotifyValue, // Store the received notification value
(TickType_t) portMAX_DELAY); // Wait indefinitely Back to top of the page