1、中断基础概念:中断向量、中断号、中断控制器(GIC/APIC)硬件架构

中断是嵌入式系统与操作系统响应异步事件的基石。理解中断向量、中断号以及中断控制器(GIC/APIC)的硬件架构,是编写可靠中断处理驱动的第一步。本节从硬件视角拆解中断的传递路径与核心数据结构。

1.1 中断向量与中断号

中断向量(Interrupt Vector)是中断服务程序(ISR)入口地址的索引表。CPU 在响应中断时,通过硬件自动获取向量号,跳转到对应的处理函数。中断号(IRQ Number)则是软件层面用于标识中断源的逻辑编号。

概念 定义 典型范围 使用场景
中断向量 中断描述符表(IDT/IVT)中每个表项的索引,指向 ISR 地址 0–255(x86) CPU 硬件自动查表跳转
中断号 操作系统或驱动层对中断源的软件编号 0–NR_IRQS(Linux) request_irq()、free_irq() 等 API
硬件中断线 物理引脚或消息信号,由中断控制器管理 SPI/PPI/LPI(GIC) 设备树或 ACPI 描述
驱动开发要点: 在 Linux 中,中断号与中断向量之间通过 irq_to_desc() 和 irq_domain 映射。不要假设中断号等于向量号,尤其在 ARM GIC 和 x86 APIC 上,映射关系由固件和内核共同维护。

1.2 中断控制器硬件架构

中断控制器负责收集外设中断请求,进行优先级仲裁,并将中断信号分发给 CPU。主流架构包括 ARM 的 GIC(Generic Interrupt Controller)和 x86 的 APIC(Advanced Programmable Interrupt Controller)。

1.2.1 ARM GIC 架构

GIC 是 ARM 体系的标准中断控制器,支持多核分发、中断优先级、安全扩展。GICv2/v3/v4 是嵌入式 Linux 驱动开发中最常打交道的版本。

GIC 核心组件:
  • Distributor(分发器): 全局中断配置、使能、优先级、目标 CPU。
  • CPU Interface(CPU 接口): 每个 CPU 核独立拥有,处理中断抢占与应答。
  • Redistributor(重分发器,GICv3+): 每个 CPU 核关联,管理 PPI 和 SGI。
ARM GIC 中断控制器架构(GICv3) 外设 SPI 中断 外设 PPI 中断 软件 SGI 中断 Distributor 中断使能/屏蔽 优先级仲裁 目标 CPU 路由 中断分组(Group0/1) Redistributor 0 PPI/SGI 管理 优先级过滤 Redistributor 1 PPI/SGI 管理 优先级过滤 CPU IF 0 CPU IF 1 说明: • SPI(Shared Peripheral Interrupt):共享外设中断,由 Distributor 路由到指定 CPU。 • PPI(Private Peripheral Interrupt):私有外设中断,每个 CPU 独立拥有,如本地定时器。 • SGI(Software Generated Interrupt):软件触发中断,用于核间通信(IPI)。

1.2.2 x86 APIC 架构

x86 平台使用 Local APIC(LAPIC)和 I/O APIC 组合。LAPIC 集成在 CPU 内部,处理本地中断源(如定时器、错误中断);I/O APIC 负责收集外设中断并转发给 LAPIC。

组件 功能 寄存器访问方式 关键特性
Local APIC 接收本地中断、IPI、定时器中断 MMIO(默认 0xFEE00000) 中断优先级、EOI、Task Priority
I/O APIC 收集外设中断,重定向到 LAPIC MMIO(默认 0xFEC00000) 24 路中断输入,可编程路由
MSI/MSI-X 外设直接写 LAPIC 的消息信号中断 PCIe 配置空间 无需 I/O APIC,减少延迟
x86 APIC 中断控制器架构 外设设备 外设设备 I/O APIC 中断重定向表 24 路 IRQ 输入 可编程目标 LAPIC Local APIC 0 IRQ 向量接收 IPI 发送/接收 定时器/错误中断 Local APIC 1 IRQ 向量接收 IPI 发送/接收 定时器/错误中断 CPU 0 CPU 1 MSI/MSI-X 直接写 LAPIC 说明: • I/O APIC 将外设中断重定向到指定 LAPIC,支持中断负载均衡。 • MSI/MSI-X 允许 PCIe 设备绕过 I/O APIC,直接向 LAPIC 发送中断消息,降低延迟。

1.3 中断优先级与嵌套基础

中断控制器通过硬件优先级寄存器决定哪个中断优先被 CPU 响应。GIC 使用 8 位优先级字段(实际实现可能只使用高 5 位或高 4 位),值越小优先级越高。APIC 使用 Task Priority Register(TPR)和 Processor Priority Register(PPR)控制中断屏蔽阈值。

驱动开发陷阱: 在 GIC 中,如果 ISR 没有在入口处提升优先级(Priority Drop),高优先级中断无法抢占当前 ISR,导致中断嵌套失效。Linux 内核通过 gic_handle_irq() 自动处理优先级分组,但自定义中断处理逻辑时务必注意 EOI(End of Interrupt)时序。

1.4 中断处理流程速览

  1. 外设触发: 设备拉高中断请求线(或发送 MSI 消息)。
  2. 中断控制器仲裁: Distributor/I/O APIC 根据优先级选择最高优先级中断,路由到目标 CPU。
  3. CPU 响应: CPU 保存上下文(PC、PSR),查询中断向量表,跳转到 ISR。
  4. ISR 执行: 读取中断状态寄存器,执行必要处理,写 EOI 寄存器。
  5. 恢复上下文: CPU 恢复现场,继续执行被中断的任务。
关键寄存器速查(GICv3):
  • ICC_PMR_EL1:中断优先级掩码寄存器,决定 CPU 响应中断的最低优先级。
  • ICC_IAR0_EL1 / ICC_IAR1_EL1:中断应答寄存器,读取后获取中断 ID 并激活中断。
  • ICC_EOIR0_EL1 / ICC_EOIR1_EL1:中断结束寄存器,写入后通知中断控制器处理完成。