3. 中断概念:中断向量、中断优先级、中断嵌套、中断服务程序(ISR)基础
在供应链控制塔的异常信号采集场景中,中断机制是嵌入式系统响应外部事件(如传感器触发、通信报文到达、硬件故障)的核心手段。理解中断的底层概念,是编写可靠、低延迟驱动的基础。
3.1 中断向量表:异常信号的“索引目录”
中断向量表(Interrupt Vector Table, IVT)是处理器用于查找中断服务程序入口地址的固定数据结构。每个中断源(如定时器溢出、GPIO 边沿触发)对应一个唯一的向量号,向量表中存储该中断对应的 ISR 起始地址。
| 概念 | 说明 | 供应链异常采集示例 |
|---|---|---|
| 向量号 | 中断源的唯一数字标识(如 IRQ 0~255) | 传送带光电传感器对应向量号 16 |
| 向量地址 | 向量号映射到内存中的具体地址(通常为 4 字节对齐) | 0x00000040(向量号 16 × 4) |
| ISR 入口 | 向量地址中存放的函数指针,指向实际处理代码 | isr_belt_sensor 函数地址 |
| 默认处理 | 未使用的中断向量指向空处理或错误处理函数 | 打印“未注册中断”日志 |
驱动开发要点: 在系统启动阶段,驱动必须将 ISR 地址写入对应的向量表条目。ARM Cortex-M 系列使用向量表偏移寄存器(VTOR)支持运行时重定位,适用于多固件分区场景。
3.2 中断优先级:异常信号的“响应顺序”
当多个中断同时发生时,优先级决定了 CPU 先处理哪一个。优先级通常分为抢占优先级和子优先级(或响应优先级),具体实现依赖芯片架构。
- 抢占优先级(Preemption Priority): 决定是否打断正在执行的低优先级中断。数值越小,优先级越高。
- 子优先级(Subpriority): 当抢占优先级相同时,决定多个挂起中断的处理顺序,但不支持嵌套打断。
- 硬件优先级: 部分处理器(如 Cortex-M)内置固定硬件优先级,用于解决软件优先级相同时的仲裁。
供应链场景建议: 将紧急异常(如温度超限、急停按钮)配置为最高抢占优先级;将数据采集类中断(如条码扫描完成)配置为较低优先级,避免阻塞关键安全响应。
3.3 中断嵌套:高优先级信号“插队”处理
中断嵌套是指一个中断服务程序正在执行时,被另一个更高优先级的中断打断,CPU 暂停当前 ISR,转而执行高优先级 ISR,完成后返回原 ISR 继续执行。嵌套深度受限于堆栈空间和中断控制器配置。
常见陷阱: 嵌套中断可能导致堆栈溢出或优先级反转。在驱动中应尽量缩短 ISR 执行时间,避免在 ISR 内调用可能阻塞的函数(如
printf、malloc)。
3.4 中断服务程序(ISR):异常信号的“处理函数”
中断服务程序是响应中断时自动执行的函数。ISR 必须遵循严格的编写规范,以保证系统稳定性和实时性。
ISR 编写核心规则
- 快速执行: ISR 应只做最必要的处理(如读取数据、置位标志),耗时操作移至任务级。
- 可重入性: 避免使用全局变量而不加保护;若必须使用,需采用原子操作或关中断保护。
- 避免阻塞: 禁止在 ISR 内调用
delay()、wait()或等待信号量。 - 保存上下文: 编译器会自动保存/恢复寄存器,但若使用汇编编写,需手动处理。
- 清除中断标志: 退出 ISR 前必须清除中断挂起位,否则会无限触发。
典型 ISR 代码结构(C 语言)
// 中断向量表声明(以 ARM Cortex-M 为例)
__attribute__((interrupt)) void isr_uart_rx(void)
{
// 1. 读取硬件状态寄存器,确认中断源
uint32_t status = UART->SR;
// 2. 读取接收数据寄存器
uint8_t data = UART->DR;
// 3. 将数据放入环形缓冲区(非阻塞操作)
if (ring_buffer_write(&rx_buf, data) == 0) {
// 缓冲区满,置位溢出标志
error_flags |= ERR_UART_OVERFLOW;
}
// 4. 清除中断标志位(写 1 清除)
UART->ICR = (1 << 0);
// 5. 触发任务级处理(如通过信号量通知 RTOS 任务)
// osSemaphoreRelease(rx_sem);
}
供应链异常采集适配: 在控制塔网关驱动中,ISR 通常只负责将传感器数据压入 DMA 缓冲区或轻量级队列,后续由任务线程完成协议解析、异常判定和上报。这种设计将实时性要求高的中断处理与业务逻辑解耦。
3.5 中断优先级与嵌套配置示例
以下表格展示了在典型 ARM Cortex-M4 平台上,为供应链控制塔设备配置中断优先级的推荐方案:
| 中断源 | 抢占优先级 | 子优先级 | 说明 |
|---|---|---|---|
| 急停按钮(GPIO) | 0(最高) | 0 | 必须立即响应,不可被任何中断打断 |
| 温度超限(ADC 比较器) | 1 | 0 | 高优先级,可打断普通数据采集 |
| UART 接收(条码/ RFID) | 2 | 0 | 中等优先级,数据量小但需及时读取 |
| 定时器(周期性采集) | 2 | 1 | 与 UART 同级,子优先级较低 |
| DMA 传输完成 | 3 | 0 | 低优先级,可被其他中断打断 |
配置方法: 使用芯片厂商提供的 HAL 或 LL 库函数设置优先级分组和具体优先级数值。例如,STM32 使用
HAL_NVIC_SetPriority() 和 HAL_NVIC_EnableIRQ()。
3.6 中断延迟与抖动:驱动性能的关键指标
在供应链实时控制场景中,中断延迟(Interrupt Latency)和抖动(Jitter)直接影响异常信号的响应时效。
- 中断延迟: 从中断信号触发到 ISR 第一条指令执行的时间。包括硬件识别、优先级仲裁、上下文保存等开销。
- 抖动: 中断延迟的最大变化量。高抖动可能导致数据采集时间戳不准确或控制指令超时。
降低延迟和抖动的常用手段:
- 将关键中断优先级设为最高,避免被其他中断阻塞。
- 避免在 ISR 中执行浮点运算或复杂循环。
- 使用零延迟中断(Zero Latency Interrupt)特性(部分 Cortex-M7 支持)。
- 将中断处理拆分为 ISR(极短)和任务级处理(较长)。
3.7 本章小结
- 中断向量表是中断驱动的“入口地图”,驱动需在初始化阶段正确注册 ISR 地址。
- 中断优先级决定异常信号的响应顺序,供应链场景应将安全类中断设为最高优先级。
- 中断嵌套允许高优先级中断打断低优先级 ISR,但需注意堆栈深度和可重入性。
- ISR 编写必须遵循“短、快、不阻塞”原则,核心处理移至任务上下文。
- 中断延迟与抖动是驱动实时性的关键指标,需通过优先级配置和代码优化加以控制。