1. 中断处理机制基础认知
中断处理是Linux驱动开发中最核心的硬件交互机制之一。当我在早期开发USB设备驱动时,第一次真正理解中断的工作流程后,整个外设控制逻辑突然变得清晰起来。简单来说,中断就是硬件设备向CPU发送的"紧急呼叫"信号,比如网卡收到数据包、键盘检测到按键按下,都需要通过中断机制及时通知CPU处理。
与轮询方式相比,中断机制最大的优势在于资源利用率。我曾做过实验:用轮询方式读取GPIO按键状态,CPU占用率始终维持在90%以上;而改用中断驱动后,空闲状态下CPU占用几乎为零。这种差异在嵌入式设备上尤为明显,直接关系到功耗和性能表现。
现代处理器架构中,中断处理分为两个关键阶段:
- 上半部(Top Half):在中断上下文中立即执行的紧急任务,要求快速响应且不能阻塞。典型操作如读取硬件状态、清除中断标志。
- 下半部(Bottom Half):通过工作队列、tasklet等机制延后处理的非紧急任务,可以执行较复杂的操作。这种分层设计是我在优化触摸屏驱动响应速度时的重要技巧。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 中断注册与处理实现
2.1 中断号获取与注册
在x86体系结构中,我们通常通过PCI配置空间获取中断号。但在ARM平台上,我经常需要查阅芯片手册确定中断映射关系。以GPIO中断为例,最新的内核已经提供了更简洁的注册接口:
c复制int gpiod_to_irq(struct gpio_desc *desc);
但实际开发中我发现,不同芯片厂商的GPIO控制器实现差异很大。在为某款国产芯片移植驱动时,就遇到过硬件中断号与Linux虚拟中断号映射不一致的问题。这时需要仔细检查设备树中的interrupt-parent和interrupts属性配置。
中断注册的核心函数request_irq有几个关键参数需要注意:
c复制int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev);
特别是flags参数,我总结了几种常用组合:
- IRQF_TRIGGER_RISING:上升沿触发,适合按键类设备
- IRQF_TRIGGER_HI
