在学习了一些关于中断优先级的相当困难的过程之后,我仍然有点想弄清楚我可以在SysTick_IRQn上调用什么值(这是ISR每1ms调用一次FreeRTOS调度器)。
TLDR;
我的一部分人认为HAL_NVIC_SetPriority(SysTick_IRQn, 15 ,0U) (最低优先级可能的)和HAL_NVIC_SetPriority(SysTick_IRQn, 10 ,0U) (稍高一点)之间的任何东西都是允许的,还有一部分我认为HAL_NVIC_SetPriority(SysTick_IRQn, 15 ,0U) (最低优先级可能)和HAL_NVIC_SetPriority(SysTick_IRQn, 5 ,0U) (相当高一点)之间的任何东西都是允许的。这是假设FreeRTOSConfig.h中的configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY设置为5。混淆之处在于,在FreeRTOS中,较高的数字是更高的优先级,而在STM32中,较高的数字是较低的优先级,文档很难理解。
详细信息:
为了证明我已经做出了勇敢的努力,并帮助你帮助我填补空白,以下是我目前的理解。我要写一篇关于我所知道的真理的描述,它看起来像是在教你,尽管我在寻求对我上述问题的答案,以及你认为合适的更正,或附加洞察力。
虽然这可能适用于许多STM32微控制器或家庭,但让我们特别从STM32F207ZG的角度来讨论它。
注:STM32CubeF2下载在这里。
我的理解是:
如果您查看一个标准的FreeRTOSConfig.h文件(例如: STM32Cube_FW_F2_V1.7.0/Projects/STM322xG_EVAL/Applications/FreeRTOS/FreeRTOS_ThreadCreation/Inc/FreeRTOSConfig.h) ),您将看到以下内容:
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
/* 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 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )在STM32Cube_FW_F2_V1.7.0/Drivers/CMSIS/Device/ST/STM32F2xx/Include/stm32f217xx.h中,__NVIC_PRIO_BITS被定义为4U,因为"STM32F2XX使用4位作为优先级级别“。
首先,这很有趣,因为这意味着可用的8个优先级位中只有4个是实际使用的!STM32 HAL库调用HAL_NVIC_SetPriority()有一个标题,如下所示,它似乎表明您有8位要设置(PreemptPriority从0到15,SubPriority从0到15),但实际上您没有--您只有4位要设置。
/**
* @brief Sets the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of IRQn_Type enumeration
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f2xxxx.h))
* @param PreemptPriority: The preemption priority for the IRQn channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority
* @param SubPriority: the subpriority level for the IRQ channel.
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority.
* @retval None
*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{ 因此,您只需要设置4位,但是您可以确定有多少位是PreemptPriority位,多少位是SubPriority位,如下所示:
HAL_NVIC_SetPriorityGrouping(),UM1940,9.2.4,p 124/1371。

如果您使用的是带有STM32驱动程序库的STM32,那么在启动NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 )之前,要确保所有的优先级位都被指定为抢占优先级位。
因此,在代码中首先要做的事情之一(至少在通过osKernelStart()或vTaskStartScheduler()启动osKernelStart()调度程序之前)是:
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);这将您的所有4个优先级位配置为PreemptPriority位,没有一个配置为SubPriority位。这意味着对HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)函数的任何调用现在都将始终使用0作为最右边的参数。
然后,您应该从本质上调用(注意:这是通过HAL_InitTick()调用的
/*Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, 15 ,0U);其中15是SysTick滴答优先级。因为我们所有的4位都可用,这给了我们一个0到15的优先级范围,其中15是最低的中断优先级,0是最高优先级。
那么,为什么我们要将SysTick设置为最低优先级呢?答:因为这是FreeRTOS调度器的一个很好的实践,SysTick中断调用它。事实上,根据他们自己的文档,过高的优先级会破坏FreeRTOS。让我们试着解决这个问题。
我们知道现在PreemptPriority设置的中断选项是0到15,但范围甚至更窄:我们只能将SysTick中断的PreemptPriority设置为10至15 (我认为--这里需要一些帮助)。为什么是10到15?嗯,FreeRTOS文档 (尽管这非常令人困惑)甚至明确声明:
以"FromISR“结尾的FromISR函数是中断安全的,但是即使这些函数也不能从具有逻辑优先级的中断(即:从数字上降低configMAX_SYSCALL_INTERRUPT_PRIORITY定义的优先级(configMAX_SYSCALL_INTERRUPT_PRIORITY是在FreeRTOSConfig.h头文件中定义的)调用)。因此,任何使用RTOS函数的中断服务例程都必须手动将其优先级设置为数值等于或大于configMAX_SYSCALL_INTERRUPT_PRIORITY设置的值。这确保中断的逻辑优先级等于或小于configMAX_SYSCALL_INTERRUPT_PRIORITY设置。
现在,请参阅本页顶部的FreeRTOSConfig.h。我们知道__NVIC_PRIO_BITS是4,我们看到:
configMAX_SYSCALL_INTERRUPT_PRIORITY是(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)),意思是5 << (8 - 4) = decimal 80 = 0b01010000。
FreeRTOS文档提供了一些关于为什么左移的有价值的洞察力(参见题为"Cortex-M内部优先级表示“的部分),但我无法从中辨别出来。
所以,现在做一些有教养的猜测,知道我们的优先级是0到15,0是最高的,15是最低的,而知道configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY是5,我们也许可以使用15-5= 10作为最高优先级,15作为最低优先级,或者5到15是可以的,但是0到4是不允许的?我不知道.我很困惑..。
发布于 2018-05-09 11:22:44
首先,不要混淆FreeRTOS任务优先级和N维也纳优先级。它们是完全不同的。
在上面的示例中,如果中断进行FreeRTOS API调用,您可以对中断使用5到15的中断优先级。如果它们不进行FreeRTOS API调用,那么您可以使用从0到15的任意优先级的中断。
不要担心转移,因为它都是为您处理的,但是原因是使用了优先级寄存器的前4位(注意一些处理器使用不同数量的优先级位)。
https://stackoverflow.com/questions/50243996
复制相似问题