0
0
FreeRTOSprogramming~20 mins

xTaskNotifyGive() as lightweight semaphore in FreeRTOS - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
FreeRTOS Notification Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this FreeRTOS task notification example?

Consider two tasks: TaskA and TaskB. TaskA calls xTaskNotifyGive(TaskBHandle); and TaskB waits using ulTaskNotifyTake(pdTRUE, portMAX_DELAY);. What will TaskB receive?

FreeRTOS
void TaskA(void *pvParameters) {
    // Notify TaskB
    xTaskNotifyGive(TaskBHandle);
    vTaskDelay(pdMS_TO_TICKS(1000));
}

void TaskB(void *pvParameters) {
    // Wait for notification
    uint32_t count = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    printf("Notification count: %lu\n", count);
    vTaskDelete(NULL);
}
ANotification count: 2
BNotification count: 0
CNotification count: 1
DThe code causes a runtime error
Attempts:
2 left
💡 Hint

Think about what xTaskNotifyGive() does to the notification value and how ulTaskNotifyTake() reads it.

🧠 Conceptual
intermediate
1:30remaining
Which statement best describes xTaskNotifyGive() as a lightweight semaphore?

In FreeRTOS, how does xTaskNotifyGive() function as a lightweight semaphore?

AIt increments a task's notification value, signaling availability of a resource.
BIt creates a new semaphore object in the kernel.
CIt blocks the calling task until a resource is free.
DIt resets the task notification value to zero.
Attempts:
2 left
💡 Hint

Think about what happens to the task notification value when xTaskNotifyGive() is called.

🔧 Debug
advanced
2:30remaining
Why does this code cause TaskB to block forever?

TaskA calls xTaskNotifyGive(TaskBHandle); twice quickly. TaskB calls ulTaskNotifyTake(pdTRUE, 1000); once. TaskB never proceeds. Why?

FreeRTOS
void TaskA(void *pvParameters) {
    xTaskNotifyGive(TaskBHandle);
    xTaskNotifyGive(TaskBHandle);
    vTaskDelete(NULL);
}

void TaskB(void *pvParameters) {
    uint32_t count = ulTaskNotifyTake(pdTRUE, 1000);
    if(count == 0) {
        printf("Timeout waiting for notification\n");
    } else {
        printf("Received notification count: %lu\n", count);
    }
    vTaskDelete(NULL);
}
ABecause ulTaskNotifyTake resets the count to zero after first call, second notify is lost.
BBecause TaskB never calls ulTaskNotifyTake twice to consume both notifications.
CBecause xTaskNotifyGive does not increment the notification value.
DBecause TaskA deletes itself before TaskB starts.
Attempts:
2 left
💡 Hint

Consider how many notifications TaskB consumes with one call to ulTaskNotifyTake().

📝 Syntax
advanced
2:00remaining
Which option correctly uses xTaskNotifyGive() and ulTaskNotifyTake() as a semaphore?

Choose the code snippet that correctly uses xTaskNotifyGive() and ulTaskNotifyTake() to synchronize two tasks.

A
xTaskNotifyGive(TaskHandle);
uint32_t count = ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
B
xTaskNotifyGive(TaskHandle);
uint32_t count = ulTaskNotifyTake(pdTRUE);
C
xTaskNotifyGive(TaskHandle, 1);
uint32_t count = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
D
xTaskNotifyGive(TaskHandle);
uint32_t count = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
Attempts:
2 left
💡 Hint

Check the parameters of ulTaskNotifyTake() and how xTaskNotifyGive() is called.

🚀 Application
expert
2:30remaining
How many notifications can ulTaskNotifyTake() accumulate before blocking?

If TaskA calls xTaskNotifyGive(TaskBHandle); 5 times quickly, and TaskB calls ulTaskNotifyTake(pdTRUE, portMAX_DELAY); once, what is the value returned by TaskB?

A5
B0
C1
DIt causes a runtime error
Attempts:
2 left
💡 Hint

Think about how xTaskNotifyGive() increments the notification value and how ulTaskNotifyTake() returns it.