2. Linux中断子系统:中断向量、中断控制器、中断处理流程

中断子系统是嵌入式Linux实时性能的基石。DMA传输完成后,硬件通过中断线向CPU发出信号,CPU必须快速响应并完成数据移交。理解中断向量、中断控制器(IRQ Controller)以及完整的中断处理流程,是优化DMA中断延迟的前提。

2.1 中断向量表与中断号

中断向量表(Interrupt Vector Table, IVT)是CPU响应中断时的入口地址映射表。每个中断源被分配一个唯一的中断向量号(Vector Number),CPU在中断响应周期中通过硬件自动获取该向量号,并跳转到对应的处理函数。

概念 说明 典型范围
中断向量号 CPU硬件识别的数字编号,用于索引IVT ARM:0~15(异常),16~(IRQ)
x86:0~255
IRQ号 Linux软件抽象的中断编号,与硬件向量映射 0~NR_IRQS-1(通常256~2048)
中断描述符 内核维护的irq_desc结构体,包含处理函数、标志、统计 每个IRQ号对应一个
实时要点:在实时系统中,中断向量号到IRQ号的映射延迟必须可预测。固定映射(如SPI中断)优于动态分配,避免查找开销。
中断向量表映射结构 向量号 0x10 向量号 0x11 向量号 0x12 向量号 0x13 IRQ 32 IRQ 33 IRQ 34 IRQ 35 irq_desc[32] irq_desc[33] irq_desc[34] irq_desc[35] 硬件向量 → 软件IRQ号 → 中断描述符:三级映射,实时系统需保证映射确定性

2.2 中断控制器(IRQ Controller)

中断控制器负责收集多个外设中断请求,进行优先级仲裁,并向CPU提交中断信号。在嵌入式系统中,常见的中断控制器包括GIC(Generic Interrupt Controller,ARM)、APIC(x86)和NVIC(Cortex-M)。

2.2.1 GICv2/v3 架构

GIC是ARM体系的标准中断控制器,支持三种中断类型:

  • SPI(Shared Peripheral Interrupt): 共享外设中断,可路由到任意CPU核心,用于DMA等外设。
  • PPI(Private Peripheral Interrupt): 私有外设中断,绑定到特定CPU核心,如本地定时器。
  • SGI(Software Generated Interrupt): 软件触发中断,用于核间通信(IPI)。
特性 GICv2 GICv3
最大中断数 1020 1020(扩展至16K)
路由方式 静态路由(CPU接口绑定) 动态路由(基于亲和性)
优先级位宽 8位(256级) 8位(256级)
虚拟化支持 有限 原生支持(vGIC)
实时适用性 适合确定性中断路由 适合多核负载均衡
GIC中断控制器架构 DMA 以太网 定时器 中断分发器 (Distributor) 优先级仲裁 使能/屏蔽 路由决策 CPU接口0 (Core 0) CPU接口1 (Core 1) CPU CPU DMA中断通过Distributor仲裁后,由CPU接口向指定核心触发IRQ信号

2.3 中断处理流程:从硬件到软件

一个完整的中断处理流程分为硬件阶段和软件阶段。理解每个阶段的耗时,是优化DMA中断延迟的关键。

2.3.1 硬件阶段

  1. 外设断言中断线: DMA传输完成,拉高中断请求信号。
  2. 中断控制器仲裁: GIC比较优先级,选择最高优先级中断。
  3. CPU中断响应: CPU保存上下文(PC、PSR、LR),跳转到中断向量入口。
  4. 向量获取: 读取GIC的IAR寄存器,获取中断号。

2.3.2 软件阶段

  1. 中断入口汇编: 保存通用寄存器,调用handle_arch_irq。
  2. 通用中断处理: 调用generic_handle_irq,查找irq_desc。
  3. 中断控制流: 执行handle_level_irq或handle_edge_irq。
  4. 执行action回调: 调用request_irq注册的中断处理函数(ISR)。
  5. 退出中断: 写EOI寄存器,恢复上下文,返回被中断的任务。
Linux中断处理完整流程 ① 外设断言中断 ② GIC仲裁 ③ CPU响应 ④ 读取IAR ⑤ 保存上下文 ⑥ generic_handle_irq ⑦ handle_level_irq ⑧ ISR执行 ⑨ 写EOI ⑩ 恢复上下文 硬件阶段(①~④)不可抢占,软件阶段(⑤~⑩)可被更高优先级中断嵌套 DMA中断优化重点:缩短ISR执行时间,将耗时操作推迟到tasklet或工作队列

2.4 中断处理函数注册与上下文

驱动通过request_irq注册中断处理函数,并指定处理标志:

int request_irq(unsigned int irq,
                irq_handler_t handler,
                unsigned long flags,
                const char *name,
                void *dev_id);
标志 含义 对DMA的影响
IRQF_TRIGGER_RISING 上升沿触发 适合DMA完成脉冲信号
IRQF_TRIGGER_HIGH 高电平触发 需注意电平保持时间
IRQF_SHARED 共享中断线 增加ISR遍历开销,实时场景避免
IRQF_NO_SUSPEND 系统休眠时保持使能 DMA后台传输需要
IRQF_ONESHOT 中断线保持屏蔽直到ISR完成 防止中断嵌套,适合实时确定性
实时陷阱: 使用IRQF_SHARED时,内核会遍历所有注册的handler,导致中断响应时间不确定。DMA中断应独占IRQ线,避免共享。

2.5 中断处理中的延迟来源

在DMA中断场景中,以下环节是延迟的主要贡献者:

  • 中断控制器访问延迟: 读取IAR、写EOI涉及MMIO访问,总线等待时间不可忽略。
  • 中断屏蔽与恢复: local_irq_save/local_irq_restore操作影响全局中断响应。
  • 中断嵌套: 高优先级中断抢占低优先级ISR,导致DMA数据移交延迟。
  • Cache抖动: ISR执行导致指令/数据Cache污染,影响被中断任务的恢复。