Date: marzo 3, 2025
Author: Guillermo Garcia
Categories: RTOS Tags: FreeRTOS
Interrupts in FreeRTOS are a mechanism crucial role in real-time operating systems (RTOS), enabling efficient handling of time-sensitive tasks. FreeRTOS, a popular RTOS for embedded systems, provides a structured approach to managing interrupts.
Table of Contents
Interrupts are essential in an embedded system since they allow different events to be handled asynchronously. In this article we will see how to manage interruptions when developing applications based on FreeRTOS.
It is important that we know certain details about using interruptions properly before starting to work with the rest of the FreeRTOS mechanisms.
Microcontrollers with an ARM Cortex-M core have a flexible and powerful system for managing interrupts, a nested vector interrupt controller (NVIC).
When dealing with an operating system like FreeRTOS, the NVIC may seem unintuitive, and if interrupts are not managed well, bad things can happen in the application.
The ARM Cortex-M architecture distributes interrupts through a vector where each member of the vector represents a specific interrupt to a system service. Let’s see an example for the M0/M0+ and M4/M4.
This vector includes both system exceptions and peripheral interrupts. Negative IRQs (-1 (SysTick) to -14 (NMI) plus reset) are defined by the ARM core, everything else «above» with an IRQ number >=0 are vendor specific and usually correspond to peripheral interrupts like UART, I²C, USB that are assigned by the microcontroller vendor.
Understanding how interrupts are managed allows us to understand how to assign the correct priorities and also let FreeRTOS know about it. When assigning priorities to an interrupt we have to keep in mind one very important thing:
The lower the priority number assigned, the greater the urgency.
This means that interrupt priority 0 is the most urgent.
The exception/interrupt priority is assigned with an 8-bit priority register and the number of bits implemented depends on the vendor implementation. ARM specifies a minimum of 2 bits for M0/M0+ and 3 bits for M3/M4/M7.
/* Cortex-M specific definitions. */ #ifdef __NVIC_PRIO_BITS /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 /* 15 priority levels */ #endif /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf /* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 /* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
FreeRTOS uses the configKERNEL_INTERRUPT_PRIORITY
macro in FreeRTOSConfig.h for interrupts used by the kernel port layer.
As mentioned above, the important point to note is that configKERNEL_INTERRUPT_PRIORITY
is set to the lowest urgent interrupt level in the system. This means that kernel interrupts (SysTick and context switches) are executed with the lowest urgency possible. This makes sense since the kernel should not block or interrupt the other interrupts in the system.
Using an RTOS like FreeRTOS means that I have to understand its use of the interrupt system because otherwise it can lead to conflicts and incorrect application behavior. The following table can serve as a guide for setting the priorities in our application with FreeRTOS.
It is not uncommon to call RTOS functions (e.g. to set or clear a semaphore) from an interrupt service routine (ISR). There is one very important rule with FreeRTOS:
Only RTOS API functions ending with FromISR
are allowed to be called from an interrupt service routine.
FromISR functions are interrupt-safe, for example:
If there is one thing you need to consider before continuing with this serious issue regarding interruptions in FreeRTOS, it is the following points.
FromISR()
interrupt variants.configMAX_SYSCALL_INTERRUPT_PRIORITY
can use the RTOS API.
Deja una respuesta