0
0
FreeRTOSprogramming~7 mins

Nested interrupt handling in FreeRTOS

Choose your learning style9 modes available
Introduction

Nested interrupt handling lets higher priority interrupts pause lower priority ones. This helps your system respond faster to urgent events.

When you have multiple interrupts with different importance levels.
When a critical sensor needs immediate attention even if another interrupt is running.
When you want to improve system responsiveness in real-time applications.
When handling time-sensitive tasks that must not wait.
When you want to avoid missing important events during long interrupt processing.
Syntax
FreeRTOS
void ISR_Handler(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    // Handle interrupt

    // Clear interrupt flag

    // If a higher priority task was woken by ISR
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

Use portYIELD_FROM_ISR() to request a context switch if needed.

Configure interrupt priorities properly to enable nesting.

Examples
Example of a high priority ISR that can preempt lower priority ISRs.
FreeRTOS
void HighPriorityISR(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // Handle high priority interrupt
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
Example of a low priority ISR that can be interrupted by higher priority ISRs.
FreeRTOS
void LowPriorityISR(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // Handle low priority interrupt
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
Sample Program

This program simulates two interrupts: low and high priority. The high priority interrupt can preempt the low priority one, showing nested interrupt handling.

FreeRTOS
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

volatile int highPriorityFlag = 0;
volatile int lowPriorityFlag = 0;

void HighPriorityISR(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    highPriorityFlag = 1; // Set flag
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

void LowPriorityISR(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    lowPriorityFlag = 1; // Set flag
    // Simulate longer processing
    for (volatile int i = 0; i < 100000; i++) {}
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

int main(void) {
    // Simulate interrupts firing
    LowPriorityISR();
    if (lowPriorityFlag) {
        printf("Low priority interrupt handled\n");
    }
    HighPriorityISR();
    if (highPriorityFlag) {
        printf("High priority interrupt handled\n");
    }
    return 0;
}
OutputSuccess
Important Notes

Make sure interrupt priorities are set correctly in your microcontroller to allow nesting.

Keep ISRs short to avoid long blocking of other interrupts.

Use portYIELD_FROM_ISR() to switch tasks safely after ISR.

Summary

Nested interrupts let urgent tasks interrupt less urgent ones.

Use proper priority settings and portYIELD_FROM_ISR() in FreeRTOS ISRs.

Keep interrupt code short and efficient for best results.