1. VxWorks 中断机制概述
中断是嵌入式实时系统响应外部异步事件的核心机制。在 VxWorks 中,中断处理路径必须满足严格的时间确定性要求,任何延迟都可能导致系统失控。理解中断向量表、中断控制器和中断服务程序(ISR)这三个基本概念,是掌握 WindView 中断分析的前提。
1.1 中断向量表
中断向量表(Interrupt Vector Table, IVT)是一张存储在固定内存地址的跳转表,每个表项对应一个中断源,存放该中断对应的处理函数入口地址。VxWorks 在系统启动阶段初始化这张表,并在运行时通过 intConnect() 动态绑定 ISR。
| 属性 | 说明 |
|---|---|
| 存储位置 | 通常位于 RAM 低地址区(如 0x0000 ~ 0x03FF),可动态修改 |
| 表项大小 | 每个表项 4 字节(32 位指针)或 8 字节(64 位) |
| 最大中断数 | 由 CPU 架构决定,x86 为 256,PowerPC 为 256,ARM 为 16~1024 |
| 初始化时机 | 系统启动时由 usrKernelInit() 或 BSP 完成 |
| 动态绑定 | 通过 intConnect(VEC, ISR, param) 写入表项 |
调试要点: 使用 WindView 捕获中断时,首先确认中断向量号是否与硬件设计一致。向量号错位会导致 ISR 无法触发或触发错误的 ISR。
经验法则: 在 BSP 调试阶段,建议在
intConnect() 之后立即调用 intContextShow() 验证向量表内容。
1.2 中断控制器
中断控制器(Interrupt Controller)是 CPU 与外部中断源之间的硬件桥梁。它负责接收多个外设的中断请求,进行优先级裁决,并向 CPU 提交唯一的中断向量号。VxWorks 支持多种中断控制器,包括 8259A(x86)、GIC(ARM)、MPIC(PowerPC)等。
中断控制器的核心功能
- 中断屏蔽: 通过寄存器单独启用/禁用每个中断源。
- 优先级裁决: 当多个中断同时到达时,选择最高优先级的中断提交给 CPU。
- 向量号生成: 向 CPU 提供唯一的中断向量号,用于索引中断向量表。
- 中断结束(EOI): ISR 执行完毕后通知控制器释放中断线。
| 控制器类型 | 典型架构 | 最大中断源 | 优先级级数 | VxWorks 驱动 |
|---|---|---|---|---|
| 8259A | x86 / Pentium | 15(级联) | 8 | i8259IntLib |
| GICv2/v3 | ARM Cortex-A | 1024 | 256 | armGicIntLib |
| MPIC | PowerPC | 256 | 16 | mpicIntLib |
| INTC | NXP i.MX | 128 | 64 | imxIntLib |
常见陷阱: 中断控制器未正确初始化时,WindView 可能显示“中断丢失”或“虚假中断”。检查 BSP 中
sysIntInit() 是否在 usrKernelInit() 之前被调用。
1.3 中断服务程序(ISR)
中断服务程序(Interrupt Service Routine, ISR)是响应中断时执行的函数。VxWorks 的 ISR 运行在特殊的中断上下文中,与普通任务上下文有严格区别。ISR 必须短小、快速、不可阻塞。
ISR 的关键约束
- 不可调用阻塞 API: 如
semTake()、msgQSend()、malloc()、printf()。 - 不可访问任务私有资源: 如任务栈、任务局部变量。
- 必须保存/恢复上下文: VxWorks 内核自动保存大部分寄存器,但 ISR 需手动保存浮点寄存器(如使用浮点运算)。
- 执行时间必须极短: 通常控制在几十微秒以内,否则会阻塞其他中断。
ISR 的典型结构
#include <vxWorks.h>
#include <intLib.h>
#include <sysLib.h>
/* 中断服务程序 */
void myIsr(int arg)
{
/* 1. 读取硬件状态寄存器,确认中断源 */
UINT32 status = REG_READ(INT_STATUS_REG);
/* 2. 处理中断(仅做必要操作,如置标志位) */
if (status & RX_READY) {
g_rxFlag = TRUE; /* 全局标志,由任务轮询 */
}
/* 3. 写中断结束(EOI)寄存器 */
REG_WRITE(INT_EOI_REG, 0);
}
/* 中断连接 */
STATUS initMyInterrupt(void)
{
/* 向量号 0x25,ISR 入口 myIsr,参数 0 */
return intConnect(INUM_TO_IVEC(0x25), myIsr, 0);
}
WindView 分析要点: 在 WindView 时间线中,ISR 执行区域显示为红色高亮条。如果 ISR 执行时间超过 100 μs,应检查是否在 ISR 中调用了阻塞函数或执行了长循环。
1.4 中断上下文 vs 任务上下文
| 对比项 | 中断上下文(ISR) | 任务上下文(Task) |
|---|---|---|
| 调度方式 | 不可抢占(除非嵌套中断) | 可被更高优先级任务抢占 |
| 阻塞调用 | 禁止 | 允许 |
| 栈空间 | 使用中断栈(固定大小) | 使用任务栈(可配置) |
| 信号量操作 | 仅允许 semGive() |
semTake() / semGive() |
| 内存分配 | 禁止(malloc 不可用) |
允许 |
| WindView 标识 | 红色高亮条 | 蓝色/绿色任务条 |
1.5 中断延迟与 WindView 观测
中断延迟(Interrupt Latency)是从硬件中断信号到达 CPU 到 ISR 开始执行之间的时间。VxWorks 的中断延迟通常为 1~10 μs,但在以下情况下会恶化:
- 中断嵌套: 高优先级 ISR 执行期间,低优先级中断被阻塞。
- 中断屏蔽: 任务调用
intLock()或taskLock()导致全局中断关闭。 - Cache 未命中: ISR 代码或数据不在指令/数据 Cache 中。
WindView 实战: 在 WindView 配置中启用“Interrupt Latency”测量项,可直接在时间线上看到每个中断的延迟数值。如果延迟超过 50 μs,应检查是否有任务长时间关闭中断。