2. 中断处理流程:中断请求、中断响应、中断服务程序(ISR)执行、中断返回、中断现场保护与恢复

中断处理是操作系统响应异步事件的核心机制。一个完整的中断处理生命周期包含五个紧密衔接的阶段:中断请求、中断响应、中断服务程序(ISR)执行、中断返回,以及贯穿始终的中断现场保护与恢复。理解这一流程是掌握操作系统并发与实时性的基础。

2.1 中断处理五阶段总览

下表概括了每个阶段的核心动作、参与硬件/软件模块以及关键特征:

阶段 核心动作 主要参与者 关键特征
中断请求 外设或软件产生中断信号,发送至中断控制器 外设、GIC(通用中断控制器) 电平触发/边沿触发;可屏蔽/不可屏蔽
中断响应 CPU 保存当前执行现场,查询中断向量,跳转至 ISR 入口 CPU、GIC、中断向量表 硬件自动完成;原子操作
ISR 执行 执行与中断源对应的处理逻辑 CPU、内核中断处理框架 上下文受限;应短小精悍
中断返回 恢复现场,执行中断返回指令,回到被中断点 CPU 恢复 CPSR/PC 等关键寄存器
现场保护与恢复 保存/恢复被中断任务的寄存器、状态字、栈指针 CPU(硬件部分)、ISR 入口/出口代码(软件部分) 贯穿响应与返回阶段
关键概念: 中断现场保护是中断处理正确性的基石。若现场保存不完整,被中断任务恢复后将产生不可预测的行为,导致系统崩溃或数据损坏。

2.2 中断请求(Interrupt Request)

中断请求是中断处理流程的起点。外设通过其中断线向中断控制器(如 ARM GIC)发送请求信号。中断控制器对多个中断源进行优先级仲裁,并将最高优先级的中断转发给 CPU。

  • 中断源类型:
    • 硬件中断: 由外部设备(定时器、网络控制器、磁盘控制器)产生。
    • 软件中断: 由 CPU 执行特定指令(如 ARM 的 SVC、SWI)主动触发,用于系统调用。
  • 触发方式:
    • 电平触发: 中断信号保持有效电平直到被 CPU 响应。
    • 边沿触发: 中断信号在电平跳变(上升沿或下降沿)时被检测。
  • 中断控制器仲裁: GIC 根据中断优先级(Priority)和中断 ID 进行裁决,向 CPU 发送 IRQ 或 FIQ 信号。

2.3 中断响应(Interrupt Response)

CPU 在每条指令执行周期的末尾采样中断请求线。当检测到有效中断且中断使能位(CPSR.I 或 CPSR.F)允许响应时,CPU 硬件自动执行以下原子操作序列:

  1. 保存返回地址: 将当前程序计数器(PC)的值保存到链接寄存器(LR)或专用栈中。
  2. 保存当前状态: 将当前程序状态寄存器(CPSR)保存到备份状态寄存器(SPSR)中。
  3. 切换处理器模式: CPU 切换到中断模式(IRQ 或 FIQ 模式),并禁用同级中断。
  4. 获取中断向量: 从中断向量表中读取对应中断类型的入口地址。
  5. 跳转执行: 将 PC 设置为中断向量地址,开始执行 ISR。
硬件加速: 上述 1-5 步由 CPU 微架构在数个时钟周期内完成,无需软件干预,保证了中断响应的实时性。

2.4 中断服务程序(ISR)执行

ISR 是处理特定中断事件的软件函数。其执行环境与普通任务有显著区别:

  • 上下文受限: ISR 运行在中断上下文中,不可睡眠、不可持有互斥锁、不可进行可能阻塞的系统调用。
  • 执行时间要求: ISR 应尽可能短小,通常只完成必要的数据搬运、状态清除和事件标记,将耗时处理推迟到下半部(Bottom Half)或任务上下文。
  • 中断嵌套: 高优先级中断可以抢占低优先级 ISR 的执行。GIC 通过优先级掩码控制嵌套深度。
/* 典型的 ISR 框架(ARM Cortex-A 系列) */
void irq_handler(void) {
    unsigned int irq_id;
    /* 1. 从 GIC 读取中断 ID */
    irq_id = gic_read_iar();

    /* 2. 根据中断 ID 分发处理 */
    switch (irq_id) {
        case TIMER_IRQ:
            timer_isr();
            break;
        case UART_IRQ:
            uart_isr();
            break;
        default:
            /* 未知中断,错误处理 */
            break;
    }

    /* 3. 向 GIC 发送中断结束信号(EOI) */
    gic_write_eoir(irq_id);
}

2.5 中断返回(Interrupt Return)

ISR 执行完毕后,CPU 执行中断返回指令(ARM 架构中为 SUBS PC, LR, #4 或 MOVS PC, LR),该指令完成以下操作:

  1. 恢复 PC: 从 LR 中取出被中断点的返回地址(需根据流水线调整偏移)。
  2. 恢复 CPSR: 将 SPSR 中的内容复制回 CPSR,恢复被中断时的处理器状态和中断使能位。
  3. 恢复处理器模式: CPU 从中断模式切换回被中断前的模式(用户模式、系统模式等)。

至此,CPU 从被中断的指令处继续执行,仿佛中断从未发生过。

2.6 中断现场保护与恢复

现场保护与恢复是中断处理流程中保证正确性的关键环节,分为硬件自动保护和软件手动保护两部分。

保护层级 保护内容 执行者 说明
硬件自动保护 PC、CPSR → SPSR、LR CPU 微架构 中断响应时自动完成,不可编程
软件手动保护 通用寄存器(R0-R12)、栈指针(SP)、浮点寄存器等 ISR 入口/出口代码 由编译器或汇编编写者显式压栈/出栈
嵌套保护 多层 LR/SPSR 保存 软件 + GIC 硬件 中断嵌套时需手动保存前一层 LR/SPSR
常见错误: 在 ISR 中修改了通用寄存器但未在入口处保存,导致返回后被中断任务使用错误的数据。这是中断处理中最隐蔽的 bug 之一。

2.7 中断处理完整流程示意图

下图展示了从外设请求到中断返回的完整数据流与控制流:

中断处理完整流程图 中断处理完整流程 外设中断源 GIC 中断控制器 CPU 中断响应 硬件现场保护 中断请求 IRQ/FIQ ISR 执行 跳转至 ISR 入口 中断返回指令 硬件现场恢复 被中断任务继续执行 恢复 PC 和 CPSR 说明: 1. 硬件现场保护与恢复由 CPU 在中断响应和返回时自动完成,保存 PC 和 CPSR。 2. 软件现场保护(通用寄存器等)需在 ISR 入口/出口代码中显式处理。 3. GIC 负责中断优先级仲裁和中断 ID 分发,是连接外设与 CPU 的关键桥梁。

2.8 中断现场保护与恢复的软件实现

在 ARM Cortex-A 系列处理器中,ISR 的入口和出口通常由汇编代码编写,以确保现场保护的完整性。以下是一个典型的现场保护与恢复代码片段:

/* ARM 汇编:中断现场保护与恢复 */
irq_entry:
    /* 软件现场保护:压栈被中断任务的通用寄存器 */
    SUB     lr, lr, #4          /* 调整返回地址(ARM 流水线) */
    SRSDB   sp!, #0x12          /* 保存 SPSR 和 LR 到 IRQ 模式栈 */
    CPS     #0x12               /* 切换到 IRQ 模式 */
    PUSH    {r0-r12, lr}        /* 保存通用寄存器 R0-R12 和 LR */

    /* 调用 C 语言 ISR 处理函数 */
    BL      irq_handler

    /* 软件现场恢复:出栈通用寄存器 */
    POP     {r0-r12, lr}        /* 恢复通用寄存器 */
    RFEIA   sp!                 /* 恢复 SPSR 和 PC,完成中断返回 */
设计原则: 现场保护代码必须与被中断任务的上下文严格对称。压栈顺序与出栈顺序相反,确保寄存器值被正确恢复。

2.9 中断处理流程中的关键时序

中断处理的实时性由以下关键时序指标衡量:

  • 中断延迟(Interrupt Latency): 从中断请求信号到达 CPU 到 ISR 第一条指令开始执行的时间间隔。受中断屏蔽、指令执行周期、总线竞争等因素影响。
  • 中断响应时间(Interrupt Response Time): 中断延迟 + ISR 执行时间。
  • 中断嵌套深度: 允许的高优先级中断抢占低优先级 ISR 的层数,受栈空间和 GIC 优先级配置限制。

理解并优化这些时序指标,是嵌入式实时系统设计中的核心挑战。