FreeRTOS中断分析

本文是《ALIENTEK STM32F429 FreeRTOS 开发教程》第四章学习笔记
第一章笔记–FreeRTOS简介与源码下载
第二章笔记–FreeRTOS在STM32F4上移植
第三章笔记-FreeRTOS系统配置

一、Cortex-M中断管理

1.1 中断概述

中断由硬件产生,当中断产生后CPU就会中断当前流程转去处理中断服务,Cortex-M内核的MCU提供一个用于管理中断的嵌套向量中断控制器(NVIC)

NVIC 与 CM3 内核共同完成对中断的响应。NVIC的寄存器以存储器映射的方式来访问,除了包含控制寄存器和中断处理的控制逻辑之外,NVIC 还包含了 MPU
的控制寄存器、 SysTick 定时器以及调试控制。

Cortex-M3和M4的NVIC最多支持249个外部中断输入(IRQs)、1个不可屏蔽中断(NMI)、1个Systick(滴答定时器)定时器中断和多个系统异常

1.1.1中断类型

在 NVIC 的中断控制及状态寄存器中,有一个 VECTACTIVE 位段;另外,还有一个特殊功能寄存器IPSR。在它们二者的里面,都记录了当前正服务异常的编号,编号为 1-15 的对应系统异常,
这里写图片描述
编号大于等于 16 的则全是外部中断
这里写图片描述

1.2 中断管理

Cortex-M处理器有多个用于管理中断和异常的可编程寄存器,这些寄存器都在NVIC和系统控制块(SCB)中,CMSIS将这些寄存器定义为结构体。

NVIC访问地址是0xE000_E000,打开core_cm4.h文件:
这里写图片描述
可以看到NVIC基址是从 0xE000_E000 + 0x0100UL = 0xE000_E100开始的

宏定义的NVIC中有一结构体 NVIC_Type

1.2.1NVIC_Type

typedef struct
{
  __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
        uint32_t RESERVED0[24U];
  __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
        uint32_t RSERVED1[24U];
  __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
        uint32_t RESERVED2[24U];
  __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
        uint32_t RESERVED3[24U];
  __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
        uint32_t RESERVED4[56U];
  __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
        uint32_t RESERVED5[644U];
  __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
}  NVIC_Type;
1.2.1.1 中断使能除能寄存器

CM3和CM4 中可以有240对使能位/除能位,每个中断拥有一对。这 240 个对子分布在8对32位寄存器中(最后一对没有用完)。欲使能一个中断,需要写 1 到对应 SETENA 的位中;欲除能一个中断,需要写 1 到对应的 CLRENA 位中;如果往它们中写 0,

### FreeRTOS 中断处理机制 在FreeRTOS环境中,中断处理主要依赖于中断服务例程(ISR)。当中断事件触发时,对应的ISR会被立即执行以响应这一事件[^1]。 #### 定义中断服务例程 为了定义一个有效的ISR,在FreeRTOS环境下应当遵循特定的规定。例如,如果需要在一个ISR内部调用任何FreeRTOS API,则该ISR的优先级必须低于`configMAX_SYSCALL_INTERRUPT_PRIORITY`参数设定的最大允许值[^2]。这意味着较高优先级的中断不应尝试直接操作OS级别的资源或功能。 对于那些确实需要同FreeRTOS交互的ISRs来说——比如发送消息给队列、改变信号量状态等动作——应该采用专门设计用来支持从中断上下文中安全调用的形式,即带有`FromISR`后缀的方法版本[^4]。 #### 使用SYSTICK中断作为调度基础 特别值得注意的是SYSTICK中断的作用。此类型的中断通常由系统定时器周期性地激发,并且构成了FreeRTOS任务调度的基础。每当一次SYSTICK到来之时,FreeRTOS就会评估当前系统的状况并据此做出是否切换到另一个更高优先级等待中的任务的选择[^3]。 #### 处理长时间运行的操作 考虑到效率问题,实际开发过程中应尽量缩短ISR内的逻辑流程长度。这是因为较长的ISR可能会阻碍其他较低级别中断得到及时响应的机会,进而影响整个应用程序的表现质量[^5]。针对这种情况的一种常见解决方案是在ISR中仅完成必要的初步数据采集或是标志位置位等工作,随后借助事件组(Event Groups)、队列(Queues)或者其他形式的消息传递机制通知关联的任务继续后续更复杂的计算过程。 ```c void vAnExampleInterruptHandler(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; // 假设这里是从某处读取到了新数据... // 将这些数据放入队列供后台任务进一步分析 xQueueSendFromISR(xDataReceivedQueue, &receivedValue, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } ``` 上述代码片段展示了如何利用`xQueueSendFromISR()`函数向队列发送信息的同时检查是否有更高优先级的任务因此变得可运行。如果有,则通过`portYIELD_FROM_ISR()`指示内核可能需要重新安排CPU使用权。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值