目录
2.2 configLIBRARY_LOWEST_INTERRUPT_PRIORITY
2.3 configKERNEL_INTERRUPT_PRIORITY
2.4 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
2.5 configMAX_SYSCALL_INTERRUPT_PRIORITY
FreeRTOS 的中断配置需要根据所使用的 MCU 来具体配置。这需要结合 MCU 架构中有关中断的知识,本节结合 Cortex-M 的 NVIC 来讲解 STM32 平台下的 FreeRTOS 中断配置;
1. Cortex-M 中断
1.1 中断简介
中断是微控制器一个很常见的特性,中断由硬件产生,当中断产生以后 CPU 就会中断当前的流程转而去处理中断服务,Cortex-M 内核的 MCU 提供了一个用于中断管理的嵌套向量中断控制器(NVIC)。
Cortex-M3 和 M4 的 NVIC 最多支持 240 个 IRQ(中断请求)、1 个不可屏蔽中断(NMI)、1 个Systick(滴答定时器)定时器中断和多个系统异常。
1.2 中断管理简介
Cortex-M 处理器有多个用于管理中断和异常的可编程寄存器,这些寄存器大多数都在 NVIC 和系统控制块(SCB)中,CMSIS 将这些寄存器定义为结构体。以 STM32F407 为例,打开core_cm4.h,有两个结构体,NVIC_Type 和 SCB_Type,如下:
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
} NVIC_Type;
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
__IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
__IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
__IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
__IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
__I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
__I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
uint32_t RESERVED0[5];
__IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
} SCB_Type;
NVIC 和 SCB 都位于系统控制空间(SCB)内,SCS 的地址从 0XE000E000 开始,SCB 和 NVIC 的地址也在 core_cm4.h 中有定义,如下:
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address
#define SCnSCB ((SCnSCB_Type*) SCS_BASE) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct *//
1.3 优先级分组定义
当多个中断来临的时候处理器应该响应哪一个中断是由中断的优先级来决定的,高优先级的中断(优先级编号小)肯定是首先得到响应,而且高优先级的中断可以抢占低优先级的中断,这个就是中断嵌套。Cortex-M 处理器的有些中断是具有固定的优先级的,比如复位、NMI(不可屏蔽中断)、HardFault,这些中断的优先级都是负数,优先级也是最高的。
Cortex-M 处理器有三个固定优先级和 256 个可编程的优先级,最多有 128 个抢占等级,但是实际的优先级数量是由芯片厂商来决定的。在实际设计时,绝大多数的芯片都会精简设计,以致实际上支持的优先级数会更少,如 8级、16级、32级等,比如 STM32 就只有 16 级优先级。在设计芯片的时候会裁掉表达优先级的几个低端有效位,以减少优先级数,所以不管用多少位来表达优先级,都是 MSB 对齐的;

在图 4.1.3.1 中,Bit0~Bit4 没有实现,所以读它们总是返回零,写它们的话也会忽略写入的值。因此,对于 3 个位的情况,可以使用的优先级就是 8 个:0x00(最高优先级)、0x20、0x40、0x60、0x80、0xA0、0xC0 和 0xE0。
注意:这个是芯片厂商来决定的!不是我们能决定的,比如说 STM32 就选择了 4 位作为优先级!
为了使抢占机能变得更可控,Cortex-M 处理器还把 256 个优先级按位分为高低两段:抢占优先级(分组优先级)和亚优先级(子优先级),NVIC 中有一个寄存器是 "应用程序中断及复位控制寄存器(AIRCR)";AIRCR 寄存器里面有个位段名为 “优先级组”,

上图中 PRIGROUP 就是优先级分组,他把优先级分为两个位段:MSB 所在的位段(左边的)对应抢占优先级,LSB 所在的位段(右边的)对应亚优先级,也就是子优先级。

STM32 的优先级分组情况,STM32 使用了 4 位,因此最多有 5 组优先级分组设置,这 5 个分组在 msic.h 中有定义:
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits

文章详细介绍了Cortex-M处理器中断的基本概念,包括中断简介、中断管理、优先级分组、优先级设置以及用于中断屏蔽的特殊寄存器。接着,文章深入阐述了FreeRTOS在STM32平台上中断配置的相关宏定义,如configPRIO_BITS、configKERNEL_INTERRUPT_PRIORITY等,并解析了如何设置PendSV和SysTick的中断优先级。最后,文章讨论了FreeRTOS的临界段代码保护,包括任务级和中断级的临界段代码保护函数及其使用方法,并给出了中断测试实验的设计和分析。
最低0.47元/天 解锁文章
8191

被折叠的 条评论
为什么被折叠?



