Linux 中断系统全览解析:从硬件到软件的全路线理解
Linux 中断系统全览解析:从硬件到软件的全路线理解
Linux 中断是进程与硬件进行交互的核心机制之一,在计算机系统中拥有极高的优先级。本文将从硬件启动、设备树描述、内核处理、中断注册、上下文区分等方面全面解析 Linux 中断机制。
一、中断硬件原理
中断硬件通常持有以下元素:
- 中断源:如 GPIO、UART、I2C、Timer 等设备
- 中断控制器:包括 GIC、APIC、PLIC 等
- 向 CPU 通知:硬件产生中断后给予 CPU 一个 IRQ编号
硬件中断可能是线程型触发(上升、下降边缘)或者电平型触发(高、低电平),通过中断控制器编码后通知给 Linux 内核。
二、设备树中断描述
中断的硬件触发方式和配置在设备树中通过 interrupts
和 interrupt-parent
字段表示:
interrupt-parent = <&gpio1>;
interrupts = <14 IRQ_TYPE_EDGE_FALLING>; // GPIO1_14 下降边缘
基于这个配置,内核会通过 of_irq API 解析成实际中断编号,且与该设备对应。
三、Linux 内核中断处理系统结构
主要数据结构
结构 | 作用 |
---|---|
struct irq_desc | 每个中断编号对应一个 descriptor |
struct irq_chip | 控制器相关操作 (mask/unmask/ack) |
struct irqaction | 中断 handler 绑定信息 |
主要函数路径
request_threaded_irq() // 注册中断-> __setup_irq() // 创建 irq_desc, irqaction 等-> irq_startup() // 启用硬件 irq
中断触发时,内核进入:
do_IRQ() → generic_handle_irq() → handle_irq_event()→ handler function (driver 注册的)
四、中断处理方式
Linux 支持两种处理模式:
方式 1:传统 top-half + bottom-half
- Top-half:即被触发中断时首先执行的函数,运行在硬中断上下文,负责简单、快速操作,如释放 spinlock、记录事件、传递数据等。
- Bottom-half:将耗时操作延后,通常通过 softirq、tasklet、workqueue 来实现,允许睡眠、延时执行,可以在进程或内核线程中运行。
方式 2:线程化中断 (Threaded IRQ)
devm_request_threaded_irq(irq, NULL, thread_fn, IRQF_ONESHOT, ...);
- 不使用 top-half,直接通过内核线程执行 thread_fn
- 允许睡眠,适合 I2C 等慢速应答设备
- 常配合
IRQF_ONESHOT
,确保当前线程未处理完成前,不会再次触发中断
五、中断下半段的分类与处理
1. 软中断 (SoftIRQ)
- 最低层、最高优先级的下半段机制
- 在硬中断运行完后、还未返回时执行
- 通常依赖在能够进入内核的进程上,例如 ksoftirqd
- 其中最常用的是
NET_RX_SOFTIRQ
、TIMER_SOFTIRQ
、BLOCK_SOFTIRQ
2. tasklet
- 基于 softirq 实现,但是较高级。
- 同一个 tasklet 无法并行,自带不可重入性
- API 如:
tasklet_schedule()
,tasklet_disable()
3. workqueue
- 最适合长时间操作的下半段
- 允许睡眠,在内核线程中执行
- 可选择使用全局 workqueue ,或者自定义 workqueue
下半段选择指南
场景 | 选择 |
---|---|
需要最小延迟 | softirq |
需要不可并行 | tasklet |
需要睡眠/长时间 | workqueue |
I2C/微线接口 | workqueue / threaded IRQ |
六、中断常用接口 API
注册/取消
int request_irq(unsigned int irq, irq_handler_t handler, ...);
int devm_request_threaded_irq(...);
void free_irq(unsigned int irq, void *dev_id);
操控
void enable_irq(unsigned int irq);
void disable_irq(unsigned int irq);
void irq_set_irq_type(unsigned int irq, unsigned int type);
七、中断标志使用
标志 | 含义 |
---|---|
IRQF_TRIGGER_RISING | 上升边缘触发 |
IRQF_TRIGGER_FALLING | 下降边缘触发 |
IRQF_ONESHOT | 线程化中断时要求处理完成前不再次触发 |
IRQF_SHARED | 允许多设备共享同一中断口 |
IRQF_NO_AUTOEN | 注册后不自动 enable,需手动 enable_irq |
八、总结
Linux 中断系统是硬件和内核互动的基石,通过标准化的接口、动态分配、密切的上下文处理,极大程度地实现了弹性、可靠、可扩展。同时,中断的各级处理机制(top-half, softirq, tasklet, workqueue, threaded irq)结构了一套高效、安全、应对应用场景的处理模型。