1. 中断基础概念
1.1 中断的定义
中断(Interrupt)是一种硬件或软件触发的机制,用于通知处理器发生了需要立即关注的事件。当中断发生时,处理器会暂停当前正在执行的程序,保存现场,然后跳转到一个预先定义好的地址去执行中断服务程序(ISR),处理完后再返回被中断的程序继续执行。
核心特征:中断是异步事件驱动的,处理器不需要主动查询事件是否发生,而是由外设或软件主动通知处理器。
1.2 中断与轮询的对比
轮询(Polling)是另一种处理外设事件的方式,处理器周期性地检查外设的状态寄存器,判断是否有事件需要处理。中断与轮询在实时性、CPU利用率、系统复杂度等方面存在显著差异。
| 对比维度 | 中断(Interrupt) | 轮询(Polling) |
|---|---|---|
| 触发方式 | 事件发生时由外设主动通知 | 处理器主动查询状态 |
| CPU利用率 | 高,无事时CPU可执行其他任务 | 低,即使无事件也消耗CPU周期 |
| 实时性 | 高,事件发生后立即响应 | 低,响应延迟取决于轮询间隔 |
| 系统复杂度 | 较高,需要中断控制器、向量表等 | 较低,只需读取状态寄存器 |
| 适用场景 | 低频或突发性事件(按键、网络包) | 高频且可预测的事件(ADC采样) |
| 功耗 | 低,CPU可进入休眠模式 | 高,CPU持续运行 |
设计建议:在嵌入式系统中,通常将中断用于处理不可预测的异步事件,而将轮询用于处理周期性的、延迟容忍度较高的任务。混合使用两种方式往往能获得最佳效果。
1.3 中断向量表
中断向量表(Interrupt Vector Table, IVT)是存储在内存中的一张表格,每个表项对应一个中断源,存放着该中断对应的中断服务程序(ISR)的入口地址。当处理器接收到中断信号时,通过中断号在向量表中查找对应的ISR地址,然后跳转执行。
ARM架构中的向量表:在ARM Cortex-A系列处理器中,向量表基地址由VBAR(Vector Base Address Register)寄存器控制。每个向量表项占用4字节(32位)或8字节(64位),存放跳转指令或ISR地址。
| 中断号 | 向量表偏移 | 中断类型 | 描述 |
|---|---|---|---|
| 0 | 0x0000 | 复位(Reset) | 系统上电或复位后执行 |
| 1 | 0x0004 | 未定义指令(Undefined Instruction) | 执行未定义的指令码 |
| 2 | 0x0008 | 软件中断(SVC) | 通过SVC指令触发 |
| 3 | 0x000C | 预取中止(Prefetch Abort) | 指令预取时发生错误 |
| 4 | 0x0010 | 数据中止(Data Abort) | 数据访问时发生错误 |
| 5 | 0x0014 | 超中断(Hypervisor) | 虚拟化相关 |
| 6 | 0x0018 | IRQ(普通中断) | 外设中断请求 |
| 7 | 0x001C | FIQ(快速中断) | 高优先级快速中断 |
1.4 中断服务程序(ISR)基本流程
中断服务程序(Interrupt Service Routine, ISR)是响应中断事件时执行的专用函数。ISR的执行流程必须遵循严格的规范,以确保系统稳定性和数据一致性。
ISR 执行的标准步骤
- 保存现场:将当前CPU寄存器(R0-R12、LR、SPSR等)压入栈中保存。
- 识别中断源:读取中断控制器(如GIC)的中断状态寄存器,确定具体是哪个外设触发了中断。
- 清除中断标志:在中断控制器和外设中清除对应的中断挂起位,防止重复触发。
- 执行中断处理:根据中断类型执行对应的处理逻辑(如读取数据、设置状态等)。
- 恢复现场:从栈中恢复之前保存的寄存器值。
- 返回中断:执行中断返回指令(如ARM的MOVS PC, LR),恢复被中断程序的执行。
关键注意事项:
- ISR应尽量短小精悍,避免执行耗时操作(如打印、复杂计算)。
- ISR中禁止调用可能导致阻塞的函数(如信号量等待、内存分配)。
- ISR中访问的共享数据必须使用原子操作或关中断保护。
- 在ARM架构中,ISR入口和出口必须使用特定的指令序列来切换处理器模式。
/* ARM Cortex-A 中断服务程序入口汇编示例 */
IRQ_Handler:
/* 1. 保存现场 */
SUB lr, lr, #4 /* 修正返回地址 */
SRSDB sp!, #0x13 /* 保存SPSR和LR到SVC模式栈 */
CPS #0x13 /* 切换到SVC模式 */
PUSH {r0-r12, lr} /* 保存通用寄存器 */
/* 2. 识别中断源 - 读取GIC中断号 */
MOV r4, #0xFFFFFF00 /* GIC基地址(示例) */
LDR r0, [r4, #0x0C] /* 读取GICC_IAR获取中断ID */
/* 3. 清除中断标志 */
STR r0, [r4, #0x10] /* 写入GICC_EOIR确认中断结束 */
/* 4. 调用C语言ISR处理函数 */
BL C_IRQ_Handler
/* 5. 恢复现场 */
POP {r0-r12, lr} /* 恢复通用寄存器 */
RFEIA sp! /* 恢复SPSR和PC,返回被中断程序 */
ARM架构特殊说明:在ARM Cortex-A系列处理器中,中断响应过程涉及处理器模式的自动切换。当IRQ中断发生时,处理器自动切换到IRQ模式,并保存返回地址到LR_irq、保存CPSR到SPSR_irq。ISR编写者需要特别注意模式切换时的寄存器使用规则。