当前位置: 首页 > news >正文

驱动开发硬核特训 · Day 17:深入掌握中断机制与驱动开发中的应用实战

🎥 视频教程请关注 B 站:“嵌入式 Jerry”


一、前言

在嵌入式驱动开发中,“中断”几乎无处不在。无论是 GPIO 按键、串口通信、网络设备,还是 SoC 上的各种控制器,中断都扮演着核心触发机制的角色。对中断机制掌握程度的高低,直接影响到你驱动开发水平的深度。

本篇将从以下结构展开:

  • 中断的基本概念与分类
  • Linux 内核中的中断框架
  • request_irq() 的实战用法与原理解析
  • 中断处理函数与上下半部机制
  • 中断在 DTS 中的描述与匹配方式
  • 实战:为一个 GPIO 按键注册中断
  • 调试技巧与常见误区

二、中断基础概念

2.1 什么是中断?

中断(Interrupt)是指处理器在运行过程中,外部设备或内部条件发生特定事件时,打断当前正在执行的任务,转而执行一个中断服务程序(ISR)的机制。

2.2 中断的分类

类型描述
外部中断外设发出的信号,如 GPIO、UART、定时器等
内部中断处理器内部事件触发,如异常、软中断等
边沿触发在电平变化的瞬间触发(如上升沿、下降沿)
电平触发在保持某一电平时持续触发(如高电平、低电平)

三、Linux 内核中的中断机制

Linux 内核为中断提供了统一的框架,通过 IRQ(Interrupt Request)编号管理设备之间的中断。
在这里插入图片描述

3.1 中断号(IRQ number)

每个硬件中断都被映射为一个唯一的 IRQ 号,Linux 内核使用这个编号来注册/处理中断。

可通过如下命令查看系统中断分配:

cat /proc/interrupts

3.2 request_irq() 的框架

int request_irq(unsigned int irq,irq_handler_t handler,unsigned long flags,const char *name,void *dev);
参数含义
irq要申请的中断号
handler中断服务函数
flags触发方式,如 IRQF_TRIGGER_FALLING 等
name中断名称,用于 /proc/interrupts 识别
dev通常为 pdev 或私有结构体指针,用于共享中断区分

四、中断处理函数与上下半部机制

中断处理时间越短越好,因此 Linux 提供 中断上下半部机制

部分描述
上半部(top half)中断刚发生时的 ISR(中断服务函数),需快速返回
下半部(bottom half)通过 tasklet、workqueue 等机制延迟处理

示例:使用 workqueue 实现下半部

static void my_work_handler(struct work_struct *work)
{pr_info("Bottom half executed.\n");
}static DECLARE_WORK(my_work, my_work_handler);static irqreturn_t my_irq_handler(int irq, void *dev)
{schedule_work(&my_work);return IRQ_HANDLED;
}

五、设备树中断描述与解析

5.1 DTS 中的中断定义

button@0 {compatible = "gpio-keys";gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;linux,code = <KEY_ENTER>;label = "Enter Button";interrupt-parent = <&gpio3>;interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
};

5.2 驱动中解析中断号

irq = of_irq_get(np, 0);
ret = request_irq(irq, handler, IRQF_TRIGGER_FALLING, "button", dev);

六、实战讲解:为 GPIO 按键注册中断

以下是一个完整的按键中断驱动代码片段:

static irqreturn_t button_isr(int irq, void *dev_id)
{pr_info("Button interrupt triggered!\n");return IRQ_HANDLED;
}static int btn_probe(struct platform_device *pdev)
{int irq;struct device_node *np = pdev->dev.of_node;irq = of_irq_get(np, 0);if (irq < 0)return irq;return devm_request_irq(&pdev->dev, irq, button_isr,IRQF_TRIGGER_FALLING, "button", NULL);
}

驱动匹配表

static const struct of_device_id btn_of_match[] = {{ .compatible = "myvendor,button" },{ }
};
MODULE_DEVICE_TABLE(of, btn_of_match);

七、调试技巧与排错建议

7.1 无法响应中断?

  • 检查 of_irq_get() 返回值
  • 确保设备树中 interrupt-parent 正确
  • 查看内核是否启用了相应的 GPIO 中断支持
  • 使用 cat /proc/interrupts 观察中断是否触发计数增加

7.2 中断多次触发?

  • 检查 IRQF_TRIGGER_* 设置是否与实际硬件匹配
  • 排查上拉/下拉电阻或信号抖动问题

八、问答环节总结

Q1:一个驱动中能注册多个中断吗?

可以。使用 request_irq() 多次注册不同 irq。

Q2:可以使用中断做耗时操作吗?

不建议。应放入下半部如 workqueue 中。

Q3:中断共享怎么办?

设置 IRQF_SHARED,并正确传入 dev_id 区分中断源。

Q4:中断服务函数可以被抢占吗?

在默认情况下,中断服务函数运行在中断上下文,不能被抢占,但可以被更高优先级中断打断。


九、总结提炼

关键点说明
中断是驱动中的基础机制几乎所有外设都依赖中断响应事件
request_irq() 是核心接口注册中断的入口函数
使用设备树描述中断资源通过 interrupts + interrupt-parent 精确匹配
上下半部机制非常重要把耗时操作放到 workqueue/tasklet
实战中注意调试利用 /proc/interrupts 和日志追踪触发行为

✅ 今日作业建议

  1. 在你的开发板上找一个 GPIO 按键,编写设备树 + 驱动注册中断。
  2. 使用 printk 或 dev_info() 输出中断触发信息,验证中断触发次数。
  3. 尝试通过 workqueue 延迟执行中断下半部逻辑,如点亮 LED。

🎥 视频教程请关注 B 站:“嵌入式 Jerry”


http://www.xdnf.cn/news/84691.html

相关文章:

  • 或者某些 M 理论、Loop Quantum Gravity 的空背景设想
  • 【Java面试笔记:基础】8.对比Vector、ArrayList、LinkedList有何区别?
  • L2-1、打造稳定可控的 AI 输出 —— Prompt 模板与格式控制
  • 局域网内,将linux(Ubuntu)的硬盘映射成Windows上,像本地磁盘一样使用
  • Lua 第8部分 补充知识
  • ProxySQL 读写分离规则配置指南
  • exception:com.alibaba.nacos.api.exception.NacosException: user not found! 解决方法
  • 解决Python与Java交互乱码问题:从编码角度优化数据流
  • 云原生 - Service Mesh
  • 【Linux运维涉及的基础命令与排查方法大全】
  • 位运算练习:起床困难综合征(贪心,位运算)(算法竞赛进阶指南学习笔记)
  • 2025-04-22| Docker: --privileged参数详解
  • 【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读
  • 黑阈免激活版:智能管理后台,优化手机性能
  • vscode flutter 插件, vscode运行安卓项目,.gradle 路径配置
  • 刷刷刷刷刷sql题
  • Oracle在ERP市场击败SAP
  • JVM考古现场(二十四):逆熵者·时间晶体的永恒之战
  • PHP通讯录网站源码无需sql数据库
  • Vue2-指令语法
  • 直播分享|TinyVue 多端实战与轻量图标库分享
  • Linux嵌入式系统SQlite3数据库学习笔记
  • 实验一 进程控制实验
  • 《构建通用学习体系:从底层逻辑到场景应用》
  • Python 基础
  • Trent硬件工程师培训完整135讲
  • Java基础复习(JavaSE进阶)第六章 IO流体系
  • DCDC芯片,boost升压电路设计,MT3608 芯片深度解析:从架构到设计的全维度技术手册
  • 已安装爱思助手和Apple相关驱动,但仍无法有线连接iPhone热点,且网络适配器没有Apple Mobile Device Ethernet,问题解决
  • MySQL索引知识点(笔记)