4. 中断系统基础
在 RTOS 环境中,中断是系统对外部事件做出快速响应的核心机制。理解中断系统的组成,是分析实时性能、定位抖动来源、优化响应时间的前提。本节从硬件与内核协同的角度,梳理中断源、中断向量表、中断优先级、中断嵌套,以及中断延迟与响应时间的构成。
一、中断源:事件的起点
中断源是能够触发中断请求的硬件或软件事件。按来源可分为外部中断与内部中断:外部中断来自 GPIO 电平变化、定时器溢出、串口收发、ADC 转换完成、DMA 传输结束等外设;内部中断则来自软件触发(如 SVC、PendSV)、异常(除零、总线错误)以及内核自身的系统节拍。
在 RTOS 中,中断源通常被抽象为“中断服务程序 + 事件通知”的组合。ISR 只做最紧急的硬件处理,然后通过信号量、消息队列或任务通知唤醒对应任务,把耗时逻辑交给任务上下文完成。这种“上半部/下半部”划分,是控制中断延迟的关键设计。
二、中断向量表:从异常号到入口地址
中断向量表是一张存放中断入口地址的表格,位于存储器固定位置(如 Cortex-M 的 0x0000_0000 或重映射后的地址)。每个中断源对应一个向量号,CPU 收到中断后,用向量号索引表格,跳转到对应 ISR。向量表通常包含初始栈指针、复位、NMI、HardFault、SysTick、以及各外设中断入口。
在 RTOS 移植中,向量表常被重定位到 RAM 或 Flash 的特定区域,以便动态注册 ISR。若向量表配置错误,会出现“中断触发后跑飞”或“进入 HardFault”的典型故障。
三、中断优先级与嵌套
中断优先级决定多个中断同时到达时谁先被响应,以及高优先级中断能否打断正在执行的低优先级 ISR。Cortex-M 使用 NVIC 管理优先级,数值越小优先级越高。优先级分为抢占优先级和子优先级:抢占优先级决定能否嵌套,子优先级决定同抢占级下的排队顺序。
中断嵌套允许高优先级中断打断低优先级 ISR,从而缩短高实时事件的响应时间。但嵌套层数过深会增大栈消耗,并可能引发优先级反转或栈溢出。RTOS 中通常将内核调度相关的 PendSV、SysTick 设为最低优先级,确保它们不会打断外设 ISR。
四、中断延迟与响应时间的组成
中断延迟通常指“事件发生”到“ISR 第一条指令执行”之间的时间;响应时间则更宽泛,包含从中断请求到任务真正处理完事件的全过程。其组成可拆解为:
- 硬件识别延迟:中断信号同步、优先级仲裁、取向量所需时钟周期。
- 压栈与上下文保存:Cortex-M 自动压栈 R0-R3、R12、LR、PC、xPSR,通常 12 个周期左右。
- 内核关中断时间:RTOS 临界区、调度器锁、驱动中的关中断操作会直接阻塞响应。
- ISR 执行时间:与代码路径、分支预测、Flash 等待周期、Cache 命中率相关。
- 任务唤醒与调度延迟:ISR 发送信号量后,任务何时被调度取决于当前就绪任务优先级与调度器状态。
| 组成环节 | 典型量级 | 主要影响因素 | 优化方向 |
|---|---|---|---|
| 硬件识别与仲裁 | 几个到十几个周期 | NVIC 优先级、总线频率 | 提高主频、合理分组 |
| 自动压栈 | 约 12 周期 | 内核架构、FPU 是否使能 | 避免不必要的 FPU 上下文 |
| 关中断临界区 | 数微秒到数十微秒 | RTOS API、驱动实现 | 缩短临界区、使用无锁队列 |
| ISR 执行 | 数微秒到数百微秒 | 代码复杂度、Cache、Flash 等待 | 上半部精简、下半部下沉 |
| 任务调度 | 数微秒到数十微秒 | 就绪表、优先级、调度器 | 提高任务优先级、减少阻塞 |
五、案例:串口接收中断的响应链路
以 STM32 + FreeRTOS 的串口接收为例,典型链路如下:
USART1_IRQHandler:
1. 读取 SR 与 DR,清除中断标志
2. 将数据写入环形缓冲区
3. 若缓冲区达到阈值,调用 xSemaphoreGiveFromISR()
4. 触发 PendSV,请求任务切换
任务侧:
xSemaphoreTake( rxSem, portMAX_DELAY );
从环形缓冲区取数据并解析协议
若把协议解析直接放在 ISR 中,ISR 执行时间会从几微秒膨胀到几百微秒,导致其他中断被长时间阻塞。正确做法是 ISR 只搬运数据并通知任务,解析交给任务完成。
六、复盘:如何量化与优化
要优化中断响应,先要测量。可用 GPIO 翻转配合示波器,在 ISR 入口和出口各翻转一次,测量 ISR 执行时间;在事件发生处翻转,测量中断延迟。若延迟超标,按以下顺序排查:
- 检查是否有长临界区或关中断操作,定位到具体函数。
- 检查中断优先级分组是否合理,是否存在高优先级中断被低优先级长时间阻塞。
- 检查 ISR 是否过长,是否调用了非 ISR 安全的 RTOS API。
- 检查任务侧优先级与阻塞时间,确认唤醒后能及时调度。
- 检查 Flash 等待周期与 Cache 配置,必要时将 ISR 放入 RAM 执行。
中断系统的本质是“硬件事件 → 向量跳转 → 优先级仲裁 → ISR 执行 → 任务唤醒”的链路。理解每一段的耗时与约束,才能在 RTOS 中把实时性能从“感觉还行”变成“可测量、可优化、可保证”。