4. 中断服务程序设计与实时性分析

中断服务程序(ISR)是航电计算平台中连接硬件事件与实时任务的桥梁。ISR 写得好不好,直接决定系统能否在确定的时间内响应外部事件。本节围绕 ISR 编写规范、中断延迟、中断抖动、响应时间测量与优化方法展开,重点说明“怎么写、延迟从哪来、抖动怎么控、时间怎么测、性能怎么优化”。

一、ISR 编写规范

航电平台的 ISR 必须遵循“短、快、确定”的原则。ISR 只做最紧急、最必要的工作,把耗时处理交给任务或下半部。典型规范包括:

  • 禁止阻塞:ISR 中不得调用可能睡眠、等待信号量或动态分配内存的函数。
  • 禁止浮点与长除法:除非硬件支持上下文快速保存,否则应避免在 ISR 中使用浮点运算。
  • 共享数据保护:ISR 与任务共享的变量必须使用原子访问或关中断保护,避免竞态。
  • 可重入与优先级:明确 ISR 是否允许嵌套,并配置中断优先级,防止高优先级中断被低优先级长时间阻塞。
  • 清中断标志:在退出前必须清除外设中断标志,否则会反复进入 ISR。

下面给出一个典型的 ISR 骨架示例(以航电总线接收中断为例):

void ARINC429_Rx_ISR(void)
{
    uint32_t status = REG_READ(ARINC429_STATUS);
    if (status & RX_FIFO_NOT_EMPTY) {
        uint32_t word = REG_READ(ARINC429_RX_FIFO);
        /* 仅做入队,不做解析 */
        if (!ringbuf_push(&rx_ring, word)) {
            rx_overflow_cnt++;
        }
    }
    REG_WRITE(ARINC429_STATUS, status); /* 清中断标志 */
}

该 ISR 只完成“读 FIFO、入环形缓冲、清标志”三件事,解析、校验和协议处理全部交给任务,从而把 ISR 执行时间压缩到微秒级。

二、中断延迟与中断抖动

中断延迟是指从中断请求信号有效到 ISR 第一条指令执行之间的时间。它通常由四部分组成:

  1. 硬件传播延迟:中断控制器采样、仲裁和向量分发的时间。
  2. 关中断窗口:CPU 或系统在临界区关闭中断的时间。
  3. 当前指令完成时间:CPU 必须执行完当前指令才能响应中断。
  4. 上下文保存时间:压栈、保存寄存器、跳转到 ISR 的时间。

中断抖动则是多次中断延迟之间的波动量。抖动越小,实时性越确定。抖动的主要来源包括:关中断时间不一致、Cache 命中率变化、总线争用、DMA 抢占以及中断嵌套。对于航电系统,通常要求关键中断的抖动控制在几微秒以内。

中断延迟与抖动的时间构成 中断请求 硬件传播 关中断窗口 指令完成 上下文保存 ISR 执行 中断延迟 = 硬件传播 + 关中断 + 指令完成 + 上下文保存 抖动来源: ① 关中断时间不一致 ② Cache 命中率变化 ③ 总线/DMA 争用 ④ 中断嵌套 ⑤ 优先级反转 抖动 = 最大延迟 − 最小延迟,航电关键中断通常要求抖动 ≤ 5 μs 优化方向: 缩短关中断窗口 · 提高 ISR 优先级 · 使用向量中断 · 锁定关键代码到 Cache · 减少 ISR 内分支与循环 将非紧急处理下移到任务 · 使用 DMA 减少 CPU 搬运 · 固定中断响应路径

三、中断响应时间测量方法

测量中断响应时间最直接的方法是用示波器或逻辑分析仪同时观察“中断请求信号”和“ISR 中翻转的 GPIO”。具体做法是:在 ISR 入口翻转一个空闲 GPIO,在中断源产生时也翻转另一个 GPIO,两者之间的时间差即为中断延迟。若需要测量抖动,可连续触发多次,统计最大与最小延迟。

在没有外部仪器的条件下,也可以使用 CPU 的高精度定时器(如 ARM 的 DWT CYCCNT)进行测量:在中断请求发出前读取计数器,在 ISR 入口再次读取,两者之差除以主频即为延迟。示例代码如下:

/* 中断触发前 */
uint32_t t0 = DWT->CYCCNT;
trigger_irq();

/* ISR 入口 */
void ISR_Handler(void)
{
    uint32_t t1 = DWT->CYCCNT;
    uint32_t latency_cycles = t1 - t0;
    /* latency_us = latency_cycles / CPU_MHz */
}

需要注意的是,这种方法测量的是“软件可见延迟”,不包含硬件传播和中断控制器仲裁时间,适合用于比较不同配置下的相对变化。

四、优化方法与工程判断

优化中断实时性,核心是“减少不确定因素”。常用手段包括:

  • 缩短关中断窗口:把长临界区拆分为多个短临界区,或改用原子操作。
  • 提高关键中断优先级:确保航电总线接收、故障告警等中断不被低优先级中断阻塞。
  • 使用向量中断:避免软件查询中断源带来的额外延迟。
  • 锁定关键代码到 Cache:减少取指抖动。
  • ISR 只做入队:把协议解析、校验、日志等放到任务中。
  • 使用 DMA:减少 CPU 搬运数据的时间。

在实际工程中,建议先测量基线延迟和抖动,再逐项优化并复测。例如某航电平台在优化前测得某总线中断延迟为 8~15 μs,抖动 7 μs;通过缩短关中断窗口、提高中断优先级、将 ISR 内解析下移后,延迟降至 3~5 μs,抖动降至 2 μs 以内,满足系统 10 μs 的实时性要求。该数据为教学示例,实际数值需以具体平台实测为准。

工程提示:中断延迟和抖动是“设计出来的”,不是“调出来的”。在架构阶段就应明确关键中断的优先级、关中断策略和 ISR 职责边界,避免后期反复修改。
常见误区:在 ISR 中调用 printf、malloc 或等待信号量,会引入不可预测的延迟和抖动,严重时导致系统崩溃。航电 ISR 必须保持无阻塞、无动态分配、无长循环。

总结来说,ISR 编写规范决定了延迟的下限,中断延迟和抖动分析决定了实时性的确定性,测量方法提供了验证手段,优化方法则是在确定性与资源之间做权衡。掌握这四者之间的关系,才能在航电计算平台上设计出既快又稳的中断响应机制。