以下是关于 Linux 内核中断相关函数 request_irq
、gpio_to_irq
和 free_irq
的对比说明,采用表格形式呈现:
函数名 | request_irq | gpio_to_irq | free_irq |
---|---|---|---|
用途 | 注册中断处理函数 | GPIO 编号转中断号 | 释放已注册的中断 |
核心功能 | 绑定硬件中断与处理程序 | 获取 GPIO 对应的中断号 | 解除中断绑定 |
参数 | unsigned int irq irq_handler_t handler unsigned long flags const char *name void *dev_id | unsigned int gpio | unsigned int irq void *dev_id |
返回值 | 0 (成功)负错误码(失败) | 中断号(成功) 负错误码(失败) | 无(成功) 负错误码(失败) |
使用场景 | 驱动初始化时注册中断 | 需将 GPIO 配置为中断源时 | 驱动卸载时释放中断 |
关键注意事项 | - 需确保中断号有效 - 处理函数需快速执行 - 共享中断需设置 IRQF_SHARED - dev_id 在共享中断时唯一标识设备 | - 需确认 GPIO 支持中断功能 - 需先配置 GPIO 为输入模式 - 返回的 IRQ 号可能因平台不同而变化 | - 必须与 request_irq 配对使用- 共享中断时 dev_id 必须与注册时一致- 避免重复释放 |
典型调用顺序 | 1. gpio_to_irq 获取 IRQ 号2. request_irq 注册处理函数 | 直接调用获取 IRQ 号 | 驱动卸载时调用 |
错误处理 | 检查返回值,处理 -EBUSY (中断已被占用)等错误 | 检查返回值,处理 -EINVAL (无效 GPIO)等错误 | 检查返回值,处理 -EINVAL (无效 IRQ)等错误 |
依赖关系 | 需内核支持中断子系统 | 需内核支持 GPIO 子系统 | 需与 request_irq 配对 |
补充说明
request_irq
标志位(flags
):IRQF_TRIGGER_RISING
(上升沿触发)IRQF_SHARED
(共享中断线)IRQF_NO_SUSPEND
(系统休眠时仍触发)
gpio_to_irq
限制:- 并非所有 GPIO 都支持中断功能,需通过
gpio_is_valid
和gpio_request
验证。 - 某些平台可能要求先配置 GPIO 为中断模式(如
gpio_direction_input
)。
- 并非所有 GPIO 都支持中断功能,需通过
free_irq
注意事项:- 如果使用共享中断(
IRQF_SHARED
),必须传递与注册时相同的dev_id
。 - 释放后需确保不再触发中断,否则可能导致内核崩溃。
- 如果使用共享中断(
示例代码片段
// 1. 获取 GPIO 对应的中断号
int irq = gpio_to_irq(gpio_pin);
if (irq < 0) {
// 处理错误
}
// 2. 注册中断处理函数
int ret = request_irq(irq, irq_handler, IRQF_TRIGGER_RISING, "my_device", dev_id);
if (ret) {
// 处理错误
}
// 3. 释放中断(在驱动卸载时)
free_irq(irq, dev_id);
通过合理使用这三个函数,可以安全地管理 Linux 设备驱动中的中断资源。