FreeRTOS Interrupt Priorities vs. MCU Interrupt Priorities

Hello guys, I am new to FreeRTOS, and for the time being I have a big confusion about interrupt priorities. Here is the issue:
FreeRTOS interrupt priorities are numerically proportional to the priority level. Example: 5 has a lower priority than 95. On the other hand, MCU priorities are the opposite, i.e. 0 has a higher priority than 15. Until now everything is fine.
Now I’m reading this Richard Barry’s authored book: “Using the FreeRTOS Real Time Kernel” from where I took this graphic:
image

Now, I am looking at the FreeRTOSConfig.h header, from where I copied this part:
**
/* Use the system definition, if there is one /
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /
15 priority levels */
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

/* The lowest priority. /
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/
Priority 5, or 95 as only the top four bits are implemented. /
/
!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!
See RTOS for ARM Cortex-M. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
**
According to the book I am reading, if I want to use Interrupt safe API functions and nest them, I should use interrupts between configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY values inclusive.
Now, in the graphic attached, the reference is MCU priorities, meaning that priority 1 is a higher level than priority 7, which makes the configKERNEL_INTERRUPT_PRIORITY higher than configMAX_SYSCALL_INTERRUPT_PRIORITY, which incidentally has a MAX word, meaning that it is the maximum priority (in FreeRTOS reference). So, first question: shouldn’t configMAX_SYSCALL_INTERRUPT_PRIORITY be always numerically higher than configKERNEL_INTERRUPT_PRIORITY ? If the answer is yes, shouldn’t the graphic priority assignment be the opposite, that is: configMAX_SYSCALL_INTERRUPT_PRIORITY=1 and configKERNEL_INTERRUPT_PRIORITY=3 considering that the reference is MCU priority ?
Because we have 2 different references, how do I know which is the highest priority? The lower in MCU(0) or the higest in FreeRTOS(95 in this case)? I mean, for the MCU, 0 will be the highest and for FreeRTOS, would be 95 right?
Coming back to FreeRTOSConfig.h: Is it posible to modify this header, so I can put all the priorities in the same range? (0~15) and within this range plainly assign values to configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY so i will have a clear understanding of what is going on?
I’m sorry for the confusing text, but is the same all inside my head.

I’d recommend to also read the FreeRTOS docs regarding RTOS for ARM Cortex-M and
e.g. Understanding priority levels of ISR and FreeRTOS APIs - #16 by aggarg which contains a pretty good explanation of this rather confusing topic.
There are much more posts regarding interrupt priorities in the forum (search: configMAX_SYSCALL_INTERRUPT_PRIORITY).

1 Like

The assigning of numeric values to abstracted priorities varies according to MCU architecture. The “lower number is higher priority” convention is adopted by ARM Cortex, but I suspect the book was written with “higher number is higher priority” in mind.

Yes, I figure it was intended that way

Question 1 Part 1

In this case, yes. This is because in this model (currently also in Chapter 6.8 of Mastering The FreeRTOS Kernel) the priority is the logical priority and not the numerical priority.

Below this graphic should be the explanation that…

The relationship between an interrupt’s numeric priority and logical priority is dependent on the
processor architecture; on some processors, the higher the numeric priority assigned to an
interrupt the higher that interrupt’s logical priority will be, while on other processor architectures
the higher the numeric priority assigned to an interrupt the lower that interrupt’s logical priority
will be.

Question 1 Part 2

This diagram, and the explanation that comes with it, is written with the logical priority in mind. Using logical priority in the explanation allows this to apply to any processor. For example, in your case the lower MCU ISR number has the higher priority than a higher numbered ISR. For other chips it may be the other way around. In both of these cases however, the highest logical priority will correspond to either the lower number (if lower number is highest priority) OR to the highest number (if highest number is highest priority).


Question 2

Interrupt Service Routines (ISRs) will always have a higher priority than any FreeRTOS task. AFAIK the only FreeRTOS task which operates with an ISR priority level is the timer tick, which operates at the lower priority level (also covered in the chapter).


Question 3

I can see how the or 95 as only the top four bits are implemented can be confusing. I n this case 95 would be the decimal value of the byte (aka 0x5F) after the shift. The lowest priority would have a value of 255 (aka 0xFF) after the shift. This exact scenario is explained on page 232 of Mastering FreeRTOS

This port should already have the priorities in the same range - but feel free to play around with the code.

1 Like

I’d also very much advise looking into the resources provided by @hs2. The links can help further explain interrupt priorities.

Thank you Mr. Kody for the explanation. I guess with time I will get used to this rather confusing subject. For now, I have managed to make it work fine using the vTaskNotifyGiveFromISR API. A lot of testing needs to be done though

If you define configASSERT, all the incorrect priority configurations are caught. Therefore, it is strongly recommended to define configASSERT during development.

Thank you Mr. Gaurav for the tip