📖 Scenario: You are building a simple embedded system using FreeRTOS. The system has a button connected to an interrupt. When the button is pressed, the interrupt service routine (ISR) should notify a task to handle the button press event.
🎯 Goal: Create a FreeRTOS program where an ISR notifies a task using the ISR-to-task notification pattern. The task will print a message when it receives the notification.
📋 What You'll Learn
Create a task called ButtonTask that waits for a notification.
Create an ISR called ButtonISR that sends a notification to ButtonTask.
Use ulTaskNotifyTake in the task to wait for the notification.
Use xTaskNotifyGiveFromISR in the ISR to notify the task.
Print "Button pressed!" in the task when notified.
💡 Why This Matters
🌍 Real World
This pattern is used in embedded systems where hardware interrupts need to signal tasks to perform work without blocking the ISR.
💼 Career
Embedded software engineers use ISR-to-task notifications to write responsive and efficient real-time applications.
Progress0 / 4 steps
1
Create the ButtonTask task
Create a FreeRTOS task called ButtonTask that runs the function vButtonTask. Inside vButtonTask, write an infinite loop with no code inside yet.
FreeRTOS
Hint
Use xTaskCreate to create the task and vTaskStartScheduler to start FreeRTOS.
2
Add a notification wait in ButtonTask
Inside the infinite loop of vButtonTask, add a call to ulTaskNotifyTake(pdTRUE, portMAX_DELAY) to wait indefinitely for a notification from the ISR.
FreeRTOS
Hint
ulTaskNotifyTake blocks the task until a notification is received.
3
Create the ButtonISR to notify the task
Create an ISR function called ButtonISR that calls xTaskNotifyGiveFromISR to notify ButtonTask. Use a global variable xButtonTaskHandle to store the task handle. Also, declare xButtonTaskHandle as a global variable and assign it when creating the task in main.
FreeRTOS
Hint
Use xTaskNotifyGiveFromISR to notify the task safely from the ISR.
4
Print message when notified in ButtonTask
Modify vButtonTask so that after ulTaskNotifyTake returns, it prints "Button pressed!" using printf.
FreeRTOS
Hint
Use printf("Button pressed!\n") to show the message when the task is notified.
Practice
(1/5)
1. What is the main purpose of the ISR-to-task notification pattern in FreeRTOS?
easy
A. To allow an interrupt to quickly notify a task to run
B. To create a new task from an ISR
C. To pause a task until an interrupt finishes
D. To disable interrupts during task execution
Solution
Step 1: Understand ISR and task roles
ISRs handle hardware events quickly, tasks do longer processing.
Step 2: Identify notification purpose
The pattern lets ISR tell a task to run without delay.
Final Answer:
To allow an interrupt to quickly notify a task to run -> Option A
Quick Check:
ISR notifies task [OK]
Hint: ISR signals task to run fast using notifications [OK]
Common Mistakes:
Thinking ISR creates tasks
Believing tasks pause interrupts
Confusing disabling interrupts with notifications
2. Which function is correctly used inside an ISR to notify a task in FreeRTOS?
easy
A. vTaskNotifyGiveFromISR()
B. ulTaskNotifyTake()
C. xTaskCreate()
D. vTaskDelay()
Solution
Step 1: Identify ISR notification function
Inside ISR, use vTaskNotifyGiveFromISR() to notify tasks.
Step 2: Differentiate task functions
ulTaskNotifyTake() is used in tasks, not ISRs.
Final Answer:
vTaskNotifyGiveFromISR() -> Option A
Quick Check:
Notify from ISR = vTaskNotifyGiveFromISR() [OK]
Hint: Use vTaskNotifyGiveFromISR() inside ISR only [OK]
Common Mistakes:
Using ulTaskNotifyTake() inside ISR
Calling xTaskCreate() in ISR
Using vTaskDelay() inside ISR
3. Given this code snippet, what will be the output printed by the task?
D. Using vTaskNotifyGive() inside ISR instead of vTaskNotifyGiveFromISR()
Solution
Step 1: Check ISR notification function
vTaskNotifyGive() is not safe inside ISR; must use vTaskNotifyGiveFromISR().
Step 2: Verify task code correctness
TaskFunction can have single call; infinite loop is common but not error here.
Final Answer:
Using vTaskNotifyGive() inside ISR instead of vTaskNotifyGiveFromISR() -> Option D
Quick Check:
ISR notification function must end with FromISR [OK]
Hint: Use FromISR suffix functions inside ISRs [OK]
Common Mistakes:
Calling task functions inside ISR
Ignoring FromISR suffix importance
Assuming printf() is disallowed in tasks
5. You want to notify a task from multiple ISRs using ISR-to-task notifications. Which approach ensures the task processes all notifications without missing any?
hard
A. Use vTaskNotifyGiveFromISR() once and ulTaskNotifyTake() once; task processes only one notification
B. Use xTaskNotifyGive() in ISRs and ulTaskNotifyTake() in task with zero timeout
C. Use ulTaskNotifyTake() with clear count and call vTaskNotifyGiveFromISR() in each ISR; task loops to process all notifications
D. Use a global variable incremented in ISRs and checked in task without notifications
Solution
Step 1: Understand multiple ISR notifications
Each ISR calls vTaskNotifyGiveFromISR() to increment notification count.
Step 2: Task processes all notifications
Task uses ulTaskNotifyTake(pdTRUE, portMAX_DELAY) in a loop to clear all counts and process each notification.
Final Answer:
Use ulTaskNotifyTake() with clear count and call vTaskNotifyGiveFromISR() in each ISR; task loops to process all notifications -> Option C
Quick Check:
Multiple ISR notifications require counting and looping [OK]
Hint: Loop ulTaskNotifyTake() to handle multiple ISR signals [OK]
Common Mistakes:
Assuming one notification covers all ISR events
Using non-FromISR functions in ISR
Ignoring notification count clearing
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.