linux kernel irq相关函数详解

news2025/4/21 2:58:27

在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重新启用中断。


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI调试工具有哪些?

一、深度学习框架专用调试工具 TensorBoard • 功能&#xff1a;实时监控训练指标&#xff08;损失值、准确率&#xff09;、可视化神经网络结构、分析参数分布和梯度信息 • 适用框架&#xff1a;TensorFlow、PyTorch&#xff08;通过插件&#xff09; • 特点&#xff1a;支持…

交易模式革新:Eagle Trader APP上线,助力自营交易考试效率提升

近年来&#xff0c;金融行业随着投资者需求的日益多样化&#xff0c;衍生出了众多不同的交易方式。例如&#xff0c;为了帮助新手小白建立交易基础&#xff0c;诞生了各类跟单社区&#xff1b;而与此同时&#xff0c;一种备受瞩目的交易方式 —— 自营交易模式&#xff0c;正吸…

健身会员管理系统(ssh+jsp+mysql8.x)含运行文档

健身会员管理系统(sshjspmysql8.x) 对健身房的健身器材、会员、教练、办卡、会员健身情况进行管理&#xff0c;可根据会员号或器材进行搜索&#xff0c;查看会员健身情况或器材使用情况。

捋一遍Leetcode【hot100】的二叉树专题

二叉树专题 除了后面两个&#xff0c;都挺简单 二叉树的中序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int …

【测试文档】项目测试文档,测试管理规程,测试计划,测试文档模版,软件测试报告书(Word)

原件获取列表&#xff1a; 系统测试方案-2.docx B-Web安全服务渗透测试模板.docx 压力测试报告.docx安全测试用例及解析.docx 测试计划.doc 测试需求规范.doc 测试需求指南.docx 测试用例设计白皮.doc 单元测试报告模板.doc 单元测试计划模板.doc 回归测试指南.doc 集成测试报…

Linux的联网网络管理攻略

RHEL9版本特点 在RHEL7版本中&#xff0c;同时支持network.service和NetworkManager.service&#xff08;简称NM&#xff09;。 在RHEL8上默认只能通过NM进行网络配置&#xff0c;包括动态ip和静态ip,若不开启NM&#xff0c;否则无法使用网络RHEL8依然支持network.service&am…

Linux上位机开发实践(SoC和MCU的差异)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 soc一般是指跑linux的芯片&#xff0c;而mcu默认是跑rtos的芯片&#xff0c;两者在基本原理方面其实差异不大。只不过&#xff0c;前者由于性能的原…

ios app的ipa文件提交最简单的方法

ipa文件是ios的app打包后生成的二级制文件&#xff0c;在上架app store connect或做testflight测试的时候&#xff0c;它提示我们需要使用xcode、transporter或xcode命令行等方式来上传。 而xcode、transporter或xcode命令行的安装都需要使用mac电脑&#xff0c;假如没有mac电…

详细解释浏览器是如何渲染页面的?

渲染流程概述 渲染的目标&#xff1a;将HTML文本转化为可以看到的像素点 当浏览器的网络线程收到 HTML 文档后&#xff0c;会产生一个渲染任务&#xff0c;并将其传递给渲染主线程的消息队列。在事件循环机制的作用下&#xff0c;渲染主线程取出消息队列中的渲染任务&#xff0…

Nacos安装及数据持久化

1.Nacos安装及数据持久化 1.1下载nacos 下载地址&#xff1a;https://nacos.io/download/nacos-server/ 不用安装&#xff0c;直接解压缩即可。 1.2配置文件增加jdk环境和修改单机启动standalone 找到bin目录下的startup.cmd文件&#xff0c;添加以下语句(jdk路径根据自己…

FPGA_YOLO(四)用HLS实现循环展开以及存储模块

Vivado HLS&#xff08;High-Level Synthesis&#xff0c;高层次综合&#xff09;是赛灵思&#xff08;Xilinx&#xff09;在其 Vivado 设计套件 中提供的一款工具&#xff0c;用于将 高级编程语言&#xff08;如 C、C、SystemC&#xff09; 直接转换为 硬件描述语言&#xff0…

ASP.NET MVC 实现增删改查(CRUD)操作的完整示例

提供一个完整的 ASP.NET MVC 实现增删改查&#xff08;CRUD&#xff09;操作的示例。该示例使用 SQL Server 数据库&#xff0c;以一个简单的 Product 实体为例。 步骤 1&#xff1a;创建 ASP.NET MVC 项目 首先&#xff0c;在 Visual Studio 中创建一个新的 ASP.NET MVC 项目…

MCP理解笔记及deepseek使用MCP案例介绍

文章目录 一、MCP介绍&#xff08;1&#xff09;使用MCP与之前的AI比较&#xff08;2&#xff09;原理&#xff08;3&#xff09;优点 二、deepseek使用MCP使用案例介绍 一、MCP介绍 全称 模型上下文协议 来源 由Claude母公司Anthropic于24年底开源发布 简介 AI大模型的标准化…

# 手写数字识别:使用PyTorch构建MNIST分类器

手写数字识别&#xff1a;使用PyTorch构建MNIST分类器 在这篇文章中&#xff0c;我将引导你通过使用PyTorch框架构建一个简单的神经网络模型&#xff0c;用于识别MNIST数据集中的手写数字。MNIST数据集是一个经典的机器学习数据集&#xff0c;包含了60,000张训练图像和10,000张…

LeetCode:DFS综合练习

简单 1863. 找出所有子集的异或总和再求和 一个数组的 异或总和 定义为数组中所有元素按位 XOR 的结果&#xff1b;如果数组为 空 &#xff0c;则异或总和为 0 。 例如&#xff0c;数组 [2,5,6] 的 异或总和 为 2 XOR 5 XOR 6 1 。 给你一个数组 nums &#xff0c;请你求出 n…

Perf学习

重要的能解决的问题是这些&#xff1a; perf_events is an event-oriented observability tool, which can help you solve advanced performance and troubleshooting functions. Questions that can be answered include: Why is the kernel on-CPU so much? What code-pa…

齐次坐标变换+Unity矩阵变换

矩阵变换 变换&#xff08;transform)&#xff1a;指的是我们把一些数据&#xff0c;如点&#xff0c;方向向量甚至是颜色&#xff0c;通过某种方式&#xff08;矩阵运算&#xff09;&#xff0c;进行转换的过程。 变换类型 线性变换&#xff1a;保留矢量加和标量乘的计算 f(x)…

Pandas取代Excel?

有人在知乎上提问&#xff1a;为什么大公司不用pandas取代excel&#xff1f; 而且列出了几个理由&#xff1a;Pandas功能比Excel强大&#xff0c;运行速度更快&#xff0c;Excel除了简单和可视化界面外&#xff0c;没有其他更多的优势。 有个可怕的现实是&#xff0c;对比Exce…

启动vite项目报Unexpected “\x88“ in JSON

启动vite项目报Unexpected “\x88” in JSON 通常是文件被防火墙加密需要寻找运维解决 重启重装npm install

HTTP测试智能化升级:动态变量管理实战与效能跃迁

在Web应用、API接口测试等领域&#xff0c;测试场景的动态性和复杂性对测试数据的灵活管理提出了极高要求。传统的静态测试数据难以满足多用户并发、参数化请求及响应内容验证等需求。例如&#xff0c;在电商系统性能测试中&#xff0c;若无法动态生成用户ID、订单号或实时提取…