ulTaskNotifyTake() helps a task wait for a signal or event from another task or interrupt. It makes tasks sleep until something important happens.
ulTaskNotifyTake() for binary/counting notification in FreeRTOS
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait);
xClearCountOnExit: Use 1 (pdTRUE) to reset the notification count to zero after taking it (binary behavior). Use 0 (pdFALSE) to keep counting notifications (counting behavior).
xTicksToWait: How long the task waits if no notification is available. Use portMAX_DELAY to wait forever.
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ulTaskNotifyTake(pdFALSE, 100);This program creates two tasks. The sender sends three notifications with 500ms delay each. The receiver waits and counts notifications using ulTaskNotifyTake() in counting mode (xClearCountOnExit = pdFALSE). It prints how many notifications it got each time. When it receives all three, it stops.
#include "FreeRTOS.h" #include "task.h" #include <stdio.h> TaskHandle_t xTaskHandle = NULL; void vSenderTask(void *pvParameters) { for (int i = 1; i <= 3; i++) { vTaskDelay(pdMS_TO_TICKS(500)); xTaskNotifyGive(xTaskHandle); // Send notification printf("Sender: Notification %d sent\n", i); } vTaskDelete(NULL); } void vReceiverTask(void *pvParameters) { uint32_t ulCount; uint32_t ulTotalCount = 0; while (1) { ulCount = ulTaskNotifyTake(pdFALSE, portMAX_DELAY); // Counting mode printf("Receiver: Got %lu notifications\n", ulCount); ulTotalCount += ulCount; if (ulTotalCount >= 3) { printf("Receiver: Received all notifications, exiting.\n"); break; } } vTaskDelete(NULL); } int main(void) { xTaskCreate(vReceiverTask, "Receiver", 1000, NULL, 2, &xTaskHandle); xTaskCreate(vSenderTask, "Sender", 1000, NULL, 2, NULL); vTaskStartScheduler(); return 0; }
ulTaskNotifyTake() returns the number of notifications received since last call if counting mode is used.
Use pdTRUE for binary notification to clear count after taking it.
ulTaskNotifyTake() is efficient and lightweight compared to semaphores.
ulTaskNotifyTake() lets a task wait for notifications from other tasks or interrupts.
Use xClearCountOnExit = pdTRUE for binary (single) notification, pdFALSE for counting multiple notifications.
It helps tasks sleep and save CPU until something important happens.
Practice
ulTaskNotifyTake() function do in FreeRTOS?Solution
Step 1: Understand the purpose of ulTaskNotifyTake()
This function is designed to make a task wait (block) until it receives a notification from another task or interrupt.Step 2: Differentiate from other task functions
Creating, sending, or deleting tasks are done by other FreeRTOS functions, not ulTaskNotifyTake().Final Answer:
It blocks a task until a notification is received. -> Option DQuick Check:
ulTaskNotifyTake() waits for notification [OK]
- Confusing ulTaskNotifyTake() with task creation functions
- Thinking it sends notifications instead of receiving
- Assuming it deletes tasks
ulTaskNotifyTake() controls whether the notification count resets on exit?Solution
Step 1: Identify parameters of ulTaskNotifyTake()
ulTaskNotifyTake() takes two parameters: xClearCountOnExit and xTicksToWait.Step 2: Understand xClearCountOnExit role
This parameter decides if the notification count resets to zero when the function exits (pdTRUE) or not (pdFALSE).Final Answer:
xClearCountOnExit -> Option AQuick Check:
xClearCountOnExit resets count [OK]
- Mixing xClearCountOnExit with xTicksToWait
- Assuming ulNotificationValue is a parameter
- Confusing with notification sending options
uint32_t count = ulTaskNotifyTake(pdFALSE, portMAX_DELAY); // Assume 3 notifications were sent before this callWhat will be the value of
count after this call?Solution
Step 1: Analyze xClearCountOnExit parameter
pdFALSE means the notification count is not cleared on exit, so it counts all notifications received.Step 2: Understand the count returned
Since 3 notifications were sent before, ulTaskNotifyTake() returns the total count, which is 3.Final Answer:
3 -> Option CQuick Check:
pdFALSE keeps count, so count = 3 [OK]
- Assuming count resets to 1 regardless
- Confusing portMAX_DELAY as return value
- Thinking count is zero if notifications sent before
uint32_t count = ulTaskNotifyTake(pdTRUE, 100);
if(count == 0) {
// No notification received
}
// Task expects to count multiple notifications
Solution
Step 1: Check xClearCountOnExit usage
pdTRUE clears the notification count on exit, so only a binary notification is counted, not multiple.Step 2: Understand task expectation
The task expects to count multiple notifications, but pdTRUE resets count, so it cannot accumulate multiple counts.Final Answer:
Using pdTRUE clears count, so multiple notifications can't be counted. -> Option AQuick Check:
pdTRUE clears count, no multiple counting [OK]
- Thinking timeout 100 is invalid
- Believing ulTaskNotifyTake() can't be in if
- Confusing variable type for count
ulTaskNotifyTake() usage is correct?Solution
Step 1: Understand counting notifications
Using pdFALSE keeps the count of notifications, so the function returns the total number received.Step 2: Use single call to wait indefinitely
Calling ulTaskNotifyTake(pdFALSE, portMAX_DELAY) waits until at least one notification arrives and returns the count accumulated.Step 3: Check if count equals 2
After the call returns, check if the count is exactly 2 to proceed.Final Answer:
Call ulTaskNotifyTake(pdFALSE, portMAX_DELAY) once and check if return is 2. -> Option BQuick Check:
pdFALSE counts notifications; check return for 2 [OK]
- Calling ulTaskNotifyTake multiple times and summing counts
- Using pdTRUE which resets count
- Using zero timeout causing immediate return
Ready to prove it?
Pass the test and this pattern moves unknown
