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 即可知道该跳转到哪个处理函数。

边沿触发适合“事件型”中断(如一次数据到达),电平触发适合“状态型”中断(如 FIFO 非空)。若电平触发源在 ISR 中未被清除,中断会在返回后立即再次触发,形成中断风暴。

三、中断向量表与向量号

中断向量表(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 中断响应更精细,因为挂起信息没有丢失。

清除挂起位有两种方式:写 1 清除(W1C)和读后自动清除。混用会导致“中断丢失”或“重复响应”。在航电驱动中应统一采用 W1C,并在 ISR 中显式清除对应 IPR 位。

五、航电 SoC 中的中断路由设计

航电 SoC 通常包含多个 CPU 核、DMA 引擎和专用加速器。中断路由要解决三个问题:哪个中断送到哪个核、核间中断如何传递、安全关键中断如何隔离。

常见做法是采用两级结构:第一级是“源侧 PIC”,负责汇聚同类外设中断;第二级是“分发单元”,按路由表把中断送到目标核的本地 PIC。路由表本身也是一组寄存器,每个中断源对应一个目标核编号字段。对于安全关键中断(如电源故障、看门狗超时),通常配置为广播到所有核,或直接连到独立的安全监控核,绕过普通路由逻辑。

下面这张图给出一个航电 SoC 中断路由的典型结构:左侧是中断源,中间是源侧 PIC 与路由分发,右侧是多核本地 PIC 与向量表。

中断源 周期定时器 IRQ0-3 看门狗 IRQ4 ARINC 429 IRQ8-15 AFDX VL IRQ16-23 DMA 完成 IRQ24-27 故障监控 IRQ28-31 源侧 PIC IER 使能 IPR 挂起 IPRI 优先级 ICR 触发方式 IVR 向量号 优先级仲裁 最高挂起胜出 路由分发单元 路由表寄存器 目标核编号 广播/单播选择 安全中断旁路 目标 CPU 核 CPU0 本地 PIC 向量表基址 VBAR0 CPU1 本地 PIC 向量表基址 VBAR1 安全监控核 独立向量表 CPU2 本地 PIC 向量表基址 VBAR2 路由规则示例:IRQ0-7 → CPU0;IRQ8-15 → CPU1;IRQ16-23 → CPU2;IRQ28-31(故障监控)→ 安全监控核 + 广播至 CPU0/1/2。 安全关键中断绕过普通路由表,直接进入安全监控核的独立向量表,确保即使主路由逻辑失效仍可响应。 所有本地 PIC 共享同一套寄存器语义(IER/IPR/IPRI/IVR),但向量表基址各自独立。

六、配置示例与结果判读

下面给出一段面向 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 中,中断控制器的设计质量直接决定了系统的确定性与可认证性。寄存器模型提供了软件可见的控制面,向量表提供了可追溯的响应路径,屏蔽与挂起机制提供了精细的时序控制,而路由设计则把这三者扩展到多核与安全关键场景。理解这四者的配合关系,是后续编写中断服务程序与进行中断延迟分析的基础。