VxWorks中断服务例程ISR编写与性能优化 - 第1节

1.1 中断系统基础概念

中断(Interrupt)是嵌入式实时操作系统 VxWorks 中处理异步事件的核心机制。当外设或软件需要 CPU 立即关注时,通过中断信号暂停当前任务,转而执行预先注册的中断服务例程(ISR)。中断机制直接决定了系统的实时响应能力。

关键定义:中断是硬件或软件发出的异步信号,CPU 在每条指令执行完毕后检查中断请求,若允许则保存现场并跳转到中断向量表指定的 ISR 入口。

1.1.1 中断与轮询的对比

特性 中断驱动 轮询方式
CPU 利用率 高,无事时休眠或执行其他任务 低,持续占用 CPU 检查状态
响应延迟 微秒级,事件触发立即响应 取决于轮询周期,通常毫秒级
实时性 确定性强,适合硬实时 不确定性高,受轮询频率影响
软件复杂度 较高,需处理嵌套与共享 较低,循环检查即可
适用场景 网络、定时器、外部事件 低速、非关键状态查询

1.2 中断向量表(IVT)

中断向量表是 CPU 与操作系统之间的桥梁,存储了每个中断号对应的 ISR 入口地址。VxWorks 在系统启动时初始化向量表,支持动态注册与修改。

中断向量表结构示意图 中断向量表基址 (VEC_BASE_ADDR) 向量 0: 复位 向量 1: 时钟 向量 2: 外部IRQ 向量 3: 串口 ... resetHandler() tickHandler() extIntHandler() uartHandler() 说明 每个向量条目占用 4 字节(32位地址),VxWorks 通过 intConnect() 动态绑定 ISR

1.2.1 VxWorks 中断注册 API

/* 中断连接函数原型 */
STATUS intConnect(
    VOIDFUNCPTR *vector,    /* 中断向量地址 */
    VOIDFUNCPTR routine,    /* ISR 函数指针 */
    int parameter           /* 传递给 ISR 的参数 */
);

/* 示例:注册定时器中断 */
#include <vxWorks.h>
#include <intLib.h>

void myTimerIsr(int arg) {
    /* ISR 处理代码 */
    *(volatile int *)TIMER_STATUS_REG = 0;  /* 清除中断标志 */
}

void initTimerInt(void) {
    intConnect((VOIDFUNCPTR *)INUM_TO_IVEC(INT_TIMER0),
               (VOIDFUNCPTR)myTimerIsr,
               0);
}

1.3 中断优先级

VxWorks 支持多级中断优先级,通常由硬件中断控制器(如 x86 的 APIC、ARM 的 GIC、PowerPC 的 MPIC)提供。优先级决定了多个中断同时到达时的服务顺序。

优先级规则:高优先级中断可以抢占低优先级中断的执行。VxWorks 默认使用 0~255 级优先级,0 为最高,255 为最低。实际可用级数取决于硬件平台。

1.3.1 优先级与响应延迟

优先级等级 典型用途 最大允许延迟 ISR 长度限制
0-31(最高) 时钟、紧急故障 < 1 µs 极短,仅状态保存
32-127 高速外设(DMA、网络) 1-10 µs < 100 条指令
128-191 中速外设(UART、SPI) 10-100 µs < 500 条指令
192-255(最低) 低速事件、软件中断 > 100 µs 可稍长,但需避免阻塞

1.4 中断嵌套机制

中断嵌套是指一个 ISR 正在执行时,另一个更高优先级的中断到达,CPU 暂停当前 ISR 转而服务更高优先级中断。VxWorks 通过硬件中断控制器和软件中断屏蔽寄存器共同管理嵌套深度。

中断嵌套执行时序图 时间 → 任务 tShell ISR_LOW (pri=100) ISR_HIGH (pri=50) ISR_LOW 恢复 低优先级中断到达 高优先级中断到达 高优先级ISR完成 嵌套执行流程 1. 任务执行 → 2. 低优先级ISR开始 → 3. 高优先级中断打断 → 4. 高优先级ISR执行完毕 → 5. 恢复低优先级ISR → 6. 返回任务

1.4.1 嵌套深度与堆栈管理

VxWorks 为每个中断级别维护独立的堆栈帧。嵌套深度受限于中断堆栈大小(由 ISR_STACK_SIZE 宏定义)。默认中断堆栈为 4096 字节,深度嵌套时需谨慎评估。

/* 中断堆栈配置示例 */
#define ISR_STACK_SIZE      4096   /* 中断堆栈大小 */
#define MAX_ISR_NEST_DEPTH  8      /* 最大嵌套深度 */

/* 在 BSP 中配置中断堆栈 */
char isrStack[ISR_STACK_SIZE];
SPR(SPR_ISR_STACK_PTR, (int)&isrStack[ISR_STACK_SIZE - 8]);
嵌套风险提示:过深的中断嵌套可能导致堆栈溢出,破坏系统稳定性。建议将嵌套深度控制在 3 层以内,高优先级 ISR 应极短,仅做必要处理(如清除中断标志、发送信号量),将耗时操作推迟到任务级别。

1.5 中断处理流程总结

  1. 中断请求:外设或软件触发中断信号,中断控制器向 CPU 发送 IRQ。
  2. 中断响应:CPU 完成当前指令,保存 PC 和 SR(状态寄存器)到堆栈。
  3. 向量查找:CPU 根据中断号从向量表中获取 ISR 入口地址。
  4. 上下文切换:VxWorks 内核保存被中断任务的上下文(寄存器、栈指针)。
  5. ISR 执行:执行用户注册的中断服务例程,期间中断使能状态由硬件优先级决定。
  6. 中断返回:执行 intRet() 或 rte 指令,恢复上下文,返回被中断点。
VxWorks 中断处理完整流程 外设触发中断 CPU 保存现场 查向量表 执行 ISR 中断返回 恢复现场 返回任务
性能要点:中断延迟 = 中断响应时间 + 向量查找时间 + ISR 执行时间。在 VxWorks 中,中断响应时间通常为 0.5-2 µs(取决于 CPU 频率和缓存状态),向量查找为固定 O(1) 操作。ISR 执行时间由用户代码决定,是优化的主要目标。