cancel
Showing results for 
Search instead for 
Did you mean: 

Is NVIC_PRIORITYGROUP_4 (3) same in effect as 0 ? (32F417)

PHolt.1
Senior III

Cube MX generates a call with a value of NVIC_PRIORITYGROUP_4 which is defined as

#define NVIC_PRIORITYGROUP_4     0x00000003U /*!< 4 bits for pre-emption priority

                           0 bits for subpriority */

but if you follow the function NVIC_SetPriorityGrouping() it limits the value to 3 bits anyway, and the effect of both is identical, so why does Cube default to

NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)

I have tested both in my target and they both work apparently the same, but if there is some very subtle difference, I might never know.

There is a hint here

https://freertos.org/RTOS-Cortex-M3-M4.html

which says

Most systems default to the wanted configuration, with the noticeable exception of the STM32 driver library. If you are using an STM32 with the STM32 driver library then ensure all the priority bits are assigned to be preempt priority bits by calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before the RTOS is started.

but this just takes you round in circles.

Is there any downside to just using NVIC_SetPriorityGrouping(0)?

I am running FreeRTOS. All my interrupts are levels 1,2, and Systick is 15 as required by FreeRTOS.

I don't want any of that sub priority stuff.

Thank you in advance for any help.

4 REPLIES 4
gbm
Lead III

In real life, nobody wants that subpriority stuff. 😉 I mean, I could describe the scenario in which it would be useful and proper, it's just this scenario does not appear in real projects. By default, every NVIC is configured to max. no. of premeption levels. It's just the fantasy of HAL people to set it again to the same value, like with lots of other registers. It seems that HAL authors don't trust any reset values specified in tech docs.

PHolt.1
Senior III

Indeed, but isn't a parameter of 3 same as 0? I struggle to see any difference unless that comment

/*!< 4 bits for pre-emption priority 0 bits for subpriority */

is wrong. Anyway, it is slightly wrong because the value is limited to 3 bits anyway:

/**
  \brief   Set Priority Grouping
  \details Sets the priority grouping field using the required unlock sequence.
           The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
           Only values from 0..7 are used.
           In case of a conflict between priority grouping and available
           priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
  \param [in]      PriorityGroup  Priority grouping field.
 */
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  uint32_t reg_value;
  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
 
  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
  reg_value  =  (reg_value                                   |
                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos)  );              /* Insert write key and priority group */
  SCB->AIRCR =  reg_value;
}

A value of 3 or 0 selects the same row, surely?

0693W00000Y8cwUQAR.png

Below is table from ARM CM4 generic User Guide document (ARM DUI 0553A):

In text above the table: "Implementations having fewer than 8-bits of interrupt priority treat the least significant bits as zero"

0693W00000Y8goAQAR.jpgSTM32 CM4 (and CM7) implement only 4 bits of interrupt priority, so when all 4 bits are assigned to preemption priority, nothing is left for sub-priority.

So yes, values 0 to 3 (b'0xx) have same effect.

Thank you for the interesting observation.

PHolt.1
Senior III

Thank you for confirming.

Would anyone have any idea for the origin of this statement on the FreeRTOS website

https://freertos.org/RTOS-Cortex-M3-M4.html

Most systems default to the wanted configuration, with the noticeable exception of the STM32 driver library. If you are using an STM32 with the STM32 driver library then ensure all the priority bits are assigned to be preempt priority bits by calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before the RTOS is started.

I was wondering if perhaps FreeRTOS reads the PRIGROUP bits after it starts up and uses the bits 1..0 field for some purpose, so for its own purposes they may not be dont-care. But, stepping through the RTOS startup code, they do read PRIMASK very early on but that's not the same register and it doesn't seem to get used for anything (I didn't step on for hours) except to detect if it is being called from an ISR (which I don't do anyway). I see no evidence of PRIGROUP or AIRCR being accessed by FreeRTOS.