FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(1)

NVIC 的全称是 Nested vectored interrupt controller,即嵌套向量中断控制器。对于 M3 内核的 MCU,每个中断的优先级都是用寄存器中的 8 位来设置的。 8 位理论上设置 2^8 = 256 级中断,但是实际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如 ST的 STM32F1xx 只使用了这个 8 位中的高四位[7:4],低四位都为零,这样 2^4=16,只能表示 16级中断嵌套。

优先级分组,抢占优先级和子优先级

STM32F1xx 是只使用了这个 8 位寄存器的高四位[7:4]。

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(2)

就是这

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(3)

STM32 支持 5 种优先级分组,系统上电复位后,默认使用的是优先级分组0,也就是没有抢占式优先级,只有子优先级,

  • 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断服务程序执行过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以抢占低抢占式优先级的中断的执行。
  • 在抢占式优先级相同的情况下,有几个子优先级不同的中断同时到来,那么高子优先级的中断优先被响应。
  • 在抢占式优先级相同的情况下,如果有低子优先级中断正在执行,高子优先级的中断要等待已被响应的低子优先级中断执行结束后才能得到响应,即子优先级不支持中断嵌套。
  • Reset、 NMI、 Hard Fault 优先级为负数,高于普通中断优先级,且优先级不可配置。
  • 系统中断(比如:PendSV,SVC,SysTick)不一定比外部中断(比如 SPI,USART)要高,因为它们是在同一个 NVIC 下面设置的。

我们在上一篇笔记《FreeRTOS|FreeRTOS中断测试》中将 NVIC 优先级分组设置为 4,即:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);设置 NVIC 的优先级分组为 4 表示支持 0-15 级抢占优先级不支持子优先级。

在 NVIC 分组为 4 的情况下,抢占优先级可配置范围是 0-15,那么数值越小,抢占优先级的级别越高,即 0 代表最高优先级,15 代表最低优先级。

FreeRTOSConfig.h 中与中断有关的配置选项 :
  1. Cortex-M内核使用8bit来配置优先级,但是STM32只使用了高4bit,数值越小,优先级越高。在往寄存器里面写数值配置的时候,是按照8bit来写的,所以需要经过转换,公式为: ((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF),其中的priority就是我们配置的真正的优先级。

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(4)

源码在这:

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(5)

2.SysTick中断优先级配置

  • #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15

configKERNEL_INTERRUPT_PRIORITY,此宏定义是用来配置 FreeRTOS 用到的 SysTick 中断和 PendSV 中断的优先级。在 NVIC 分组设置为4 的情况下,此宏定义的范围就是 0-15,即专门配置抢占优先级。这里配置为了 15,即 SysTick和 PendSV 都是配置为了最低优先级,实际项目中也建议大家配置最低优先级即可。

  • #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

宏定义 configLIBRARY_LOWEST_INTERRUPT_PRIORITY的数值经过 4bit偏移后得到一个 8bit的优先级数值,即宏定义 configKERNEL_INTERRUPT_PRIORITY 的数值。这个 8bit 的数值才可以实际赋值给相应中断的优先级寄存器。这里的宏定义数值是供 PendSV 和 SysTick 中断进行优先级配置的。 比如:我们这里配置宏定义 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 是 0x0f,经过 4bit 偏移后就是 0xf0,即 SysTick 和 PendSV 的中断优先级就是 240。

3.可屏蔽的中断优先级配置

  • #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY: 用于配置STM32的特殊寄存器basepri寄存器的值,用于屏蔽中断,当大于basepri值的优先级的中断将被全部屏蔽。basepri只有4bit有效,默认只为0,即全部中断都没有被屏蔽。configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY配置为:5,意思就是中断优先级大于5的中断都被屏蔽。当把配置好的优先级写到寄存器的时候,是按照8bit来写的,所以真正写的时候需要经过转换,公式为: ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我们配置的真正的优先级。经过这个公式之后得到的是下面的这个宏: configMAX_SYSCALL_INTERRUPT_PRIORITY。在FreeRTOS中,关中断是通过配置basepri寄存器来实现的,关掉的中断由配置的basepri的值决定,小于basepri值的中断FreeRTOS是关不掉的,这样做的好处是可以系统设计者可以人为的控制那些非常重要的中断不能被关闭,在紧要的关头必须被响应。此宏定义比较重要。

  • #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

宏定义 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 的数值经过 4bit 偏移后得到一个 8bit 的优先级数值,即宏定义 configMAX_SYSCALL_INTERRUPT_PRIORITY 的数值。 这个数值是赋值给寄存器 basepri 使用的,8bit 的数值才可以实际赋值给相应中断的优先级寄存器。这里的宏定义数值赋给寄存器 basepri 后就可以实现全局的开关中断操作了。

FreeRTOSConfig.h文件中的关于NVIC的相关配置

FreeRTOS配置选项中关于NVIC相关配置的说明(FreeRTOS配置选项中关于NVIC相关配置的说明)(6)


喜欢我文章的朋友,欢迎关注、分享、点赞、评论。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页