2. 中断控制器基础:中断的概念、中断向量、中断优先级与中断嵌套
在嵌入式实时系统(RTOS)中,中断是处理器响应外部或内部异步事件的核心机制。对于 VxWorks BSP 开发而言,中断控制器(Interrupt Controller)是连接硬件外设与内核调度器的关键桥梁。本章将系统性地梳理中断的基本概念、向量表结构、优先级仲裁逻辑以及嵌套处理流程,为后续深入分析具体中断控制器(如 GIC、IOAPIC)的 BSP 适配打下坚实基础。
2.1 中断的基本概念
中断(Interrupt)是一种硬件机制,允许外设或软件通过向处理器发送电信号,暂停当前正在执行的程序流,并跳转到一个预先定义的服务例程(ISR)去处理该事件。处理完成后,处理器恢复被中断的上下文,继续执行原程序。
| 术语 | 英文 | 说明 |
|---|---|---|
| 中断请求 | IRQ | 外设向中断控制器发出的硬件信号 |
| 中断服务例程 | ISR | 响应中断时执行的函数,要求短小、无阻塞 |
| 中断向量 | Vector | 标识中断源的唯一编号,用于索引中断向量表 |
| 中断控制器 | PIC / GIC / IOAPIC | 集中管理多个中断源,负责优先级裁决与分发 |
| 中断上下文 | Interrupt Context | ISR 执行时的 CPU 状态,与任务上下文隔离 |
intConnect() 或 intVecSet() 函数,并确保 ISR 中不调用可能引起阻塞的 API(如 semTake() 带超时、malloc() 等)。
2.2 中断向量与向量表
中断向量(Interrupt Vector)是一个整数编号,每个中断源对应一个唯一的向量号。处理器在响应中断时,通过向量号在中断向量表(IVT)中查找对应的 ISR 入口地址。向量表通常位于内存的固定基地址,由 BSP 在启动阶段初始化。
2.3 中断优先级
中断优先级(Priority)用于决定当多个中断同时发生时,处理器优先响应哪一个。中断控制器通常支持可编程优先级,允许软件为每个中断源分配 0~255 级优先级(数值越小优先级越高,或反之,取决于具体硬件)。
优先级仲裁的基本规则如下:
- 抢占规则: 高优先级中断可以抢占正在执行的低优先级 ISR。
- 同优先级轮询: 相同优先级的中断按硬件连接顺序或 Round-Robin 方式响应。
- 屏蔽规则: 当前 ISR 执行期间,中断控制器可自动屏蔽同级或更低优先级的中断。
/* VxWorks BSP 中设置中断优先级示例 */
#include <vxWorks.h>
#include <intLib.h>
#include <hwif/vxBus.h>
STATUS sysIntPrioritySet(
UINT32 vector, /* 中断向量号 */
UINT32 priority /* 优先级值,0~255,0 为最高 */
)
{
VXB_DEVICE_ID pDev;
UINT32 regBase;
/* 通过 vxBus 获取中断控制器寄存器基址 */
pDev = vxbDevFindByClass("arm_gic", 0);
if (pDev == NULL)
return ERROR;
regBase = vxbDevRegBaseGet(pDev, 0);
if (regBase == 0)
return ERROR;
/* 写入 GICD_IPRIORITYR 寄存器 */
*(volatile UINT32 *)(regBase + 0x400 + (vector >> 2)) =
(priority & 0xFF) << ((vector & 3) << 3);
return OK;
}
2.4 中断嵌套
中断嵌套(Interrupt Nesting)是指在一个 ISR 执行过程中,允许更高优先级的中断打断当前 ISR,先执行高优先级 ISR,完成后返回被中断的 ISR 继续执行。嵌套深度受限于中断控制器的硬件设计以及操作系统的中断栈大小。
config.h 中,宏 INCLUDE_INT_LIB 和 INCLUDE_VXEVENTS 控制中断嵌套支持。中断栈大小由 ISR_STACK_SIZE 定义,默认通常为 4096 字节。如果嵌套深度过大,可能导致栈溢出,系统崩溃。
2.5 中断优先级与嵌套的硬件依赖
不同中断控制器的优先级模型和嵌套机制存在显著差异。下表对比了三种常见中断控制器的关键特性:
| 特性 | ARM GIC-400 | x86 IOAPIC + LAPIC | NXP (Freescale) MPIC |
|---|---|---|---|
| 优先级范围 | 0~255(0 最高) | 0~15(0 最低) | 0~15(0 最高) |
| 嵌套支持 | 硬件自动支持,通过 GICC_PMR 寄存器控制 | 需软件操作 LAPIC TPR 寄存器实现 | 硬件自动支持,通过 MI_PRI_MASK 寄存器控制 |
| 向量表位置 | 由 VBAR 寄存器指定 | IDT 由 IDTR 寄存器指定 | 由 IVOR 寄存器指定(e500 核) |
| BSP 初始化关键函数 | sysGicInit() |
sysIoApicInit() |
sysMpicInit() |
2.6 中断延迟与实时性考量
中断延迟(Interrupt Latency)是指从中断信号到达处理器引脚,到 ISR 第一条指令开始执行的时间间隔。在 VxWorks 实时系统中,中断延迟是衡量 BSP 性能的核心指标之一。
影响中断延迟的主要因素包括:
- 中断屏蔽时间: 内核或高优先级 ISR 执行期间关闭中断的时间窗口。
- 中断控制器仲裁时间: 硬件优先级比较和向量生成时间。
- 上下文保存开销: CPU 自动压栈(PC、SR、通用寄存器)的时钟周期数。
- Cache 与 TLB 缺失: 向量表和 ISR 代码不在 Cache 中时,需要从主存加载。
/* 使用 sysTimestamp 测量中断延迟 */
#include <vxWorks.h>
#include <sysTimestamp.h>
#include <intLib.h>
UINT64 tStart, tEnd;
UINT32 latencyMax = 0;
void myIsr(void)
{
tEnd = sysTimestamp();
UINT64 latency = tEnd - tStart;
if (latency > latencyMax)
latencyMax = (UINT32)latency;
/* ISR 处理逻辑 */
}
void triggerInterrupt(void)
{
tStart = sysTimestamp();
/* 触发硬件中断,例如写 GPIO 寄存器 */
*(volatile UINT32 *)GPIO_SET_REG = 1 << 5;
}
通过上述方法,BSP 开发者可以量化中断延迟,并针对性地优化中断屏蔽区间、调整优先级分配或使用中断绑定(Interrupt Affinity)将关键中断绑定到特定 CPU 核。