NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4) 与 NVIC_SetPriorityGrouping(0) 的效果相同吗?
Cube MX 生成一个值为 NVIC_PRIORITYGROUP_4 的调用,其定义为
#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 位抢占优先级子优先级为 0 位 */
但是如果你遵循函数 NVIC_SetPriorityGrouping() 它无论如何都会将值限制为 3 位,并且两者的效果是相同的,那么为什么 Cube 默认为
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)
我已经在我的目标中测试了两者,它们显然都相同,但如果存在一些非常细微的差异,我可能永远不会知道。
这里有一个提示
https://freertos.org/RTOS-Cortex-M3-M4.html
它说
大多数系统默认使用所需的配置,但 STM32 驱动程序库是一个明显的例外。如果您将 STM32 与 STM32 驱动程序库一起使用,则通过调用 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ) 确保所有优先级位都被分配为抢占优先级位;在 RTOS 启动之前。
/** \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; }
下表来自 ARM CM4 通用用户指南文档 (ARM DUI 0553A):
在表格上方的文本中:“中断优先级小于 8 位的实现将最低有效位数视为零”
STM32 CM4(和 CM7)仅实现 4 位中断优先级,因此当所有 4 位都分配给抢占优先级时,不会留下任何子优先级。
所以,是的,值 0 到 3 (b'0xx) 具有相同的效果。
另外可以参考另一篇博客: https://www.ocfreaks.com/interrupt-priority-grouping-arm-cortex-m-nvic/