Hello
we would like to use FreeRtos on a M33 (STM32L5).
For our projects we would like to use the following settings for the priorities:
NVIC_SetPriorityGrouping(4); → 8 Groups with 32 Subpriorities bxxx.yyyy
Our idea is that the groups should serve the following purpose:
0 Not used because not maskable
1 RealTime Interrupts
2 FreeRtos
3 High Priority Interrupts
4 Low Priority Interrupts
5 not used
6 not used
7 not used
We are now unsure if we have configured our FreeRtos correctly.
#define configPRIO_BITS 3 // M33 STM32L5 use 3 Bits
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 7 // lowest possible priority is 7???
/* 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 2 // Freertos on group 2???
/* masking out interrupts with BASEPRI */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
Can you tell us if we have correctly understood the defines for this application
The STM32L5 implements only three bits for interrupt priorities. And FreeRTOS requires that all three be used for preemption priorities, with no subpriorities.
So, NVIC_SetPriorityGrouping(4) and configPRIO_BITS 3 and configLIBRARY_LOWEST_INTERRUPT_PRIORITY 7 are all correct for STM32L5.
However, a small correction for your list of interrupt priorities. The FreeRTOS interrupts (the system tick and PendSV) will use priority 7, not priority 2. The 2 from configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY is merely a dividing line. Interrupts using that priority and lower priorities are allowed to call the interrupt-safe FreeRTOS API functions. Interrupts using higher priorities are not allowed. For example, the ISRs for your “RealTime Interrupts” at priority 1 are not allowed to make calls to the FreeRTOS API.
thank you very much for the quick and understandable answer. Just to be sure that we have understood it now the fixed config/interpretation
---------------------- Config 1 --------------------------------
NVIC_SetPriorityGrouping(4); // 8 Groups with 32 Subpriorities bxxx.yyyy
#define configPRIO_BITS 3 // M33 STM32L5 use 3 Bits
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 7 // lowest possible priority is 7
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 // Rtos masked border
0 Not used because not maskable (FreeRTOS APIs can not be called from these ISRs
1 RealTime Interrupts and will never disabled/masked bei Rtos)
-------------------------------------------------------------- configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY Border
2 High Priority Interrupts (FreeRTOS APIs can be called from these ISRs
3 Low Priority Interrupts and can be disabled/masked be Rtos)
4 not used
5 not used
6 not used
7 FreeRtos (Tick)
So would the following configuration not be possible?
---------------------- Config 2 --------------------------------
NVIC_SetPriorityGrouping(5); // 4 Groups with 64 Subpriorities bxx.yyyyy
#define configPRIO_BITS 3 // M33 STM32L5 use 3 Bits
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 3 // lowest possible priority is 3
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 // Rtos masked border
0 Not used because not maskable (FreeRTOS APIs can not be called from these ISRs
1 RealTime Interrupts and will never disabled/masked bei Rtos)
-------------------------------------------------------------- configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY Border
2 High Priority Interrupts (FreeRTOS APIs can be called from these ISRs
3 Low Priority Interrupts / FreeRtos (Tick) and can be disabled/masked be Rtos)
--------------------------------------------------------------
--------------------------------------------------------------
…because they use configLIBRARY_LOWEST_INTERRUPT_PRIORITY if I am not mistaken. So it would be possible to set this to 2 to achieve what es defined in the start post (though not recommended since tick and SV ISRs should typically be the lowest)? Or would this immediately break something?
Right – your config with NVIC_SetPriorityGrouping(4); is correct. One improvement would be to modify the comment that says with 32 Subpriorities to say with 0 subpriorities bxxx.zzzzz. Only 3 bits are implemented (the x bits) and the other 5 are unimplemented (the z bits).
Your config with NVIC_SetPriorityGrouping(5); (which would have 2 subpriorities) probably would work. It seems that the ARMv8-M ports (Cortex M23/M33) don’t actually prohibit the use of subpriorities like the ARMv7-M ports do. But I don’t know if FreeRTOS has officially lifted that requirement, so maybe best not to use subpriorities. I think @aggarg would know.
That was true on the ARMv7-M ports, but the ARMv8-M ports hard-code the tick and SV ISRs to use the lowest priority. If the SV ISR ever preempts another ISR, context corruption can occur.
Setting all the priority bits to preempt priority makes the configuration much simpler and therefore, is still recommended for v8M ports.
Consider the following example where 3 priority bits are implemented and priority group is set to 5:
000 | Priority Level 0, Sub priority Level 0
001 | Priority Level 0, Sub priority Level 1
----|---------------------------------------
010 | Priority Level 2, Sub priority Level 0
011 | Priority Level 2, Sub priority Level 1
----|---------------------------------------
100 | Priority Level 4, Sub priority Level 0
101 | Priority Level 4, Sub priority Level 1
----|---------------------------------------
110 | Priority Level 6, Sub priority Level 0
111 | Priority Level 6, Sub priority Level 1
----|---------------------------------------
If the configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 3, interrupts with priority 2 will also be masked in critical sections as both of them have the same priority level. Setting all the priority bits to preempt priority avoids such surprises.
Since these interrupts always need to run at the lowest priority, these are hard-coded.