news 2026/4/16 9:17:08

Linux 中断驱动程序--按键中断驱动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 中断驱动程序--按键中断驱动

一、为什么需要中断驱动?

在嵌入式 Linux 开发中,按键是最常见的输入设备之一。如果使用轮询(Polling)方式检测按键状态,CPU 需要不停地读取 GPIO 电平,这会极大地浪费系统资源,导致 CPU 无法处理其他任务。
中断(Interrupt)机制则是解决这一问题的完美方案:

  • 被动响应:CPU 仅在按键按下(或抬起)时才收到通知并进行处理。
  • 高实时性:硬件电平变化触发中断,系统能立即响应。
  • 低功耗:CPU 大部分时间处于空闲或处理其他任务的状态,无需忙等。

二、驱动核心结构

1.代码结构分析

  • 内核驱动 :负责 GPIO 初始化、中断申请、数据读取逻辑。
  • 应用测试 :负责打开设备节点并调用 read() 函数获取按键状态。
  • 设备树节点:描述硬件资源(GPIO 编号、中断触发方式)。

2. 工作流程图

  1. 初始化:驱动加载,解析设备树,申请 GPIO 和中断。
  2. 阻塞等待:用户程序调用 read(),驱动将其加入等待队列并休眠。
  3. 中断触发:按键按下,硬件产生中断,执行中断处理函数。
  4. 唤醒进程:中断处理函数唤醒等待队列中的进程,read() 返回按键值。

三、代码实现详解

1.中断处理函数 (key_irq_handler)
static irqreturn_t key_irq_handler(int irq, void * dev) { int arg = *(int *)dev; // 获取传入的参数 if(100 != arg) return IRQ_NONE; // 简单的参数校验 condition = 1; // 核心逻辑:设置条件为真 wake_up_interruptible(&wq); // 唤醒在 wq 队列上睡眠的进程 printk("irq = %d dev = %d\n", irq, arg); return IRQ_HANDLED; }
  • 中断上下文原则:ISR 必须快速执行。它只做最必要的事情——设置标志位和唤醒进程,避免任何可能引起休眠的操作(如copy_to_user)。
  • 唤醒机制wake_up_interruptible是与wait_event_interruptible完美配对的函数,它能将处于可中断睡眠状态的进程标记为可运行,由调度器决定何时恢复其执行。
2.. 文件操作:读取函数 (read)

这是驱动与应用交互的接口。

static ssize_t read(struct file * file, char __user * buf, size_t size, loff_t * loff) { int ret = 0; int status = 0; condition = 0; // 1. 重置条件标志 wait_event_interruptible(wq, condition); // 2. 进程在此处睡眠,直到 condition != 0 status = 1; // 3. 被唤醒后执行 ret = copy_to_user(buf, &status, sizeof(status)); // 4. 将数据传回用户空间 return sizeof(status); }
  • 阻塞式设计:wait_event_interruptible 宏实现了优雅的阻塞逻辑。当条件不满足时,进程主动让出 CPU;一旦被唤醒,它会自动重新检查条件并继续执行。
  • 2. 用户/内核空间隔离:必须使用 copy_to_user 将内核数据安全地拷贝到用户空间缓冲区,直接赋值会导致内核崩溃(Oops)。
3.平台驱动探针 (probe)
static int probe(struct platform_device * pdev) { // 1. 查找设备树节点 pdts = of_find_node_by_path("/ptkey"); // 2. 获取 GPIO 和 中断号 key_gpio = of_get_named_gpio(pdts, "ptkey-gpio", 0); key_irq = irq_of_parse_and_map(pdts, 0); // 3. 申请中断 request_irq(key_irq, key_irq_handler, IRQF_TRIGGER_FALLING, "key0_irq", &arg); // 4. 初始化等待队列 init_waitqueue_head(&wq); return 0; }
  • 设备树驱动模型:通过 of_find_node_by_path 和 of_get_named_gpio 等 API,驱动代码与具体的硬件地址解耦,使得同一份驱动可以适配不同的硬件平台。
  • 资源生命周期管理:在 probe 中申请的资源(GPIO、IRQ),必须在对应的 remove 函数中正确释放,否则会造成资源泄漏。
4.模块初始化与退出
static int __init key_driver_init(void) { platform_driver_register(&pdrv); // 注册平台驱动 } static void __exit key_driver_exit(void) { platform_driver_unregister(&pdrv); // 注销平台驱动 }
  • 模块入口/出口:__init 和 __exit 宏告诉内核这些函数只在模块加载/卸载时使用,之后其占用的内存可以被回收,优化了内核内存。
  • 平台总线注册:通过 platform_driver_register 将驱动注册到 Linux 的 Platform 总线上,使其能够被设备树中的匹配节点发现并调用 probe。

四、应用测试:key_app.c

1.主函数逻辑
int main(int argc, const char *argv[]) { int fd = open("/dev/key", O_RDWR); // 打开设备节点 int status = 0; while(1) { int ret = read(fd, &status, sizeof status); // 调用驱动的 read 函数 printf("ret = %d status = %d\n", ret, status); } close(fd); return 0; }
  • 标准文件操作:应用程序完全将设备视为一个普通文件,通过 open、read、close 这些 POSIX 标准接口进行交互,体现了 Linux “一切皆文件” 的设计哲学。
  • 同步阻塞行为:read 调用在此处是同步且阻塞的。程序会一直停在此行,直到内核驱动有数据返回(即按键被按下),这简化了应用层的逻辑,无需自行管理轮询或异步通知。

五、 关键技术点总结

  1. 非轮询机制:相比传统的 while 循环读取 GPIO 电平,这种 中断 + 等待队列 的方式更加高效,不占用 CPU 资源。
  2. 设备树解耦:驱动代码不包含具体的硬件地址,而是通过设备树节点(/ptkey)动态获取 GPIO 和 IRQ,提高了驱动的通用性。
  3. 阻塞 I/O:wait_event_interruptible 和 wake_up_interruptible 是成对使用的宏/函数,是实现阻塞型驱动的标准范式。
  4. 参数传递:代码中使用 &arg 作为中断共享参数,虽然本例中仅用于演示,但在多设备驱动中,通常会传递指向设备私有数据结构(struct key_dev)的指针。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/9 16:33:38

国内进口的车膜品牌推荐几家

开篇:定下基调随着国内汽车消费升级,进口车膜凭借成熟的技术工艺与稳定的品质表现,成为众多车主提升车辆防护与驾乘体验的首选。但市场上品牌繁杂、优劣难辨,给车主带来了选择困境。本次测评针对国内主流进口车膜品牌展开专业对比…

作者头像 李华
网站建设 2026/4/13 14:23:38

MathCAD许可证与其他软件集成

在科研、教育和工程领域,MathCAD作为一款卓越的数学计算和工程设计软件,经常需要与其他软件协同工作。然而,许可证管理在不同软件之间的集成可能会成为一个挑战。本文将探讨MathCAD许可证与其他软件集成的问题,并介绍如何实现无缝…

作者头像 李华
网站建设 2026/4/1 12:16:17

软考一次过的概率大吗?看完通过率分析,你就明白了!

软考因其报名条件宽松、高级也以考代评等优点,每年吸引近百万人报名参加。 有些第一次来考的考生,因为急着拿证,所以想知道软考一次过的概率有多大。 这篇文章,小希将通过分析软考的通过率来为大家解答这个问题。 一、软考整体…

作者头像 李华
网站建设 2026/4/14 13:34:19

决胜国自然:专业PPT与配图,如何为您的申报“画龙点睛”

国家自然科学基金会议评审是项目申请能否获批的关键环节。在这一阶段,高质量的PPT不仅是项目科学价值和创新性的“放大器”,更是研究团队学术水准、严谨态度与协同能力的“立体名片”。许多科研人员面临一个共同困境:掌握了前沿的科学思想和扎…

作者头像 李华
网站建设 2026/4/12 22:25:09

2026国自然模板大改,无从下笔?

作为常年参与国自然申报工作的科研人员,今年基金委发布2026国自然申请书改版通知后,我感受到了明显的调整压力。往年可按固定模块填空完成的申请书,今年被砍掉了所有固定章节,仅保留立项依据、研究内容、研究基础三大核心板块&…

作者头像 李华
网站建设 2026/4/9 16:24:41

java对象排序

在 Java 中,对象排序主要通过两种接口实现:自然排序(Comparable) 和 定制排序(Comparator)。它们分别适用于不同的场景,下面详细对比和说明。 自然排序:java.lang.Comparable定制排序…

作者头像 李华