When your program reacts to hardware events, it uses special functions called ISRs. These functions must use special safe calls to avoid problems.
ISR-safe API functions (FromISR suffix) in FreeRTOS
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
Functions with FromISR suffix are safe to call inside interrupts.
They often have an extra parameter to check if a higher priority task should run next.
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
xQueueSendFromISR(xQueue, &data, &xHigherPriorityTaskWoken);
vTaskNotifyGiveFromISR(xTaskHandle, &xHigherPriorityTaskWoken);
This program shows how to safely send data and give a semaphore from an ISR using the FromISR functions. It also shows how to check if a higher priority task should run next.
#include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" QueueHandle_t xQueue; SemaphoreHandle_t xSemaphore; void ISR_Handler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; int data = 100; // Send data to queue safely from ISR xQueueSendFromISR(xQueue, &data, &xHigherPriorityTaskWoken); // Give semaphore safely from ISR xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken); // Request context switch if needed portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } int main(void) { xQueue = xQueueCreate(5, sizeof(int)); xSemaphore = xSemaphoreCreateBinary(); // Normally tasks and interrupts would be set up here // Simulate ISR call ISR_Handler(); // Check queue and semaphore status (simplified) int receivedData; if (xQueueReceive(xQueue, &receivedData, 0) == pdTRUE) { printf("Received from queue: %d\n", receivedData); } if (xSemaphoreTake(xSemaphore, 0) == pdTRUE) { printf("Semaphore was given from ISR\n"); } return 0; }
Always use FromISR functions inside interrupts to avoid crashes or data corruption.
Remember to use portYIELD_FROM_ISR() to switch tasks if needed after ISR work.
FromISR functions are special calls safe for interrupts.
They help communicate between interrupts and tasks without errors.
Use the extra parameter to know if you should switch tasks right away.
Practice
What is the main reason to use FreeRTOS API functions with the FromISR suffix inside an interrupt service routine (ISR)?
Solution
Step 1: Understand ISR context constraints
Inside an ISR, normal FreeRTOS API functions are unsafe because they may block or cause race conditions.Step 2: Role of FromISR functions
Functions with theFromISRsuffix are designed to be safe in interrupt context by avoiding blocking and managing critical sections properly.Final Answer:
They are safe to call from ISRs and handle interrupt context correctly. -> Option BQuick Check:
FromISR functions = ISR safe calls [OK]
- Calling normal API functions inside ISR causing crashes
- Assuming FromISR functions disable interrupts
- Thinking FromISR creates tasks automatically
Which of the following is the correct way to declare a variable to track if a higher priority task was woken inside an ISR?
?Solution
Step 1: Identify FreeRTOS type for ISR task wake flag
FreeRTOS usesBaseType_tfor portability and definespdFALSEandpdTRUEfor boolean values.Step 2: Correct initialization
The variable must start aspdFALSEto indicate no task was woken yet.Final Answer:
BaseType_t higherPriorityTaskWoken = pdFALSE; -> Option CQuick Check:
Use BaseType_t and pdFALSE for ISR flags [OK]
- Using plain int instead of BaseType_t
- Initializing flag to 1 instead of pdFALSE
- Using bool which may not be portable
Consider this ISR code snippet:
BaseType_t higherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(queue, &data, &higherPriorityTaskWoken);
if (higherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}What happens if higherPriorityTaskWoken is set to pdTRUE after xQueueSendFromISR?
Solution
Step 1: Understand higherPriorityTaskWoken flag
This flag indicates if a task with higher priority than the current one was made ready by the ISR.Step 2: Role of portYIELD_FROM_ISR()
If the flag is true, callingportYIELD_FROM_ISR()requests a context switch to that higher priority task immediately after ISR exit.Final Answer:
The ISR requests a context switch to the higher priority task immediately after ISR. -> Option AQuick Check:
higherPriorityTaskWoken true triggers context switch [OK]
- Thinking interrupts are disabled by portYIELD_FROM_ISR()
- Assuming queue send fails if flag is true
- Believing higher priority task waits for ISR to finish
Identify the error in this ISR code snippet:
void ISR_Handler(void) {
BaseType_t higherPriorityTaskWoken = pdFALSE;
xSemaphoreGive(semaphore);
if (higherPriorityTaskWoken) {
portYIELD_FROM_ISR();
}
}What is the problem here?
Solution
Step 1: Check function used for semaphore give
The code usesxSemaphoreGive, which is not safe inside ISR context.Step 2: Correct ISR-safe function usage
Inside ISR,xSemaphoreGiveFromISRmust be used withhigherPriorityTaskWokenpassed by reference to track task wake.Final Answer:
The higherPriorityTaskWoken variable is not passed to xSemaphoreGiveFromISR. -> Option DQuick Check:
Use FromISR functions with higherPriorityTaskWoken [OK]
- Using normal API functions inside ISR
- Not passing higherPriorityTaskWoken pointer
- Declaring higherPriorityTaskWoken as global unnecessarily
You want to send data from an ISR to a task using a queue. Which sequence correctly uses FreeRTOS ISR-safe API functions to do this and ensure the higher priority task runs immediately if woken?
?Solution
Step 1: Use ISR-safe queue send function
Inside ISR,xQueueSendFromISRmust be used with a pointer tohigherPriorityTaskWoken.Step 2: Check higherPriorityTaskWoken and yield
IfhigherPriorityTaskWokenis set topdTRUE, callportYIELD_FROM_ISR()to request immediate context switch.Final Answer:
BaseType_t higherPriorityTaskWoken = pdFALSE; xQueueSendFromISR(queue, &data, &higherPriorityTaskWoken); if (higherPriorityTaskWoken) portYIELD_FROM_ISR(); -> Option AQuick Check:
Use FromISR + check flag + yield [OK]
- Using normal xQueueSend inside ISR
- Not passing higherPriorityTaskWoken pointer
- Calling portYIELD_FROM_ISR unconditionally
Ready to prove it?
Pass the test and this pattern moves unknown
