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() 验证向量表内容。
中断向量表结构示意图 中断向量表结构 向量号 ISR 入口地址 绑定设备/参数 状态 0x00 _excDivideByZero CPU 异常 固定 0x20 _isrTimerTick 系统时钟 已连接 0x21 _isrUartRx UART0 已连接 0x22 _isrGpioInt GPIO 按键 未连接 ... ... ... ... 说明: 每个向量号对应一个固定的硬件中断源或 CPU 异常。VxWorks 通过 intConnect() 将 ISR 地址写入对应表项。 WindView 可捕获每个向量号的触发时刻和 ISR 执行时长。

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() 之前被调用。
中断控制器工作流程 中断控制器工作流程 外设 A (UART) 外设 B (定时器) 外设 C (GPIO) 中断控制器 优先级裁决 向量号生成 中断屏蔽 EOI 管理 级联支持 CPU 中断响应 查向量表 流程: 外设触发中断 → 中断控制器裁决优先级 → 生成向量号 → CPU 响应 → 查向量表 → 执行 ISR → ISR 写 EOI WindView 可观测从外设触发到 ISR 完成的全路径延迟。

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 标识 红色高亮条 蓝色/绿色任务条
中断上下文与任务上下文对比 中断上下文 vs 任务上下文 中断上下文 • 运行在中断栈 • 不可阻塞 • 仅 semGive() 可用 • 禁止 malloc/printf • 执行时间 < 100 μs • WindView 红色高亮 任务上下文 • 运行在任务栈 • 可阻塞等待 • semTake/semGive 均可 • 允许 malloc/printf • 执行时间无硬限制 • WindView 蓝/绿色条 切换

1.5 中断延迟与 WindView 观测

中断延迟(Interrupt Latency)是从硬件中断信号到达 CPU 到 ISR 开始执行之间的时间。VxWorks 的中断延迟通常为 1~10 μs,但在以下情况下会恶化:

  • 中断嵌套: 高优先级 ISR 执行期间,低优先级中断被阻塞。
  • 中断屏蔽: 任务调用 intLock() 或 taskLock() 导致全局中断关闭。
  • Cache 未命中: ISR 代码或数据不在指令/数据 Cache 中。
WindView 实战: 在 WindView 配置中启用“Interrupt Latency”测量项,可直接在时间线上看到每个中断的延迟数值。如果延迟超过 50 μs,应检查是否有任务长时间关闭中断。