2. MCU 中断系统基础
中断系统是嵌入式实时操作系统的核心硬件机制,它允许 MCU 在响应外部或内部事件时,暂停当前正在执行的主程序,转而执行一个特定的处理程序,处理完成后再返回主程序断点处继续执行。理解中断概念、中断向量表、中断服务函数以及中断嵌套与抢占,是配置定时器中断优先级和优化实时响应的前提。
2.1 中断概念与触发机制
中断(Interrupt)是一种硬件或软件驱动的异步事件处理机制。当某个事件发生时(例如定时器计数溢出、GPIO 引脚电平变化、CAN 总线接收到报文),MCU 的硬件逻辑会自动保存当前 CPU 状态(PC、PSW 等寄存器),并跳转到与该事件对应的中断服务函数入口地址执行。
- 异步性:中断的发生与主程序执行流无关,可在任意时刻触发。
- 硬件自动响应:CPU 在每条指令执行结束后检查中断标志,无需软件轮询。
- 可屏蔽性:大部分中断可通过 CPU 的中断使能位(如 ARM Cortex-M 的 PRIMASK)或外设的中断使能寄存器进行全局或局部屏蔽。
中断源通常分为两类:
| 类型 | 触发方式 | 典型示例 |
|---|---|---|
| 外部中断 | 由 MCU 外部引脚电平变化触发 | 按键输入、传感器信号、外部故障信号 |
| 内部中断 | 由 MCU 内部外设或软件触发 | 定时器溢出、ADC 转换完成、DMA 传输完成、软件中断(SWI) |
2.2 中断向量表
中断向量表(Interrupt Vector Table, IVT)是 MCU 内存中一张固定的地址映射表,表中每个条目存储着对应中断服务函数的入口地址。当 MCU 响应某个中断时,硬件会自动根据中断号从向量表中取出地址并跳转执行。
在 ARM Cortex-M 系列(如 Infineon TC3xx、NXP S32K、ST SPC5)中,向量表通常位于 Flash 或 RAM 的起始地址(如 0x00000000),且支持重定位(通过 VTOR 寄存器)。
典型中断向量表结构(以 32 位 MCU 为例):
// 中断向量表示例(伪代码)
typedef void (*ISR_Func)(void);
const ISR_Func __attribute__((section(".isr_vector"))) VectorTable[] = {
&Reset_Handler, // 0x0000: 复位向量
&NMI_Handler, // 0x0004: 不可屏蔽中断
&HardFault_Handler, // 0x0008: 硬件错误
&MemManage_Handler, // 0x000C: 内存管理错误
&BusFault_Handler, // 0x0010: 总线错误
&UsageFault_Handler, // 0x0014: 使用错误
// ... 系统异常 ...
&TIM0_IRQHandler, // 0x0040: 定时器0中断
&TIM1_IRQHandler, // 0x0044: 定时器1中断
&CAN0_IRQHandler, // 0x0048: CAN0 中断
// ... 外设中断 ...
};
2.3 中断服务函数 (ISR)
中断服务函数(Interrupt Service Routine, ISR)是中断响应时 CPU 执行的特定代码段。ISR 必须短小精悍,避免阻塞其他中断或影响实时性。
ISR 编写规范:
- 快速执行:ISR 内不应包含延时、轮询等待或复杂计算,仅做必要的数据保存、标志置位和寄存器清除。
- 避免调用不可重入函数:如
printf()、malloc()等,可能导致死锁或堆栈损坏。 - 正确清除中断标志:在 ISR 返回前必须清除外设的中断挂起位,否则会重复触发中断。
- 使用
__attribute__((interrupt))或编译器专用关键字:确保编译器生成正确的入栈/出栈指令。
// 定时器中断服务函数示例 (ARM Cortex-M)
void TIM0_IRQHandler(void) __attribute__((interrupt));
void TIM0_IRQHandler(void)
{
// 1. 清除定时器中断标志
TIM0->SR &= ~TIM_SR_UIF;
// 2. 读取或处理数据(极简操作)
g_uiTickCount++;
// 3. 触发任务调度(RTOS 中)
// OS_TaskResume(Task_Control);
}
HAL_Delay() 或 while() 等待硬件标志,会导致中断响应时间不可控,严重时造成系统看门狗复位。
2.4 中断嵌套与抢占
中断嵌套(Interrupt Nesting)是指一个中断服务函数正在执行时,另一个更高优先级的中断发生,CPU 暂停当前 ISR 转而执行更高优先级的 ISR,处理完后再返回被暂停的 ISR 继续执行。抢占(Preemption)是中断嵌套的核心机制。
在车载 MCU 中,中断优先级通常由硬件寄存器(如 ARM Cortex-M 的 NVIC IPR 寄存器)配置,数值越小优先级越高。中断嵌套规则如下:
| 场景 | 当前 ISR 优先级 | 新中断优先级 | 行为 |
|---|---|---|---|
| 无嵌套 | 低(数值大) | 更低(数值更大) | 新中断等待当前 ISR 完成 |
| 抢占 | 低(数值大) | 高(数值小) | 立即暂停当前 ISR,执行高优先级 ISR |
| 同优先级 | 相同 | 相同 | 取决于硬件实现,通常不嵌套,等待当前 ISR 完成 |
2.5 中断优先级配置原则
在车载 MCU 实时系统中,中断优先级配置直接影响任务响应时间和系统稳定性。以下是核心配置原则:
- 时间关键型中断配置最高优先级:如 1ms 定时器中断、发动机曲轴位置传感器中断,应分配最高优先级(数值最小)。
- 数据流中断配置中等优先级:如 CAN 接收中断、SPI DMA 完成中断,确保数据不丢失但允许被时间关键中断抢占。
- 非关键中断配置最低优先级:如调试 UART 中断、按键扫描中断,避免影响实时控制环路。
- 避免优先级反转:当低优先级中断持有共享资源时,高优先级中断可能被阻塞,需通过中断优先级分组或资源锁机制解决。