按键中断,input上报demo
文章目录前言代码前言通过gpio的物理按键中断上报一个input事件代码#includelinux/module.h#includelinux/errno.h#includelinux/miscdevice.h#includelinux/kernel.h#includelinux/major.h#includelinux/mutex.h#includelinux/init.h#includelinux/device.h#includelinux/gpio/consumer.h#includelinux/platform_device.h#includelinux/of_gpio.h#includelinux/of_irq.h#includelinux/interrupt.h#includelinux/irq.h#includelinux/delay.h#includelinux/input.h#includelinux/workqueue.h#defineOWNER_NAMEkk_gpio_key#defineIRQ_NAMEkk_vak/** * 私有数据 */structem_gpio_key{intgpio_pin;//pin脚intgpio_irq;//中断号structworkqueue_struct*work_queue;//工作队列structwork_structwork;//类似标识的东西与key_worker关联起来structinput_dev*input_dev;//input接口};/* 工作处理函数 */staticvoidwork_handler(structwork_struct*work){structem_gpio_key*em_keycontainer_of(work,structem_gpio_key,work);intvalue;printk(%s start \n,__func__);//20ms消抖mdelay(20);valuegpio_get_value(em_key-gpio_pin);printk(%s value %d \n,__func__,value);if(value1){//按键松开input_report_key(em_key-input_dev,KEY_VOICECOMMAND,0);input_sync(em_key-input_dev);}elseif(value0){//按键按下input_report_key(em_key-input_dev,KEY_VOICECOMMAND,1);input_sync(em_key-input_dev);}//重新使能中断enable_irq(em_key-gpio_irq);printk(%s end \n,__func__);}/** * 按键按下触发的中断处理 */staticirqreturn_tgpio_key_isr(intirq,void*data){structem_gpio_key*em_keydata;printk(%s start \n,__func__);//关闭中断防止中断嵌套disable_irq_nosync(em_key-gpio_irq);queue_work(em_key-work_queue,em_key-work);printk(%s end \n,__func__);returnIRQ_HANDLED;}/* * 1.中断申请用于获取中断 * 2.创建工作队列用于处理耗时的操作 * 3.创建input用于上报KEY_VOICECOMMAND按下及抬起 */staticintgpio_key_probe(structplatform_device*pdev){intret;structdevice_node*nodepdev-dev.of_node;structem_gpio_key*em_key;structinput_dev*input_dev;printk(%s start \n,__func__);//给私有数据 分配内存em_keydevm_kzalloc(pdev-dev,sizeof(structem_gpio_key),GFP_KERNEL);if(!em_key){ret-ENOMEM;gotodevm_kzalloc_error;}//获取gpio pin脚em_key-gpio_pinof_get_named_gpio(node,irq-gpio,0);if(!gpio_is_valid(em_key-gpio_pin)){printk(%s gpio_pin:%d is invalid\n,__func__,em_key-gpio_pin);ret-EINVAL;gotoof_error;}/** * 中断创建 *///申请gpio引脚retdevm_gpio_request_one(pdev-dev,em_key-gpio_pin,GPIOF_IN,em_key_irq_gpio);if(ret){printk(%s em_gpio_key.gpio_pin:%d request failed \n,__func__,em_key-gpio_pin);gotorequest_error;}else{printk(%s em_gpio_key.gpio_pin:%d request succeed \n,__func__,em_key-gpio_pin);}//获得gpio中断号em_key-gpio_irqgpio_to_irq(em_key-gpio_pin);if(!em_key-gpio_irq){printk(%s .gpio_pin:%d get irq num:%d failed \n,__func__,em_key-gpio_pin,em_key-gpio_irq);gototo_irq_error;}else{printk(%s .gpio_pin:%d get irq num:%d succeed \n,__func__,em_key-gpio_pin,em_key-gpio_irq);}//根据irq申请中断retdevm_request_threaded_irq(pdev-dev,em_key-gpio_irq,NULL,gpio_key_isr,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_ONESHOT,emdoor-vak,em_key);if(ret0){printk(%s irq num:%d request failed, ret %d \n,__func__,em_key-gpio_irq,ret);gotoirq_error;}//使用工作队列处理中断这里为了及时处理中断单独创建一个em_key-work_queuecreate_workqueue(my_workqueue);if(!em_key-work_queue){printk(KERN_ERR%s Workqueue demo: Failed to create workqueue\n,__func__);return-ENOMEM;}INIT_WORK(em_key-work,work_handler);//把这个数据设置为device的私有数据dev_set_drvdata(pdev-dev,em_key);/** * input创建 */input_devinput_allocate_device();if(!input_dev){printk(%s Failed to allocate memory for input device,__func__);ret-ENOMEM;gotoinput_allocate_error;}input_dev-dev.parentpdev-dev;input_dev-namekk-input;input_dev-id.bustypeBUS_VIRTUAL;__set_bit(EV_SYN,input_dev-evbit);//同步事件__set_bit(EV_KEY,input_dev-evbit);//按键事件__set_bit(EV_REP,input_dev-evbit);//重复事件__set_bit(KEY_VOICECOMMAND,input_dev-keybit);//设置产生哪些按键值retinput_register_device(input_dev);if(ret){printk(%s Input device registration failed,__func__);gotoinput_register_error;}//把这个数据设置为input_dev的私有数据dev_set_drvdata(input_dev-dev,em_key);//将这个input设备接口存起来em_key-input_devinput_dev;enable_irq(em_key-gpio_irq);printk(%s end \n,__func__);return0;input_allocate_error:irq_error:to_irq_error:request_error:of_error:devm_kzalloc_error:returnret;input_register_error:input_free_device(input_dev);input_devNULL;returnret;}staticintgpio_key_remove(structplatform_device*pdev){structem_gpio_key*em_key;intret;//probe中开辟的私有数据内存需要释放em_keydev_get_drvdata(pdev-dev);if(IS_ERR(em_key)){retPTR_ERR(em_key);printk(KERN_ERR %s remove error!\n,__func__);}flush_workqueue(em_key-work_queue);destroy_workqueue(em_key-work_queue);input_unregister_device(em_key-input_dev);input_free_device(em_key-input_dev);input_set_drvdata(em_key-input_dev,NULL);dev_set_drvdata(pdev-dev,NULL);return0;}staticconststructof_device_idgpio_key[]{{.compatiblekk-vak},{},};/* 1. 定义platform_driver */staticstructplatform_drivergpio_keys_driver{.probegpio_key_probe,.removegpio_key_remove,.driver{.nameOWNER_NAME,.of_match_tablegpio_key,},};/* 2. 在入口函数注册platform_driver */staticint__initgpio_key_init(void){interr;printk(%s %s line %d\n,__FILE__,__FUNCTION__,__LINE__);errplatform_driver_register(gpio_keys_driver);returnerr;}/* 3. 有入口函数就应该有出口函数卸载驱动程序时就会去调用这个出口函数 * 卸载platform_driver */staticvoid__exitgpio_key_exit(void){printk(%s %s line %d\n,__FILE__,__FUNCTION__,__LINE__);platform_driver_unregister(gpio_keys_driver);}module_init(gpio_key_init);module_exit(gpio_key_exit);MODULE_LICENSE(GPL);设备树kk_key:kk_key{compatiblekk-vak;statusokay;irq-gpiopio320;};如果没有上拉中断脚会出现不断触发中断的现象需要内部上拉这个中断脚这里是MTK 引脚的配置就不在设备树里做相关的电气属性配置

相关新闻

PCIe寄存器深度解析:从硬件能力到驱动调试的实战指南

PCIe寄存器深度解析:从硬件能力到驱动调试的实战指南

1. 项目概述与核心价值搞硬件驱动或者嵌入式系统开发,尤其是涉及到高速总线通信的,PCIe(Peripheral Component Interconnect Express)绝对是一个绕不开的坎。它早已不是PC主板上那个插显卡的插槽那么简单,在服务器、存…

2026/7/22 15:52:11 阅读更多 →
GitHub热门项目分析方法与技术趋势解读

GitHub热门项目分析方法与技术趋势解读

1. GitHub 热门项目解析方法论作为开发者日常获取技术灵感和工具的重要渠道,GitHub Trending 榜单每周都会涌现出值得关注的新项目。要系统性地分析这些热门项目,我总结了一套行之有效的四步分析法:1.1 数据采集与清洗首先通过 GitHub API 获…

2026/7/22 15:52:11 阅读更多 →
Codebase Memory MCP:AI编程辅助工具中的代码知识图谱技术

Codebase Memory MCP:AI编程辅助工具中的代码知识图谱技术

1. 项目概述:Codebase Memory MCP的革新意义在AI编程辅助工具领域,我们正面临一个关键瓶颈:大模型处理代码库时的token消耗问题。传统方式下,AI代理需要反复读取整个代码文件来理解项目结构,这不仅效率低下&#xff0c…

2026/7/22 15:52:11 阅读更多 →

最新新闻

掌握libcurl:从GET请求到HTTPS验证全解析

掌握libcurl:从GET请求到HTTPS验证全解析

1. 初始化 libcurl 在程序开始时调用一次&#xff1a; #include <stdio.h> #include <curl/curl.h>int main(void) {CURLcode res;res curl_global_init(CURL_GLOBAL_DEFAULT);if (res ! CURLE_OK) {fprintf(stderr, "curl_global_init failed: %s\n",c…

2026/7/22 16:35:43 阅读更多 →
基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

基于二阶锥规划的主动配电网最优潮流求解(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页 &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&#xff1a;行百里者&#xff0c;半于九十。 &#x1f4cb;&#x1f4…

2026/7/22 16:35:43 阅读更多 →
深入解析TI HDVPSS intc_intr1中断控制器:原理、配置与实战优化

深入解析TI HDVPSS intc_intr1中断控制器:原理、配置与实战优化

1. 项目概述在嵌入式视频处理系统的开发中&#xff0c;中断控制器就像是整个系统的“神经中枢”&#xff0c;它负责接收来自各个外设的“紧急呼叫”&#xff0c;并决定是否、以及何时通知CPU这个“大脑”去处理。今天&#xff0c;我们就来深入拆解德州仪器高清视频处理子系统中…

2026/7/22 16:35:43 阅读更多 →
中国电子多项AI创新成果入选国资央企人工智能典型案例

中国电子多项AI创新成果入选国资央企人工智能典型案例

2026世界人工智能大会&#xff08;WAIC&#xff09;期间&#xff0c;国务院国资委在“智赋新质 全域焕新”企业人工智能高质量发展论坛上正式启动“国资央企智能软件工厂联合筑基工程”&#xff0c;包括中国电子在内的首批13家中央企业研发力量参与共建。第二批央企人工智能战略…

2026/7/22 16:35:43 阅读更多 →
LocalAI语音识别教程:在本地设备上部署Whisper模型的完整指南

LocalAI语音识别教程:在本地设备上部署Whisper模型的完整指南

LocalAI语音识别教程&#xff1a;在本地设备上部署Whisper模型的完整指南 【免费下载链接】LocalAI LocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required. 项目地址: https://gitcode.com/GitHub_…

2026/7/22 16:35:43 阅读更多 →
【2027最新】基于SpringBoot+Vue的校园失物招领网站管理系统源码+MyBatis+MySQL

【2027最新】基于SpringBoot+Vue的校园失物招领网站管理系统源码+MyBatis+MySQL

&#x1f4a1;实话实说&#xff1a;有自己的项目库存&#xff0c;不需要找别人拿货再加价&#xff0c;所以能给到超低价格。博主介绍&#xff1a;在校期间积极参与实验室项目研发&#xff0c;现为CSDN特邀作者、掘金优质创作者。专注于Java开发、Spring Boot框架、前后端分离技…

2026/7/22 16:34:42 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统&#xff0c;尤其是像TI C6000系列这样的高性能DSP开发中&#xff0c;我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动&#xff0c;但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案&#xff1f; 在数字化协作环境中&#xff0c;消息通知系统的重要性不言而喻明。但现实情况是&#xff0c;企业级通知方案往往需要复杂的API对接&#xff08;如企业微信、钉钉、飞书&#xff09;&#xff0c;个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点"&#xff0c;乙方听到的是"少做几页"。甲方说"不要太复杂"&#xff0c;乙方理解成"别放图表了"。结果交过去&#xff0c;甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里&#xff0c;是…

2026/7/22 0:00:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中&#xff0c;我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源&#xff0c;还是配置文件、证书等&#xff0c;都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下&#xff0c;但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP&#xff08;轻量级目录访问协议&#xff09;作为企业级身份认证的黄金标准&#xff0c;已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时&#xff0c;发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”&#xff0c;而是以可解释、可审计、可迭代的方式&#xff0c;赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻