1. 中断基础概念
1.1 中断的定义
中断(Interrupt)是一种硬件或软件发出的信号,用于通知处理器发生了需要立即关注的事件。当外设、定时器或其他硬件单元需要CPU的服务时,会通过中断线向中断控制器发送请求,中断控制器再向CPU核发送中断信号。CPU在每条指令执行完毕后检查中断引脚,若检测到有效中断信号,则暂停当前任务,保存上下文,跳转到预先注册的中断服务程序(ISR)执行处理,处理完成后恢复现场并继续执行被中断的任务。
核心要点:中断是一种异步事件处理机制,CPU不需要主动轮询外设状态,而是由外设在需要服务时主动通知CPU。
1.2 中断与轮询的对比
轮询(Polling)是另一种获取外设状态的方式:CPU周期性地读取外设的状态寄存器,检查是否有事件需要处理。中断与轮询在嵌入式系统中各有适用场景,下表从多个维度进行对比:
| 对比维度 | 中断(Interrupt) | 轮询(Polling) |
|---|---|---|
| 触发方式 | 事件驱动,外设主动通知CPU | 时间驱动,CPU主动查询外设 |
| CPU利用率 | 高——CPU只在有事件时响应,空闲时可执行其他任务 | 低——CPU需要不断查询,即使无事件也消耗指令周期 |
| 响应延迟 | 低——事件发生后立即响应(微秒级) | 高——取决于轮询间隔,平均延迟为半个轮询周期 |
| 实现复杂度 | 较高——需要配置中断控制器、注册ISR、处理嵌套和共享 | 较低——只需循环读取状态寄存器 |
| 适用场景 | 低频率但紧急的事件(按键、网络包到达、DMA完成) | 高频率且可预测的事件(ADC连续采样、传感器数据读取) |
| 功耗影响 | 低——CPU可进入休眠,中断唤醒 | 高——CPU持续运行,无法深度睡眠 |
| 可扩展性 | 好——支持多个中断源,优先级管理 | 差——轮询设备增多时CPU负载线性增长 |
工程经验:在嵌入式Linux驱动开发中,中断是首选的事件通知机制。轮询通常仅用于调试阶段、中断不可用的硬件平台,或对延迟不敏感且频率极高的数据采集场景。一个常见的设计模式是:中断负责标记事件发生,而实际的数据处理由底半部(Bottom Half)或工作队列(Workqueue)在更宽松的上下文中完成。
1.3 中断在嵌入式系统中的核心作用
中断是嵌入式系统实时响应能力的基石。没有中断机制,CPU将无法在保证低延迟的同时处理多个外设的并发事件。中断在嵌入式系统中的核心作用体现在以下几个方面:
- 实时响应:中断允许CPU对外部事件做出微秒级响应,满足硬实时系统的时序要求。例如,电机控制中的过流保护必须在数微秒内触发刹车动作。
- 多任务并发:通过中断优先级和嵌套机制,系统可以同时管理多个外设,高优先级中断可以抢占低优先级中断的处理。
- 功耗管理:CPU在无事件时进入WFI(Wait For Interrupt)或深度睡眠模式,中断事件将其唤醒,显著降低系统功耗。
- 数据搬运与DMA协同:中断与DMA(直接存储器访问)配合使用:DMA完成数据块传输后发送中断通知CPU处理,CPU无需参与逐字节搬运。
- 操作系统调度触发:系统定时器(如ARM Generic Timer)产生周期性中断,驱动操作系统的调度器进行任务切换和时间片管理。
1.4 中断子系统在Linux内核中的位置
在嵌入式Linux系统中,中断子系统是内核的核心基础设施之一,与进程调度、内存管理、设备驱动紧密耦合。下图展示了中断子系统在内核中的层次结构:
1.5 中断相关核心术语速查
在进入后续章节之前,先熟悉中断子系统中的关键术语,这些概念将在整个课程中反复出现:
| 术语 | 英文 | 定义 |
|---|---|---|
| 中断请求 | IRQ (Interrupt Request) | 外设向中断控制器发送的硬件信号,请求CPU处理事件 |
| 中断号 | IRQ Number | Linux内核中用于标识每个中断源的软件编号,驱动通过该号注册ISR |
| 硬件中断号 | HW IRQ Number | 中断控制器硬件引脚或中断源ID,与具体SoC绑定 |
| 中断服务程序 | ISR (Interrupt Service Routine) | 中断触发时CPU执行的函数,负责处理中断事件 |
| 中断控制器 | Interrupt Controller | 管理多个中断源的硬件单元,支持优先级、屏蔽、触发方式配置 |
| 中断域 | IRQ Domain | Linux内核中用于将硬件中断号映射到Linux IRQ号的抽象层 |
| 触发方式 | Trigger Type | 中断信号的触发条件:电平触发(Level)或边沿触发(Edge) |
| 底半部 | Bottom Half | 中断处理中非紧急部分的延迟执行机制(Tasklet / Workqueue / Softirq) |
常见误区:初学者容易混淆“硬件中断号”和“Linux IRQ号”。硬件中断号由SoC厂商定义,Linux IRQ号由内核在运行时动态分配或静态映射。驱动开发中,驱动只能使用Linux IRQ号来注册中断处理函数,不能直接操作硬件中断号。中断域(IRQ Domain)负责完成这两者之间的转换。