3、中断控制器:T113 内部 GIC 架构与中断号分配

全志 T113 处理器内部集成了 ARM 通用中断控制器 (Generic Interrupt Controller, GIC),版本为 GIC-400。GIC 是连接外设中断源与 CPU 核心的桥梁,负责中断的使能、屏蔽、优先级仲裁以及分发。理解 GIC 的架构、中断号分配规则以及触发类型,是编写正确且高效 GPIO 中断驱动的理论基础。

3.1 GIC 架构分层与核心组件

T113 的 GIC-400 采用经典的两层架构:分发器 (Distributor) 和 CPU 接口 (CPU Interface)。分发器负责全局中断管理,CPU 接口则负责将中断信号传递给具体的 CPU 核心。

架构要点: 分发器与 CPU 接口通过独立的寄存器组进行配置,驱动开发中需要分别操作这两类寄存器以实现中断的完整控制流程。
GIC-400 架构分层与中断流向 外设中断源 (Peripherals) GPIO Bank A/B/C/D/E/F/G · UART · SPI · I2C · Timer · DMA 分发器 (Distributor) 中断使能/屏蔽 · 优先级配置 · 触发类型选择 · 中断号路由 寄存器基址: 0x01C81000 CPU 接口 (CPU Interface) 中断抢占 · 中断应答 (IAR) · 中断结束 (EOI) Cortex-A7 Core 0 / Core 1 中断信号流向 外设 → 分发器 → CPU接口 → 核心

3.2 中断号分配规则

T113 的 GIC 支持三种中断类型:共享外设中断 (SPI)、私有外设中断 (PPI) 和 软件触发中断 (SGI)。GPIO 中断属于 SPI 类型,其中断号由 GPIO Bank 和 Pin 的物理位置共同决定。

中断类型 ID 范围 描述 典型用途
SGI ID 0 – 15 软件触发中断,用于核间通信 CPU Core 0 向 Core 1 发送 IPI
PPI ID 16 – 31 私有外设中断,每个 CPU 核心独有 本地定时器、看门狗、性能监视
SPI ID 32 – 159 共享外设中断,所有核心共享 GPIO 中断、UART、SPI、I2C、DMA
GPIO 中断号速查: GPIO Bank A 对应 SPI ID 32–63,Bank B 对应 64–95,Bank C 对应 96–127,Bank D 对应 128–159。每个 Bank 内部按 Pin 号顺序分配,例如 PA0 对应 ID 32,PA1 对应 ID 33,以此类推。
GPIO 中断号分配映射 (SPI 类型) GPIO Bank A PA0 – PA31 SPI ID: 32 – 63 例: PA0 → ID 32 GPIO Bank B PB0 – PB31 SPI ID: 64 – 95 例: PB0 → ID 64 GPIO Bank C PC0 – PC31 SPI ID: 96 – 127 例: PC0 → ID 96 GPIO Bank D PD0 – PD31 SPI ID: 128 – 159 例: PD0 → ID 128 GIC 分发器 (Distributor) 根据 SPI ID 将中断路由到指定 CPU 核心 Cortex-A7 Core 0 / Core 1 每个 Bank 占用连续 32 个 SPI ID Bank 内 Pin 号 = ID 偏移量

3.3 中断触发类型:边沿与电平

GIC 支持两种中断触发类型:边沿触发 (Edge-triggered) 和 电平触发 (Level-triggered)。GPIO 中断通常配置为边沿触发,但某些特殊场景(如按键长按检测)可能需要电平触发。两种类型的差异直接影响中断响应逻辑和去抖处理方式。

特性 边沿触发 (Edge) 电平触发 (Level)
触发条件 信号上升沿或下降沿 信号保持高电平或低电平
中断锁存 GIC 锁存边沿事件,即使 CPU 未及时响应也不会丢失 中断信号必须保持有效电平,直到 CPU 应答
重复触发 仅触发一次,除非信号再次跳变 只要电平有效,中断会持续挂起
去抖需求 硬件或软件去抖,防止毛刺误触发 通常不需要去抖,但需注意电平保持时间
GPIO 适用场景 按键按下/释放、脉冲计数、编码器 状态检测、唤醒源、长按检测
GIC 配置寄存器 GICD_ICFGRn 对应位设为 0b01 (上升沿) 或 0b11 (双沿) GICD_ICFGRn 对应位设为 0b00 (高电平) 或 0b10 (低电平)
电平触发陷阱: 使用电平触发时,如果中断服务程序 (ISR) 没有清除外设的中断挂起状态(例如 GPIO 中断状态寄存器),GIC 会认为中断仍然有效,导致 CPU 反复进入中断,形成“中断风暴”。务必在 ISR 中先清除 GPIO 内部中断标志,再写 GIC 的 EOI 寄存器。
边沿触发 vs 电平触发 时序对比 边沿触发 (上升沿) GPIO 信号 触发 触发 电平触发 (高电平有效) GPIO 信号 持续触发 (电平有效期间) 关键区别 边沿触发:只在跳变瞬间产生中断,适合脉冲类信号,但易受毛刺干扰 电平触发:在电平有效期间持续请求中断,适合状态检测,但 ISR 必须清除中断源 GPIO 中断驱动中,推荐使用边沿触发 + 软件去抖,兼顾响应速度和稳定性

3.4 GIC 寄存器操作要点

在 GPIO 中断驱动中,需要操作以下 GIC 关键寄存器组:

  • GICD_CTLR (0x01C81000):分发器控制寄存器,使能分发器。
  • GICD_ISENABLERn (0x01C81100 + 4*n):中断使能寄存器,将对应 SPI ID 的位写 1 使能中断。
  • GICD_ICENABLERn (0x01C81180 + 4*n):中断屏蔽寄存器,写 1 屏蔽中断。
  • GICD_ICFGRn (0x01C810C00 + 4*n):中断配置寄存器,配置触发类型(边沿/电平)和极性。
  • GICD_ICPENDRn (0x01C81280 + 4*n):中断清除挂起寄存器,用于清除误挂起状态。
  • GICC_IAR (0x01C8200C):CPU 接口中断应答寄存器,读取获取当前中断 ID。
  • GICC_EOIR (0x01C82010):CPU 接口中断结束寄存器,写入中断 ID 表示处理完成。
驱动初始化流程:
1. 配置 GPIO 引脚为中断模式,设置触发极性 (上升沿/下降沿/高电平/低电平)。
2. 配置 GICD_ICFGRn 设置触发类型。
3. 配置 GICD_ISENABLERn 使能对应 SPI 中断。
4. 配置 CPU 接口 GICC_PMR 设置优先级掩码。
5. 使能 GICD_CTLR 和 GICC_CTLR。
6. 在 ISR 中:读取 GICC_IAR → 处理 GPIO 中断状态 → 清除 GPIO 中断标志 → 写 GICC_EOIR。

3.5 中断响应延迟与优先级

GIC 支持 16 级中断优先级 (0–15,0 为最高)。GPIO 中断通常配置为中等优先级 (例如 8–10),避免阻塞高实时性外设(如定时器、DMA)。中断响应延迟受以下因素影响:

因素 典型延迟 (CPU 主频 1.2GHz) 说明
GIC 硬件仲裁 ~50 ns 分发器比较优先级,选择最高优先级中断
CPU 中断入口 ~100 ns CPU 保存上下文,跳转到中断向量表
ISR 执行 取决于代码 GPIO 中断 ISR 应尽量短,仅做标志置位或数据搬运
中断嵌套 额外 50–200 ns 高优先级中断可抢占低优先级 ISR
优化建议: 在 GPIO 中断 ISR 中,避免调用可能导致睡眠的函数(如 printk、mutex_lock)。使用 tasklet 或 workqueue 将耗时操作推迟到下半部执行,确保中断响应延迟在微秒级。