欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > linux kernel irq相关函数详解

linux kernel irq相关函数详解

2025/4/21 6:00:42 来源:https://blog.csdn.net/liuluyang530/article/details/147356466  浏览:    关键词:linux kernel irq相关函数详解

在Linux内核驱动开发中,处理中断涉及一系列关键函数,正确使用这些函数对确保驱动的稳定性和性能至关重要。以下是disable_irqfree_irqplatform_get_irqrequest_irq等函数的详细解析,涵盖其功能、用法、注意事项及示例代码。


一、核心函数详解

1. request_irq:注册中断处理程序
  • 功能:申请中断线并绑定中断处理函数。

  • 函数原型

    
    int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev_id);

  • 参数

    • irq:中断号(通过platform_get_irq获取)。

    • handler:中断处理函数(如irq_handler_t类型)。

    • flags:中断标志(如IRQF_SHAREDIRQF_TRIGGER_RISING)。

    • name:中断名称(在/proc/interrupts中显示)。

    • dev_id:设备标识符(用于共享中断时的唯一标识)。

  • 返回值:成功返回0,失败返回错误码。

  • 示例

    
    ret = request_irq(irq_num, my_interrupt_handler, IRQF_SHARED, "my_device", dev);
    if (ret) {pr_err("Failed to request IRQ %d\n", irq_num);return ret;
    }

2. platform_get_irq:获取平台设备中断号
  • 功能:从设备树或平台资源中提取中断号。

  • 函数原型

    
    int platform_get_irq(struct platform_device *dev, unsigned int num);

  • 参数

    • dev:平台设备结构体指针。

    • num:中断资源索引(通常为0,表示第一个中断)。

  • 返回值:成功返回中断号,失败返回负数错误码。

  • 示例

    
    int irq = platform_get_irq(pdev, 0);
    if (irq < 0) {dev_err(&pdev->dev, "Failed to get IRQ\n");return irq;
    }

3. free_irq:释放中断资源
  • 功能:解除中断处理函数并释放中断线。

  • 函数原型

    
    void free_irq(unsigned int irq, void *dev_id);

  • 参数

    • irq:中断号。

    • dev_id:与request_irq时一致的设备标识符。

  • 注意事项

    • 必须在驱动卸载(如remove函数)中调用。

    • 共享中断时,dev_id必须唯一匹配。

  • 示例

    
    free_irq(irq_num, dev);

4. disable_irq 与 enable_irq:禁用/启用中断
  • 功能:临时禁用或重新启用中断线。

  • 函数原型

    
    void disable_irq(unsigned int irq);
    void enable_irq(unsigned int irq);

  • 变体

    • disable_irq_nosync:立即禁用中断,不等待当前处理完成。

    • enable_irq:需与disable_irq成对调用。

  • 注意事项

    • 多次调用disable_irq需对应相同次数的enable_irq

    • 避免在中断上下文中调用disable_irq(可能导致死锁)。

  • 示例

    
    disable_irq(irq_num);
    // 执行关键操作(如修改共享数据)
    enable_irq(irq_num);


二、使用场景与流程

1. 驱动初始化(Probe函数)
  1. 获取中断号:通过platform_get_irq获取硬件中断号。

  2. 注册中断处理程序:调用request_irq绑定处理函数。

  3. 可选配置:设置中断触发方式(如边沿触发)或共享标志。

2. 中断处理函数
  • 典型结构

    
    static irqreturn_t my_interrupt_handler(int irq, void *dev_id) {struct my_device *dev = (struct my_device *)dev_id;// 处理中断逻辑return IRQ_HANDLED;
    }

  • 共享中断:需通过dev_id区分不同设备。

3. 驱动卸载(Remove函数)
  1. 禁用中断:调用disable_irq确保中断不再触发。

  2. 释放中断:通过free_irq解除注册。

  3. 清理资源:释放与dev_id关联的内存。


三、注意事项与最佳实践

1. 内存与资源管理
  • 使用devm_request_irq:自动管理资源,避免free_irq遗漏。

    
    int devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev_id);

  • 错误处理:检查request_irqplatform_get_irq的返回值。

2. 共享中断处理
  • 标志设置:必须使用IRQF_SHARED

  • 唯一dev_id:每个设备需提供唯一的标识符(如设备结构体指针)。

3. 中断禁用与同步
  • 避免长时间禁用:可能导致中断丢失或系统延迟。

  • 自旋锁保护:在中断处理函数中使用自旋锁(spin_lock)保护共享数据。


四、完整示例代码

平台设备驱动示例

#include <linux/interrupt.h>
#include <linux/platform_device.h>struct my_device {struct device *dev;int irq;
};static irqreturn_t my_interrupt_handler(int irq, void *dev_id) {struct my_device *dev = dev_id;// 处理中断return IRQ_HANDLED;
}static int my_probe(struct platform_device *pdev) {struct my_device *dev;int irq, ret;dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);if (!dev) return -ENOMEM;irq = platform_get_irq(pdev, 0);if (irq < 0) return irq;ret = devm_request_irq(&pdev->dev, irq, my_interrupt_handler,IRQF_SHARED, "my_device", dev);if (ret) return ret;dev->irq = irq;platform_set_drvdata(pdev, dev);return 0;
}static int my_remove(struct platform_device *pdev) {struct my_device *dev = platform_get_drvdata(pdev);disable_irq(dev->irq);// free_irq 由 devm_request_irq 自动处理return 0;
}

五、常见问题解答

1. 为何free_irq需要dev_id参数?
  • 唯一标识:确保释放正确的中断处理程序,尤其在共享中断时。

2. disable_irqdisable_irq_nosync的区别?
  • 同步性disable_irq等待当前中断处理完成;disable_irq_nosync立即禁用。

3. 多次调用disable_irq的影响?
  • 计数机制:内核维护禁用计数,需相同次数的enable_irq重新启用中断。


通过合理使用上述函数,开发者能够高效管理中断资源,确保驱动程序的稳定性和响应能力。实际开发中需结合具体硬件和内核版本调整实现细节。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词