2. 中断源与中断类型:外部中断、内部中断、软件中断、异常与中断的区别

好,咱们今天聊聊中断的“出身”问题。

中断从哪来?说白了,就是谁触发了这个中断。我个人习惯把中断源分成三大类:外部中断内部中断软件中断。另外还有一个容易混淆的概念——异常。很多新手工程师搞不清中断和异常的区别,我当年也踩过这个坑。

2.1 外部中断:来自芯片“墙外”的信号

外部中断,顾名思义,信号来自SoC芯片的外部。比如一个按键按下、一个传感器数据准备好、或者一根网线插上了。

我在项目中遇到过最典型的场景:一个IoT芯片需要响应外部传感器的数据就绪信号。传感器通过一根GPIO线告诉CPU:“我有数据了,快来取!”这就是外部中断。

外部中断的特点:

  • 由芯片外部引脚的电平变化或边沿触发
  • 通常是异步的——你不知道它什么时候来
  • 需要配置GPIO的中断触发模式(上升沿、下降沿、高电平、低电平)

嗯,这里要注意:外部中断的响应速度受限于引脚上的信号传播延迟和内部去抖电路。我曾经因为没做去抖处理,导致一个按键中断被误触发了十几次……

2.2 内部中断:芯片“内务”自己报信

内部中断是SoC内部模块产生的中断。比如定时器溢出、DMA传输完成、UART收到一个字节。

你想想看,CPU正在跑主程序,突然定时器说:“时间到了!”CPU就得停下来去处理定时任务。这就是内部中断的典型场景。

内部中断源 典型触发条件 我见过的坑
定时器 计数值到达比较值 中断服务函数执行太久,导致下一次中断丢失
DMA 传输完成或传输错误 忘记清中断标志位,导致一直进中断
UART 接收缓冲区非空 波特率不匹配导致频繁触发错误中断
I2C/SPI 传输完成或仲裁丢失 从设备没应答导致总线挂死

我的经验:内部中断的优先级设计很关键。比如定时器中断通常要设得比UART高,因为时间精度要求高。但DMA中断可以设低一些,毕竟数据晚一点处理也没关系。

2.3 软件中断:CPU自己“主动找事”

软件中断是CPU执行一条特殊指令主动触发的中断。比如ARM架构的SVC(Supervisor Call)指令,或者x86的INT指令。

说白了,就是程序自己喊:“我要进内核态!”操作系统里系统调用就是靠软件中断实现的。

// ARM Cortex-M 示例:触发软件中断
// 通过写 NVIC 的软件触发中断寄存器
NVIC->STIR = 5;  // 触发中断号5的中断

// 或者使用汇编指令
__ASM volatile ("SVC #0");  // 触发 Supervisor Call

软件中断的好处是:它是同步的。你执行这条指令,中断立刻发生,不会像外部中断那样“随机”。这在实现任务切换、系统调用时特别有用。

警告:软件中断虽然方便,但别滥用。我曾经见过一个项目,工程师用软件中断来实现函数调用……结果中断嵌套层数太多,栈直接爆了。软件中断是用来进入特权模式的,不是用来替代函数调用的。

2.4 异常与中断:到底有啥区别?

这个问题我面试时经常问。很多人答不上来,或者答得模棱两可。

其实很简单:中断是“意料之外,情理之中”异常是“出事了,必须处理”

  • 中断:外部设备或内部模块主动通知CPU。CPU可以等当前指令执行完再响应。比如网卡说“有数据包到了”,CPU可以等当前指令跑完再去收包。
  • 异常:CPU执行指令时自己发现不对劲。比如除零、访问非法地址、取指失败。这些必须立即处理,不能等。

我记得有一次调试一个嵌入式系统,程序跑着跑着就死机了。查了半天,发现是除零异常没处理,CPU直接进入了异常处理循环。嗯,从那以后我写代码都会检查除数是否为零。

特性 中断 异常
触发方式 外部事件或内部模块 指令执行错误或系统错误
同步/异步 异步(不知道何时发生) 同步(执行到某条指令时发生)
响应时机 当前指令执行完后 立即响应(通常)
可屏蔽性 可屏蔽(关全局中断) 通常不可屏蔽
典型例子 定时器、UART、GPIO 除零、缺页、非法指令

一句话总结:中断是“有人找你”,异常是“你出事了”。处理方式也不同——中断处理完可以继续执行,异常处理完可能得重启或终止当前任务。

2.5 实际设计中的选择建议

做SoC架构设计时,怎么分配中断源和中断类型?我个人的经验是:

  1. 外部中断:留给真正需要实时响应的外部事件。比如紧急停止按钮、电源管理事件。
  2. 内部中断:留给外设模块。每个外设分配一个中断号,不要共享。
  3. 软件中断:留给操作系统或底层驱动。用于系统调用、任务切换。
  4. 异常:必须全部注册处理函数。哪怕只是打印一条日志,也比死机强。

避坑指南:我曾经设计过一个SoC,把两个外设的中断号分配成了同一个。结果调试时发现,按下一个按键,UART也收到了中断……查了三天才发现是中断号冲突。所以,中断号分配一定要仔细核对数据手册。

好了,这一节的内容就这些。下一节咱们聊聊中断控制器——那个负责“排队叫号”的硬件模块。