Nested interrupt handling in FreeRTOS - Time & Space Complexity
When dealing with nested interrupts in FreeRTOS, it's important to understand how the time spent handling interrupts grows as more interrupts occur.
We want to know how the total handling time changes when interrupts can interrupt other interrupts.
Analyze the time complexity of the following nested interrupt handling code snippet.
void ISR1(void) {
// Handle interrupt 1
if (condition_for_ISR2) {
ISR2(); // Nested interrupt call
}
// Finish ISR1
}
void ISR2(void) {
// Handle interrupt 2
}
This code shows one interrupt service routine (ISR1) that may call another ISR (ISR2) inside it, representing nested interrupts.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: ISR1 executes and may call ISR2 inside it.
- How many times: ISR1 runs once per interrupt, ISR2 runs only if condition is true during ISR1.
As the number of interrupts increases, the total time spent handling them grows roughly in proportion to how many interrupts occur and how often nested interrupts happen.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 interrupts | About 10 ISR1 calls plus some ISR2 calls |
| 100 interrupts | About 100 ISR1 calls plus more ISR2 calls |
| 1000 interrupts | About 1000 ISR1 calls plus many ISR2 calls |
Pattern observation: The total handling time grows roughly linearly with the number of interrupts and nested calls.
Time Complexity: O(n)
This means the total time to handle interrupts grows in a straight line as the number of interrupts increases, including nested ones.
[X] Wrong: "Nested interrupts multiply the handling time exponentially."
[OK] Correct: Each nested interrupt adds some fixed extra time, but they do not multiply the total time exponentially because interrupts are handled one after another, not all at once.
Understanding how nested interrupts affect execution time helps you design responsive systems and shows you can think about how code behaves under real conditions.
"What if ISR2 could also call ISR1 again? How would the time complexity change?"
Practice
What is the main purpose of nested interrupt handling in FreeRTOS?
Solution
Step 1: Understand interrupt priorities
Nested interrupts allow interrupts with higher priority to interrupt those with lower priority.Step 2: Relate to FreeRTOS behavior
FreeRTOS supports nested interrupts to ensure urgent tasks get immediate attention.Final Answer:
Allow higher priority interrupts to interrupt lower priority ones -> Option AQuick Check:
Nested interrupts = higher priority interrupts interrupting lower priority [OK]
- Thinking all interrupts are disabled during task switching
- Believing interrupts run only sequentially without nesting
- Confusing nested interrupts with disabling interrupts
Which of the following is the correct way to yield from an ISR in FreeRTOS?
void ISR_Handler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Some ISR code
// ...
// Yield if needed
?
}Solution
Step 1: Identify correct ISR yield function
In FreeRTOS, portYIELD_FROM_ISR is used to request a context switch from an ISR safely.Step 2: Check other options
taskYIELD is for tasks, vTaskDelay is for delaying tasks, portEND_SWITCHING_ISR is not a FreeRTOS API.Final Answer:
portYIELD_FROM_ISR(xHigherPriorityTaskWoken); -> Option BQuick Check:
Yield from ISR = portYIELD_FROM_ISR [OK]
- Using taskYIELD inside ISR causing errors
- Calling vTaskDelay inside ISR which is invalid
- Confusing portEND_SWITCHING_ISR with portYIELD_FROM_ISR
Given the following FreeRTOS ISR code snippet, what will be the value of xHigherPriorityTaskWoken after execution?
void ISR_Timer(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}Assume the semaphore unblocks a higher priority task waiting.
Solution
Step 1: Understand xSemaphoreGiveFromISR behavior
This function sets xHigherPriorityTaskWoken to pdTRUE if a higher priority task is unblocked.Step 2: Given higher priority task is unblocked
Since the semaphore unblocks a higher priority task, xHigherPriorityTaskWoken becomes pdTRUE.Final Answer:
pdTRUE -> Option CQuick Check:
Higher priority task unblocked = xHigherPriorityTaskWoken pdTRUE [OK]
- Assuming xHigherPriorityTaskWoken stays pdFALSE always
- Confusing semaphore handle with boolean flag
- Ignoring the effect of unblocking higher priority tasks
Identify the error in this nested interrupt handling code snippet:
void ISR_UART(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(xQueue, &data, NULL);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}Solution
Step 1: Check xQueueSendFromISR parameters
The function requires a pointer to xHigherPriorityTaskWoken to update it if a higher priority task is woken.Step 2: Identify missing argument
Passing NULL means xHigherPriorityTaskWoken is never updated, so portYIELD_FROM_ISR may not yield correctly.Final Answer:
xHigherPriorityTaskWoken should be passed to xQueueSendFromISR -> Option DQuick Check:
Pass xHigherPriorityTaskWoken pointer to FromISR APIs [OK]
- Passing NULL instead of &xHigherPriorityTaskWoken
- Calling portYIELD_FROM_ISR without updating flag
- Using wrong variable types for task woken flag
You want to implement nested interrupt handling where a high priority interrupt can preempt a low priority one and safely switch tasks if needed. Which combination of steps is correct?
- Configure interrupt priorities properly
- Use
portYIELD_FROM_ISR()inside ISRs - Disable all interrupts during ISR execution
- Use FromISR API versions for FreeRTOS calls inside ISRs
Choose the best combination.
Solution
Step 1: Configure interrupt priorities
Proper priority setup allows nested interrupts to work correctly.Step 2: Use portYIELD_FROM_ISR and FromISR APIs
These ensure safe task switching and API calls inside ISRs.Step 3: Avoid disabling all interrupts during ISR
Disabling all interrupts prevents nesting, so step 3 is incorrect.Final Answer:
1, 2, and 4 only -> Option AQuick Check:
Nested interrupts need priorities + FromISR APIs + portYIELD_FROM_ISR [OK]
- Disabling all interrupts prevents nesting
- Forgetting to use FromISR API versions
- Ignoring interrupt priority configuration
Ready to prove it?
Pass the test and this pattern moves unknown
