1. Linux驱动开发中的中断机制解析
在嵌入式系统和设备驱动开发中,中断处理机制是连接硬件与操作系统的关键桥梁。想象一下,当你按下键盘时,CPU不需要持续检查按键状态,而是通过中断机制立即响应——这就是中断的核心价值。
1.1 中断与轮询的本质区别
传统轮询方式就像不断打电话询问快递是否到达,而中断机制则像快递员按门铃通知。从技术实现来看:
c复制// 轮询方式伪代码
while(1) {
if (device_ready) {
process_data();
}
}
这种方式的缺陷显而易见:
- CPU利用率极低(通常<10%)
- 响应延迟不可预测
- 系统功耗居高不下
中断机制的工作流程则完全不同:
- 外设产生中断信号
- 中断控制器汇总信号
- CPU保存当前上下文
- 执行中断服务程序(ISR)
- 恢复被中断的任务
1.2 中断处理的核心指标对比
| 指标 | 轮询方式 | 中断方式 |
|---|---|---|
| CPU利用率 | <10% | >90% |
| 响应延迟 | 毫秒级 | 微秒级 |
| 系统功耗 | 高 | 低 |
| 适用场景 | 简单低速设备 | 复杂高速设备 |
实际项目中,我曾遇到一个案例:改用中断方式处理传感器数据后,系统整体功耗降低了63%,这充分证明了中断机制的价值。
2. 中断处理程序开发实战
2.1 中断注册与处理框架
Linux内核提供了完善的中断处理API,核心函数是request_irq():
c复制#include <linux/interrupt.h>
// 典型中断处理函数原型
irqreturn_t my_handler(int irq, void *dev_id) {
/* 处理逻辑 */
return IRQ_HANDLED;
}
// 注册中断
int request_irq(unsigned int irq,
irq_handler_t handler,
unsigned long flags,
const char *name,
void *dev_id);
关键参数说明:
flags:定义中断触发方式IRQF_TRIGGER_RISING:上升沿触发IRQF_TRIGGER_FALLING:下降沿触发IRQF_SHARED:共享中断
2.2 GPIO中断完整示例
以下是基于树莓派GPIO中断的完整驱动示例:
c复制#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#define GPIO_IRQ_PIN 17
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) {
int val = gpio_get_value(GPIO_IRQ_PIN);
printk("GPIO %d state: %d\n", GPIO_IRQ_PIN, val);
return IRQ_HANDLED;
}
static int __init my_init(void) {
int ret, irq;
// GPIO配置
if ((ret = gpio_request(GPIO_IRQ_PIN, "my_irq_gpio"))) {
pr_err("GPIO request failed\n");
return ret;
