1、中断基础概念:中断的定义、中断向量、中断优先级、中断嵌套
中断是嵌入式系统与 Linux 内核驱动开发中最核心的异步事件处理机制。在 Subdev 驱动开发中,中断处理的设计直接决定了系统的实时性、可靠性与可维护性。本节从最基础的中断概念出发,建立中断处理的理论框架。
1.1 中断的定义
中断(Interrupt)是一种硬件或软件触发的信号,用于通知处理器发生了需要立即关注的事件。当中断发生时,处理器会暂停当前正在执行的程序,保存现场,跳转到一个预先定义的中断服务程序(ISR,Interrupt Service Routine)去处理该事件,处理完成后再恢复现场,继续执行被中断的程序。
核心特征:中断是一种异步事件,它不依赖于处理器当前的执行流,可以在任何时刻发生。这种机制使得处理器能够对外部或内部事件做出快速响应,而无需通过轮询方式浪费 CPU 周期。
Subdev 驱动视角:在 Subdev 驱动中,中断通常由硬件子设备(如 GPIO 控制器、I2C 从设备、SPI 外设、DMA 控制器等)产生。驱动开发者需要注册对应的中断处理函数,并在其中完成数据读取、状态清除、唤醒等待队列等操作。
中断的典型处理流程可以用以下 SVG 流程图表示:
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 图表示:
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 图表示:
1.4 中断嵌套
中断嵌套(Interrupt Nesting)是指在一个中断服务程序执行期间,允许另一个更高优先级的中断打断当前 ISR 的执行。中断嵌套提高了系统的实时响应能力,但也增加了中断处理的复杂性和潜在风险。
中断嵌套的实现需要满足以下条件:
- 硬件支持:CPU 必须支持在中断处理过程中再次响应中断(通常通过中断屏蔽寄存器控制)。
- 现场保护:每次中断嵌套都需要保存当前 ISR 的上下文,嵌套深度增加时栈空间消耗增大。
- 优先级判断:只有优先级高于当前 ISR 的中断才能嵌套,同级或低优先级中断被屏蔽。
Subdev 驱动关键点:在 Linux 内核中,中断嵌套行为由中断控制器和内核中断子系统共同管理。Subdev 驱动的 ISR 默认运行在关闭本地 CPU 中断(
local_irq_disable)或关闭当前 IRQ 线的上下文中,因此驱动开发者通常不需要手动处理嵌套逻辑。但是,如果 ISR 中调用了 spin_lock 等可能导致睡眠的函数,必须使用 spin_lock_irqsave 等变体来避免死锁。
中断嵌套的执行时序可以用以下 SVG 图表示:
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 驱动的具体中断注册流程。