ARM Linux 嵌入式中断全流程解析:从 GPIO 到 GIC 架构实战

ARM Linux 嵌入式中断全流程解析:从 GPIO 到 GIC 架构实战 本文基于 Cortex-A 系列处理器imx6ull/Cortex-A7/A53整理覆盖中断处理全流程、GIC 架构演进、CP15 协处理器操作、底层汇编指令适合嵌入式 Linux / 裸机开发入门与复习。一、中断处理的 6 个标准步骤ARM 体系中一个完整的中断流程如下中断源发出中断请求如 GPIO 按键、定时器、UART 等外设触发CPU 检查是否响应中断 是否被屏蔽检查 CPSR 中的 I/F 位比较中断优先级由 GIC通用中断控制器仲裁保护现场保存 CPSR、LR压栈寄存器执行中断服务函数ISR恢复现场出栈返回被中断的程序继续执行二、GIC 架构与版本演进GICGeneric Interrupt Controller是 ARM 官方定义的中断控制器标准。1️⃣ GIC 版本对比GIC 版本适用处理器典型场景GIC v1Cortex-A5早期 32 位嵌入式GIC v2Cortex-A732 位imx6ull、树莓派等GIC v3/v4Cortex-A5364 位手机 SoCGIC v5重架构支持数百核服务器 / 高性能计算imx6ull 实际支持 160 个中断号0–159三、GIC 中断类型详解GIC 将中断分为三类中断类型缩写中断号范围说明软件中断SGI0 – 15CPU 核间通信私有外设中断PPI16 – 31每个核独享共享外设中断SPI32 – 1019GPIO、UART、Timer 等✅我们常用的 GPIO 中断属于 SPI四、CP15 协处理器与 GIC 基地址ARM 中很多系统控制功能都通过CP15 协处理器完成。1️⃣ 常用指令mrc p15, 0, Rt, CRn, CRm, opc2 ; 读 CP15 寄存器 mcr p15, 0, Rt, CRn, CRm, opc2 ; 写 CP15 寄存器2️⃣ 读取 GIC 基地址CBARmrc p15, 4, r1, c15, c0, 0 ; 读取 CBAR得到 GIC 基地址到 r1五、中断关键寄存器GIC 接口中有两个非常关键的寄存器uint32_t ICC_IAR; /* Offset: 0x200C (R) 中断应答寄存器 */ uint32_t ICC_EOIR; /* Offset: 0x2010 (W) 中断结束寄存器 */ICC_IARCPU 读取后表示“我知道这个中断了”ICC_EOIRCPU 写入后表示“中断处理完毕”⚠️ 两者缺一不可否则中断会一直挂起。六、开关中断与控制指令1️⃣ cps 指令最常用cpsie i ; 使能 IRQ 中断 cpsid i ; 关闭 IRQ 中断标志含义IIRQ 中断FFIQ 快速中断2️⃣ SCTLR 控制示例mrc p15, 0, r0, c1, c0, 0 ; 读 SCTLR bic r0, r0, #(1 13) orr r0, r0, #(1 12) mcr p15, 0, r0, c1, c0, 0 ; 写回 SCTLR七、GPIO 中断实战示例Key0GPIO1_18以GPIO1_18 按键中断为例典型流程如下配置 GPIO 为中断模式设置触发方式下降沿 / 上升沿使能 GPIO 中断在 GIC 中使能对应 SPI 中断设置中断优先级ISR 中读取ICC_IAR清除中断标志写ICC_EOIR结束中断GPIO → GIC → CPU 内核​ 是标准的硬件中断链路。八、完整中断调用链总结外设中断(GPIO/UART/Timer) ↓ GIC(SPI/PPI/SGI) ↓ CPU(IRQ/FIQ) ↓ 保护现场 ↓ 执行 ISR ↓ 恢复现场 ↓ ICC_EOIR ↓ 返回原程序九、常见踩坑提醒 ⚠️❌ 只清 GPIO 中断标志不写ICC_EOIR→ 中断反复进入❌ 忘记cpsie i→ 中断永远进不来❌ 混淆 SPI / PPI / SGI 的中断号范围❌ 在多核平台未正确绑定中断亲和性GICv3十、总结一句话中断 硬件触发 GIC 仲裁 CPU 响应 现场保护 ISR 执行 中断结束