Configure FreeRtos with Groups/Subpriorities on M33

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

Best thanks and greetings
Sebastian

Hi Sebastian,

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.

I’d like to add this pretty good explanation of FreeRTOS interrupt mapping and configuration.

Hello Jeff, hello Hartmut,

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)
--------------------------------------------------------------	
--------------------------------------------------------------	

Thanks in advance for your effort!

Greetings
Sebastian

…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?

Hi Sebastian,

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.

Hi Oliver,

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.

1 Like

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.

Thanks.

2 Likes

Thank you all for your support. We have decided to implement our project with the simple config with all preempt priority