1. 中断基础概念:什么是中断、中断向量表、中断优先级、中断嵌套

各位同学,咱们今天聊聊中断。说实话,中断是嵌入式系统里最基础也最核心的概念之一。我做了十几年驱动开发,可以负责任地告诉你——不懂中断,就别谈嵌入式。

1.1 什么是中断?

先问个问题:你正在厨房炒菜,突然门铃响了,你会怎么做?

正常人都会先关小火,去开门,处理完门铃的事,再回来继续炒菜。对吧?

中断就是这个道理。

CPU 正在执行主程序,突然外设(比如串口收到数据、定时器溢出、GPIO 电平变化)发来一个信号,告诉 CPU:“嘿,我这有事,你先停一下手上的活,来处理我!”

CPU 保存当前现场(就像你记住炒菜的火候),跳去执行中断服务程序(ISR),处理完再回来继续原来的工作。

核心要点:中断是一种硬件机制,让 CPU 能够及时响应外部或内部事件,而不需要轮询等待。

我在项目中遇到过一件事:有个同事做数据采集,用轮询方式读传感器。CPU 占用率飙到 90%,系统几乎干不了别的。后来改成中断触发,CPU 占用率直接降到 5%。你想想看,这差距有多大。

1.2 中断向量表

好,现在 CPU 知道有中断来了。但它怎么知道该跳到哪里去执行代码?

这就得靠中断向量表了。

中断向量表,说白了就是一张“地址映射表”。每个中断源都有一个固定的编号(中断号),CPU 根据这个编号去查表,找到对应的 ISR 入口地址,然后跳过去执行。

这张表通常放在内存的固定位置。比如 ARM Cortex-M 系列,向量表默认从地址 0x00000000 开始。

中断号 中断源 向量地址 ISR 入口
0 复位 0x00000000 Reset_Handler
1 NMI 0x00000004 NMI_Handler
2 硬错误 0x00000008 HardFault_Handler
16 SysTick 0x00000040 SysTick_Handler
32 UART1 0x00000080 UART1_IRQHandler

嗯,这里要注意:不同架构的向量表布局不一样。x86 用 IDT(中断描述符表),ARM 用 VTOR(向量表偏移寄存器)。但核心思想是一样的——查表跳转。

个人经验:我建议你在项目初期就把向量表布局画清楚。特别是多核系统,每个核都有自己的向量表,搞混了就是灾难。

1.3 中断优先级

问题来了:如果同时来了两个中断,CPU 先处理谁?

这就涉及到中断优先级了。

每个中断源都有一个优先级数值。数值越小,优先级越高(也有反过来的,看具体芯片)。CPU 会优先响应优先级最高的中断。

我曾经在一个工业控制项目里踩过坑:两个外设共用一根中断线,优先级没配好,结果高优先级的中断一直被低优先级的堵着,系统直接卡死。从那以后,我每次配优先级都格外小心。

常见的优先级模型有两种:

  • 固定优先级:硬件写死的,不能改。比如 x86 的 IRQ0 优先级最高。
  • 可编程优先级:软件可以配置。ARM Cortex-M 的 NVIC 就支持,每个中断可以设 0~255 的优先级。

避坑指南:我曾经见过有人把所有中断都设成同一优先级。结果呢?中断互相抢占,系统行为完全不可预测。记住:关键中断(比如系统时钟、看门狗)一定要设高优先级。

1.4 中断嵌套

中断嵌套,就是“中断里套中断”。

CPU 正在处理一个低优先级的中断,这时来了一个高优先级的中断。CPU 会暂停当前 ISR,去处理高优先级的,处理完再回来继续低优先级的。

这就像你正在接一个普通电话,突然来了老板的电话——你会说“稍等”,先接老板的,挂掉再继续之前的电话。

中断嵌套的规则:

  • 高优先级可以打断低优先级
  • 同级中断不能互相打断(通常按硬件顺序处理)
  • 低优先级不能打断高优先级

下面这张图展示了中断嵌套的流程:

中断嵌套执行流程 主程序执行 低优先级 ISR 高优先级 ISR 时间 执行顺序说明: 1. 主程序正在执行 2. 低优先级中断触发 → CPU 保存现场,跳转到低优先级 ISR 3. 低优先级 ISR 执行中,高优先级中断触发 4. CPU 再次保存现场,跳转到高优先级 ISR 5. 高优先级 ISR 执行完毕 → 返回低优先级 ISR 6. 低优先级 ISR 执行完毕 → 返回主程序 关键:每次中断切换都要保存和恢复现场,这是开销所在。

中断嵌套虽然灵活,但也要小心。嵌套层数太多,栈空间可能不够。我见过一个案例,中断嵌套了 5 层,栈直接溢出,系统跑飞了。

建议:中断嵌套尽量控制在 2~3 层以内。如果业务逻辑复杂,可以考虑用中断+任务队列的方式,把耗时操作放到主循环或 RTOS 任务里处理。

1.5 中断响应流程总结

最后,咱们把整个中断响应流程串起来:

  1. 中断请求:外设或内部模块发出中断信号
  2. 中断判优:CPU 检查当前中断优先级,决定是否响应
  3. 保存现场:CPU 自动压栈(PC、PSR、寄存器等)
  4. 查向量表:根据中断号找到 ISR 入口地址
  5. 执行 ISR:运行中断服务程序
  6. 恢复现场:出栈,回到被中断的地方继续执行

这 6 步,每一步都有坑。后面几章我会结合具体硬件和代码,一个一个给你拆解。

一句话总结:中断是 CPU 的“紧急通道”,向量表是“地图”,优先级是“通行规则”,嵌套是“通道里的通道”。搞懂这四样,中断这块你就入门了。