1、中断基础概念:中断的定义、中断向量、中断优先级、中断嵌套

中断是嵌入式系统与 Linux 内核驱动开发中最核心的异步事件处理机制。在 Subdev 驱动开发中,中断处理的设计直接决定了系统的实时性、可靠性与可维护性。本节从最基础的中断概念出发,建立中断处理的理论框架。

1.1 中断的定义

中断(Interrupt)是一种硬件或软件触发的信号,用于通知处理器发生了需要立即关注的事件。当中断发生时,处理器会暂停当前正在执行的程序,保存现场,跳转到一个预先定义的中断服务程序(ISR,Interrupt Service Routine)去处理该事件,处理完成后再恢复现场,继续执行被中断的程序。

核心特征:中断是一种异步事件,它不依赖于处理器当前的执行流,可以在任何时刻发生。这种机制使得处理器能够对外部或内部事件做出快速响应,而无需通过轮询方式浪费 CPU 周期。
Subdev 驱动视角:在 Subdev 驱动中,中断通常由硬件子设备(如 GPIO 控制器、I2C 从设备、SPI 外设、DMA 控制器等)产生。驱动开发者需要注册对应的中断处理函数,并在其中完成数据读取、状态清除、唤醒等待队列等操作。

中断的典型处理流程可以用以下 SVG 流程图表示:

中断处理基本流程 中断处理基本流程 主程序执行 中断事件发生 保存现场(压栈) 跳转中断向量表 执行中断服务程序 恢复现场(出栈) 继续执行主程序 关键说明 • 中断是异步的 • 保存/恢复现场由硬件自动完成 • ISR 应短小精悍

1.2 中断向量

中断向量(Interrupt Vector)是中断服务程序入口地址的索引表。每个中断源都被分配一个唯一的中断向量号,处理器在响应中断时,根据中断向量号从中断向量表中取出对应的 ISR 入口地址,然后跳转执行。

概念 说明 典型值/范围
中断向量号 每个中断源的唯一数字标识 0~255(x86),0~1023(ARM GIC)
中断向量表 存储所有 ISR 入口地址的数组 存放在内存固定区域(如 0x0000~0x03FF)
中断描述符表(IDT) x86 架构中的中断向量表实现 256 个条目,每个 8 字节
异常向量表 ARM 架构中的中断向量表实现 8 个条目(复位、未定义指令、SWI、预取中止、数据中止、IRQ、FIQ、保留)
Subdev 驱动注意:在 Linux 内核中,中断向量号被抽象为 IRQ 号(Interrupt Request Number)。驱动开发者通过 request_irq() 函数将 IRQ 号与 ISR 绑定。不同硬件平台的中断向量号到 IRQ 号的映射关系由平台代码管理,驱动应使用平台无关的 IRQ 号。

中断向量表的结构可以用以下 SVG 图表示:

中断向量表结构 中断向量表结构 中断向量表(基地址:VECTOR_BASE) 向量 0:复位 向量 1:未定义 向量 2:SWI 向量 3:预取中止 向量 4:数据中止 向量 5:IRQ 向量 6:FIQ 向量 7:保留 向量 8:... 向量 N:... 每个向量条目 = ISR 入口地址(4 字节或 8 字节) 处理器根据中断向量号 × 向量条目大小 + 基地址 计算 ISR 入口

1.3 中断优先级

中断优先级(Interrupt Priority)用于决定当多个中断同时发生时,处理器应该先响应哪一个。优先级高的中断会优先被处理,优先级低的中断则被暂时屏蔽或挂起。

中断优先级的实现方式主要有以下三种:

  • 固定优先级:每个中断源分配一个固定的优先级,不可动态改变。例如 ARM 的 FIQ 优先级始终高于 IRQ。
  • 可编程优先级:通过寄存器配置每个中断源的优先级,可以在运行时调整。例如 GIC(Generic Interrupt Controller)支持 16~256 级可编程优先级。
  • 轮转优先级:优先级在多个中断源之间循环分配,防止某个中断被长期饿死。常用于实时性要求均衡的系统。
优先级模型 特点 典型硬件 Subdev 驱动影响
固定优先级 简单、确定性强、灵活性差 传统 8051、AVR 驱动无需配置优先级
可编程优先级 灵活、可动态调整、配置复杂 ARM GIC、RISC-V PLIC 驱动需在 probe 中设置优先级
轮转优先级 公平、实时性均衡、实现复杂 某些 DSP、CAN 控制器 驱动需考虑优先级反转
Subdev 驱动实践:在 Linux 内核中,中断优先级通常由中断控制器驱动管理。Subdev 驱动通过 devm_request_irq() 注册中断时,可以指定 irqflags 参数(如 IRQF_TRIGGER_RISING),但优先级设置通常由中断控制器驱动或设备树(Device Tree)中的 interrupts 属性配置。

中断优先级仲裁的流程可以用以下 SVG 图表示:

中断优先级仲裁流程 中断优先级仲裁流程 中断源 A(优先级 3) 中断源 B(优先级 1) 中断源 C(优先级 2) 中断控制器 优先级仲裁逻辑 比较所有挂起中断的优先级 选择最高优先级 向 CPU 发送中断信号 CPU 内核 响应最高优先级中断 优先级规则 • 数值越小优先级越高 • 本例中 B(优先级1)被选中

1.4 中断嵌套

中断嵌套(Interrupt Nesting)是指在一个中断服务程序执行期间,允许另一个更高优先级的中断打断当前 ISR 的执行。中断嵌套提高了系统的实时响应能力,但也增加了中断处理的复杂性和潜在风险。

中断嵌套的实现需要满足以下条件:

  • 硬件支持:CPU 必须支持在中断处理过程中再次响应中断(通常通过中断屏蔽寄存器控制)。
  • 现场保护:每次中断嵌套都需要保存当前 ISR 的上下文,嵌套深度增加时栈空间消耗增大。
  • 优先级判断:只有优先级高于当前 ISR 的中断才能嵌套,同级或低优先级中断被屏蔽。
Subdev 驱动关键点:在 Linux 内核中,中断嵌套行为由中断控制器和内核中断子系统共同管理。Subdev 驱动的 ISR 默认运行在关闭本地 CPU 中断(local_irq_disable)或关闭当前 IRQ 线的上下文中,因此驱动开发者通常不需要手动处理嵌套逻辑。但是,如果 ISR 中调用了 spin_lock 等可能导致睡眠的函数,必须使用 spin_lock_irqsave 等变体来避免死锁。

中断嵌套的执行时序可以用以下 SVG 图表示:

中断嵌套执行时序 中断嵌套执行时序 时间 主程序执行 低优先级 ISR(优先级 3) 高优先级 ISR(优先级 1) 恢复执行 中断A 中断B 中断嵌套执行流程说明 1. 主程序执行过程中,低优先级中断 A 发生,CPU 保存现场,跳转到 ISR_A 2. ISR_A 执行过程中,高优先级中断 B 发生,CPU 再次保存 ISR_A 的现场 3. CPU 跳转到 ISR_B 执行,ISR_B 完成后恢复 ISR_A 的现场 4. ISR_A 继续执行,完成后恢复主程序的现场,主程序继续运行 5. 嵌套深度 = 2(主程序 → ISR_A → ISR_B),栈空间消耗 = 2 × 现场大小

1.5 中断相关概念对比

概念 定义 与 Subdev 驱动的关系 典型配置位置
中断 异步事件通知机制 Subdev 设备产生中断信号 硬件引脚、设备树
中断向量 ISR 入口地址索引 驱动通过 IRQ 号绑定 ISR request_irq(irq, handler, ...)
中断优先级 中断响应顺序 影响 ISR 的实时响应 中断控制器寄存器、设备树
中断嵌套 高优先级打断低优先级 ISR 驱动需考虑重入与锁保护 spin_lock_irqsave
中断屏蔽 暂时禁止中断响应 临界区保护的关键手段 local_irq_disable/enable
中断延迟 从中断发生到 ISR 开始执行的时间 影响驱动实时性指标 内核配置、中断控制器设置
学习建议:中断基础概念是 Subdev 驱动开发中中断处理设计的基石。理解中断向量表的结构有助于在调试时定位 ISR 入口;理解中断优先级有助于合理分配设备的中断响应顺序;理解中断嵌套有助于编写安全的 ISR 代码,避免死锁和数据竞争。后续章节将深入讲解 Linux 内核中的中断处理框架、上半部/下半部机制以及 Subdev 驱动的具体中断注册流程。