当使用STM32和FreeRTOS时,`HAL_NVIC_SetPriority()`的有效值是什么?

当使用STM32和FreeRTOS时,`HAL_NVIC_SetPriority()`的有效值是什么?,c,stm32,freertos,C,Stm32,Freertos,在经历了一个相当困难的学习中断优先级的过程后,我仍然有点难以理解在SysTick\u IRQn(即ISR每1ms调用一次FreeRTOS调度程序)上允许调用的HAL\u NVIC\u SetPriority()值 太长,读不下去了 我的一部分认为HAL\u-IRQn,15,0U)(可能的最低优先级)和HAL\u-IRQn,10,0U)(可能的最低优先级)之间的任何事情都是允许的,我的一部分认为HAL\u-IRQn,15,0U)(可能的最低优先级)而且HAL\u NVIC\u SetPriorit

在经历了一个相当困难的学习中断优先级的过程后,我仍然有点难以理解在
SysTick\u IRQn
(即ISR每1ms调用一次FreeRTOS调度程序)上允许调用的
HAL\u NVIC\u SetPriority()

太长,读不下去了 我的一部分认为
HAL\u-IRQn,15,0U)
(可能的最低优先级)和
HAL\u-IRQn,10,0U)
(可能的最低优先级)之间的任何事情都是允许的,我的一部分认为
HAL\u-IRQn,15,0U)
(可能的最低优先级)而且
HAL\u NVIC\u SetPriority(SysTick\u IRQn,5,0U)
(相当高一点)是允许的。这是假设FreeRTOSConfig.h中的
configLIBRARY\u MAX\u SYSCALL\u INTERRUPT\u PRIORITY
设置为5。混淆之处在于,在FreeRTOS中,数字越高优先级越高,但在STM32中,数字越高优先级越低,而且文档理解起来相当困难


细节: 为了证明我做出了勇敢的努力,也为了帮助你帮我填补空白,以下是我目前的理解。我要写一篇描述我所知道的真实情况的文章,这样看起来就像我在教你一样,即使我在寻找我上述问题的答案,以及你认为合适的更正确认,或附加见解

虽然这可能适用于许多STM32微控制器或系列,但让我们特别从以下方面来讨论它

注:

我的理解是: 如果查看标准的FreeRTOSConfig.h文件(例如:STM32Cube\u FW\u F2\u V1.7.0/Projects/STM322xG\u EVAL/Applications/FreeRTOS/FreeRTOS\u 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) )
因此,您只需要设置4位,但实际上您可以决定多少位是
PreemptPriority
位,多少位是
SubPriority
位,如下所示:

HAL\u NVIC\u SetPriorityGrouping()
from,9.2.4,p124/1371。

:

如果将STM32与STM32驱动程序库一起使用,则通过调用NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4),确保将所有优先级位分配为抢占优先级位;在RTOS启动之前

因此,在代码中首先要做的事情之一(至少在通过
osKernelStart()
vTaskStartScheduler()
启动FreeRTOS调度程序之前)是:

/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
这将所有4个优先级位配置为
PreemptPriority
位,没有一个配置为
SubPriority
位。这意味着对
HAL\u NVIC\u SetPriority(IRQn类型IRQn,uint32\u t PreemptPriority,uint32\u t SubPriority)函数的任何调用现在都将始终使用0作为最右边的参数

然后您应该本质上调用(注意:这是通过
HAL\u InitTick()
调用的):

其中,
15
是SysTick tick优先级。由于我们有所有4位可用,因此优先级范围为0到15,其中15是最低中断优先级,0是最高优先级

那么,为什么我们要将SysTick设置为最低优先级?回答:因为这是FreeRTOS调度程序的一个好做法,SysTick中断调用它。事实上,根据FreeRTOS自己的文档,给它太高的优先级会破坏FreeRTOS。让我们试着弄清楚这一点

我们知道,对于
PreemptPriority
设置,我们的中断选项现在是0到15,但比这还要窄:我们只能将SysTick中断的PreemptPriority设置为10到15(我想--我需要一些帮助)。为什么是10到15?嗯,(尽管这非常混乱)甚至明确指出:

以“FromISR”结尾的FreeRTOS函数是中断安全的,但即使这些函数也不能从逻辑优先级高于configMAX\u SYSCALL\u interrupt\u priority(configMAX\u SYSCALL\u interrupt\u priority在FreeRTOSConfig.h头文件中定义)的中断调用。因此,任何使用RTOS API函数的中断服务例程必须手动将其优先级设置为数值等于或大于configMAX_SYSCALL_interrupt_priority设置的值。这确保中断的逻辑优先级等于或小于configMAX_SYSCALL_interrupt_priority设置

现在,回到本页顶部的FreeRTOSConfig.h。我们知道
\u NVIC\u PRIO\u BITS
是4,我们看到:


configMAX\u SYSCALL\u INTERRUPT\u PRIORITY
(configLIBRARY\u MAX\u SYSCALL\u INTERRUPT\u PRIORITY首先不要混淆FreeRTOS任务优先级和NVIC优先级。它们完全不同

在上面的示例中,如果中断进行FreeRTOS API调用,则可以使用5到15的中断优先级。如果中断不进行FreeRTOS API调用,则可以使用0到15的任何优先级的中断


不要担心移位,因为它都是为您处理的,但原因是使用了优先级寄存器的前4位(注意,一些处理器使用不同数量的优先级位)我想说的是,如果你不理解优先级系统是如何工作的,最好不要在像RTOS这样复杂的环境中触摸它。首先了解它如何在裸露的金属环境中工作,考虑为什么要改变它,当你成为NVIC主调谐器的RTOS时,我建议使用CSTIS函数这是一个问题!这确实帮助我了解了更多关于这个主题的内容:)。到目前为止,这是一条非常具有挑战性的道路..!谢谢你的回答。好的,
configLIBRARY\u MAX\u SYSCALL\u INTERRUPT\u PRIORITY
描述了一个NVIC优先级,对吗?即使它在FreeRTOSConf内
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/*Configure the SysTick IRQ priority */
HAL_NVIC_SetPriority(SysTick_IRQn, 15 ,0U);