Linux驱动中断处理与tasklet工程案例 - 第1节
1.1 中断的定义
中断(Interrupt)是嵌入式系统中一种核心的硬件/软件协作机制。它允许外设或软件在需要时异步通知CPU暂停当前任务,转而执行一个预先定义好的处理函数(中断服务例程,ISR),处理完成后再恢复原来的执行流。
核心思想: 中断避免了CPU轮询(Polling)外设状态带来的CPU空转浪费,实现了事件驱动的实时响应。
1.2 中断类型
根据触发源和处理方式,中断主要分为两大类:硬件中断和软件中断。在Linux内核中,两者都通过统一的中断子系统进行管理。
1.2.1 硬件中断 (Hardware Interrupt)
由外部硬件设备(如GPIO按键、UART接收、定时器、DMA控制器)通过芯片的物理中断引脚或内部中断控制器(如GIC、APIC)向CPU发送的电平/边沿信号触发。
- 可屏蔽中断 (Maskable Interrupt): 大多数外设中断,CPU可通过中断屏蔽寄存器暂时忽略。
- 不可屏蔽中断 (Non-Maskable Interrupt, NMI): 用于紧急事件(如看门狗超时、硬件故障),CPU必须立即响应。
- 共享中断 (Shared Interrupt): 多个设备共用同一根中断线,ISR需通过硬件寄存器判断中断来源。
1.2.2 软件中断 (Software Interrupt)
由CPU执行特定指令(如ARM的 SWI、x86的 INT n)主动触发的中断。在Linux中,软件中断主要用于系统调用和下半部机制(如 tasklet、softirq)。
- 系统调用 (System Call): 用户态程序通过软件中断陷入内核态,请求内核服务。
- 异常 (Exception): 由指令执行错误(如除零、缺页)同步触发,属于软件中断的一种特殊形式。
- 软中断 (SoftIRQ) / Tasklet: 内核软件模拟的中断,用于在中断上下文中延迟执行非紧急任务。
| 对比维度 | 硬件中断 | 软件中断 |
|---|---|---|
| 触发源 | 外部硬件设备 | CPU指令执行 |
| 触发方式 | 异步(随机发生) | 同步(可预测) |
| 典型用途 | 外设事件响应 | 系统调用、下半部 |
| 中断号分配 | 由硬件/设备树/ACPI决定 | 由内核软件定义 |
| 可屏蔽性 | 大部分可屏蔽 | 通常不可屏蔽 |
1.3 中断在嵌入式系统中的作用
在资源受限、实时性要求高的嵌入式系统中,中断机制扮演着不可替代的角色。以下是中断在嵌入式系统中的五大核心作用:
- 实时响应 (Real-Time Response): 中断允许CPU在微秒级响应外部事件(如传感器数据就绪、按键按下),满足硬实时系统的时序要求。
- CPU利用率最大化: 避免轮询浪费,CPU在无事件时执行其他任务或进入低功耗模式,仅在中断发生时被唤醒。
- 多任务协作基础: 中断是抢占式调度(Preemptive Scheduling)的底层支撑,高优先级中断可以打断低优先级任务。
- 外设与CPU解耦: 外设通过中断通知CPU,无需CPU主动查询状态,简化了驱动设计并提高了系统吞吐量。
- 电源管理: 中断可作为唤醒源(Wake-up Source),让CPU在空闲时进入深度睡眠,由外设中断唤醒,显著降低功耗。
工程经验: 在嵌入式Linux驱动开发中,中断服务例程(ISR)必须短小精悍。耗时的操作(如数据拷贝、协议解析)应推迟到下半部(Bottom Half)中执行,例如使用
tasklet 或工作队列(Workqueue),以避免阻塞其他中断或导致系统响应延迟。
常见误区: 初学者常将中断服务例程写得过长,甚至在其中调用
printk、kmalloc 等可能引起睡眠的函数。这会导致中断延迟增加、系统锁死或内核恐慌(Kernel Panic)。记住:ISR 中只做最必要的硬件操作,其余工作交给下半部。