3. 中断控制器架构与寄存器模型
在航电计算平台中,处理器核往往需要同时响应来自多个外设、总线桥、定时器和故障监控单元的中断请求。如果让每个中断源直接连到 CPU 的中断引脚,引脚数量和优先级仲裁都会失控。因此,实际 SoC 普遍采用可编程中断控制器(PIC,Programmable Interrupt Controller)作为中断汇聚与分发中枢。本节围绕 PIC 的寄存器模型、中断向量表、屏蔽与挂起机制,以及航电 SoC 中的中断路由设计展开。
一、可编程中断控制器的基本职责
PIC 的核心职责可以概括为四件事:汇聚(把多路中断源收敛为一条到 CPU 的请求线)、仲裁(按优先级决定先响应谁)、记录(保存哪些中断正在等待处理)、屏蔽(允许软件临时禁止某些中断)。在航电场景中,还要额外承担路由职责——把不同中断源定向到不同的 CPU 核或不同的异常入口。
一个典型 PIC 对外呈现三类接口:面向中断源的输入侧(IRQ0~IRQn 请求线)、面向 CPU 的输出侧(INT 请求线、ACK 应答线、向量号总线),以及面向软件的控制侧(一组内存映射寄存器)。软件对中断的全部控制,最终都落到这组寄存器上。
二、寄存器模型:中断控制的实际操作面
PIC 的寄存器通常按“每个中断源一位”的方式组织,常见的有以下几类:
- 使能/屏蔽寄存器(IER / IMR):IER 的 bit i 置 1 表示允许 IRQ i 上报;IMR 则是其反相形式,置 1 表示屏蔽。二者往往成对存在,写其中一个会同步另一个。
- 挂起寄存器(IPR / Pending):记录已经到达但尚未被 CPU 应答的中断。bit i 为 1 表示 IRQ i 正在等待。
- 优先级寄存器(IPRI):为每个中断源配置优先级,通常每源 3~4 bit,数值越小优先级越高(需在设计中明确约定,本课程统一采用“数值小=优先级高”)。
- 向量号寄存器(IVR):CPU 应答时读取,返回当前最高优先级挂起中断对应的向量号。
- 触发方式寄存器(ICR):配置每个中断源为边沿触发还是电平触发。
以 32 位寄存器、32 个中断源为例,一次典型的中断响应流程是:外设拉高 IRQ5 → IPR 的 bit5 置 1 → PIC 检查 IER 的 bit5 是否为 1 → 若允许,比较所有挂起中断的优先级 → 拉高 INT → CPU 应答 → PIC 把最高优先级中断的向量号写入 IVR 并清除对应 IPR 位。软件在中断服务程序(ISR)中读取 IVR 即可知道该跳转到哪个处理函数。
三、中断向量表与向量号
中断向量表(IVT)是一张“向量号 → 处理函数入口地址”的映射表。在 ARM 架构中,它通常位于异常向量基址(VBAR)指向的内存区域;在部分航电 SoC 中,则采用固定基址 + 向量号偏移的方式。向量号由 PIC 在应答时提供,CPU 据此计算入口地址。
向量表的关键设计点是向量号与中断源的绑定关系必须稳定。航电软件在认证过程中需要可追溯的中断响应路径,因此向量号一般静态分配,不随运行时状态变化。例如:IRQ0~IRQ7 分配给周期定时器与看门狗,IRQ8~IRQ15 分配给 ARINC 429 接收通道,IRQ16~IRQ23 分配给 AFDX 虚拟链路,IRQ24 以上保留给故障注入与调试。
四、屏蔽与挂起:两级过滤机制
屏蔽和挂起共同构成中断的“两级过滤”。挂起是硬件行为:中断源一旦满足触发条件,无论软件是否准备好,IPR 对应位都会被置 1,这是不可屏蔽的记录。屏蔽是软件行为:通过 IER 决定该挂起是否被允许上报到 CPU。
这种分离带来一个重要能力:软件可以“先屏蔽、后处理”。例如在关键任务区,软件把 IER 清零以推迟所有低优先级中断,此时中断仍会在 IPR 中累积;退出关键区后恢复 IER,PIC 会立即把累积的挂起中断按优先级上报。这比直接关闭 CPU 中断响应更精细,因为挂起信息没有丢失。
五、航电 SoC 中的中断路由设计
航电 SoC 通常包含多个 CPU 核、DMA 引擎和专用加速器。中断路由要解决三个问题:哪个中断送到哪个核、核间中断如何传递、安全关键中断如何隔离。
常见做法是采用两级结构:第一级是“源侧 PIC”,负责汇聚同类外设中断;第二级是“分发单元”,按路由表把中断送到目标核的本地 PIC。路由表本身也是一组寄存器,每个中断源对应一个目标核编号字段。对于安全关键中断(如电源故障、看门狗超时),通常配置为广播到所有核,或直接连到独立的安全监控核,绕过普通路由逻辑。
下面这张图给出一个航电 SoC 中断路由的典型结构:左侧是中断源,中间是源侧 PIC 与路由分发,右侧是多核本地 PIC 与向量表。
六、配置示例与结果判读
下面给出一段面向 32 源 PIC 的初始化配置示例,采用“数值小=优先级高”的约定。假设基址为 0x4000_0000,寄存器偏移:IER=0x00,IPR=0x04,IPRI=0x08(每源 4 bit,共 4 个寄存器),ICR=0x18,IVR=0x1C。
/* 1. 先屏蔽全部中断,避免配置过程中误触发 */
PIC_IER = 0x00000000;
/* 2. 配置触发方式:IRQ0-7 边沿,IRQ8-31 电平 */
PIC_ICR = 0xFFFFFF00; /* bit=1 表示电平触发 */
/* 3. 配置优先级:定时器最高(0),故障监控次高(1),通信类中等(8) */
PIC_IPRI[0] = 0x00000010; /* IRQ0=0, IRQ1=1 */
PIC_IPRI[1] = 0x88888888; /* IRQ8-15=8 */
PIC_IPRI[2] = 0x88888888; /* IRQ16-23=8 */
PIC_IPRI[3] = 0x11111111; /* IRQ28-31=1 */
/* 4. 使能需要的中断源 */
PIC_IER = 0x0000000F /* IRQ0-3 定时器 */
| 0x0000FF00 /* IRQ8-15 ARINC 429 */
| 0x00FF0000 /* IRQ16-23 AFDX */
| 0xF0000000; /* IRQ28-31 故障监控 */
/* 5. 在 ISR 中读取向量号并清除挂起 */
uint32_t vec = PIC_IVR; /* 读取最高优先级向量号 */
PIC_IPR = (1u << vec); /* W1C 清除对应挂起位 */
dispatch_isr(vec); /* 跳转到向量表对应入口 */
配置完成后,可通过以下现象判断是否正常:向某个已使能中断源注入一次请求,观察 IPR 对应位是否置 1;若 IER 对应位为 1,应能看到 INT 拉高、IVR 返回正确向量号;在 ISR 中写 IPR 后,该位应清零,且若没有其他挂起中断,INT 应恢复低电平。若 IPR 置位但 INT 始终不拉高,优先检查 IER 是否被误清零;若 ISR 反复进入同一向量,优先检查电平触发源是否在 ISR 中被清除。
在航电 SoC 中,中断控制器的设计质量直接决定了系统的确定性与可认证性。寄存器模型提供了软件可见的控制面,向量表提供了可追溯的响应路径,屏蔽与挂起机制提供了精细的时序控制,而路由设计则把这三者扩展到多核与安全关键场景。理解这四者的配合关系,是后续编写中断服务程序与进行中断延迟分析的基础。