本文基于 Cortex-A 系列处理器(imx6ull/Cortex-A7/A53)整理,覆盖中断处理全流程、GIC 架构演进、CP15 协处理器操作、底层汇编指令,适合嵌入式 Linux / 裸机开发入门与复习。
一、中断处理的 6 个标准步骤
ARM 体系中,一个完整的中断流程如下:
-
中断源发出中断请求
- 如 GPIO 按键、定时器、UART 等外设触发
-
CPU 检查是否响应中断 & 是否被屏蔽
- 检查 CPSR 中的 I/F 位
-
比较中断优先级
- 由 GIC(通用中断控制器)仲裁
-
保护现场
- 保存 CPSR、LR,压栈寄存器
-
执行中断服务函数(ISR)
-
恢复现场
- 出栈,返回被中断的程序继续执行
二、GIC 架构与版本演进
GIC(Generic Interrupt Controller)是 ARM 官方定义的中断控制器标准。
1️⃣ GIC 版本对比
| GIC 版本 | 适用处理器 | 典型场景 |
|---|---|---|
| GIC v1 | Cortex-A5 | 早期 32 位嵌入式 |
| GIC v2 | Cortex-A7(32 位) | imx6ull、树莓派等 |
| GIC v3/v4 | Cortex-A53(64 位) | 手机 SoC |
| GIC v5 | 重架构,支持数百核 | 服务器 / 高性能计算 |
👉 imx6ull 实际支持 160 个中断号(0--159)
三、GIC 中断类型详解
GIC 将中断分为三类:
| 中断类型 | 缩写 | 中断号范围 | 说明 |
|---|---|---|---|
| 软件中断 | SGI | 0 -- 15 | CPU 核间通信 |
| 私有外设中断 | PPI | 16 -- 31 | 每个核独享 |
| 共享外设中断 | SPI | 32 -- 1019 | GPIO、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 基地址(CBAR)
mrc 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_IAR:CPU 读取后,表示"我知道这个中断了"
-
ICC_EOIR:CPU 写入后,表示"中断处理完毕"
⚠️ 两者缺一不可,否则中断会一直挂起。
六、开关中断与控制指令
1️⃣ cps 指令(最常用)
cpsie i ; 使能 IRQ 中断
cpsid i ; 关闭 IRQ 中断
| 标志 | 含义 |
|---|---|
| I | IRQ 中断 |
| F | FIQ 快速中断 |
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 中断实战示例(Key0:GPIO1_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 执行 + 中断结束