DRV_05_GPIO按键驱动分析与使用
发布时间 - 2025-06-27 00:00:00 点击率:次资料下载
由于无法通过浏览器直接访问,需要使用Git工具进行下载:
git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
您可以观看百问网的驱动大全视频,以获取更多相关信息。
GPIO按键驱动分析与使用参考资料:
Linux 5.x内核 Documentation\devicetree\bindings\input\gpio-keys.txt drivers\input\keyboard\gpio_keys.c Linux 4.x内核 Documentation\devicetree\bindings\input\gpio-keys.txt drivers\input\keyboard\gpio_keys.c
设备树示例:
IMX6ULL:Linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull-14x14.dts
STM32MP157:Linux-5.4/arch/arm/boot/dts/stm32mp15xx-100ask.dtsi
QEMU:linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull_qemu.dts
- 驱动程序框架
- 设备树示例
2.1 设备树讲解属性:
必备:compatible = "gpio-keys";
可选:autorepeat:表示自动重复,按下按键不松开,驱动会自动重复上报按键值
对于每一个GPIO按键,都是一个子节点,有这些属性:
gpios:使用哪个GPIO
interrupts:对应的中断
linux,code:对应的按键值
注意:gpios和interrupts至少要保留一个,不能都省略
debounce-interval:消除抖动的间隔,单位:ms,默认是5ms
2.2 100ASK_IMX6ULL
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
user1 {
label = "User1 Button";
gpios = ;
gpio-key,wakeup;
linux,code = ;
};
user2 {
label = "User2 Button";
gpios = ;
gpio-key,wakeup;
linux,code = ;
};
}; 2.3 100ASK_STM32MP157
joystick {
compatible = "gpio-keys";
#size-cells = ;
button-0 {
label = "usr_button0";
linux,code = ;
interrupt-parent = ;
interrupts = ;
};
button-1 {
label = "usr_button1";
linux,code = ;
interrupt-parent = ;
interrupts = ;
};
}; 2.4 QEMU
gpio-keys@0 {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = ;
status = "okay";
Key0 {
label = "Key 0";
gpios = ;
linux,code = ;
};
};
gpio-keys@1 {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = ;
status = "okay";
Key0 {
label = "Key 1";
gpios = ;
linux,code = ;
};
}; - gpio_keys.c驱动程序分析
3.1 套路
根据设备树获得硬件信息:哪个GPIO、对于什么按键分配/设置/注册input_dev结构体
request_irq:在中断处理函数中确定按键值、上报按键值
有两种IRQ函数
gpio_keys_gpio_isr:设备
树中的用gpios来描述用到的引脚
gpio_keys_irq_isr:设备树中的用interrupts来描述用到的引脚
3.2 gpio_keys_gpio_isr分析
理想状况是:按下、松开按键,各产生一次中断,也只产生一次中断。 但是对于机械开关,它的金属弹片会反复震动。GPIO电平会反复变化,最后才稳定。一般是几十毫秒才会稳定。 如果不处理抖动的话,用户只操作一次按键,会发生多次中断,驱动程序可能会上报多个数据。
怎么处理按键抖动?
在按键中断程序中,可以循环判断几十亳秒,发现电平稳定之后再上报 使用定时器 显然第1种方法太耗时,违背“中断要尽快处理”的原则,你的系统会很卡。
怎么使用定时器?看下图:
核心在于:在GPIO中断中并不立刻记录按键值,而是修改定时器超时时间,10ms后再处理。 如果10ms内又发生了GPIO中断,那就认为是抖动,这时再次修改超时时间为10ms。 只有10ms之内再无GPIO中断发生,那么定时器的函数才会被调用。 在定时器函数中上报按键值。
3.3 gpio_keys_irq_isr分析
有个变量key_pressed,用来表示当前按键状态:初始值是false,表示按键没有被按下。
发生中断
上报"按下的值":input_event(input, EV_KEY, button->code, 1); input_sync(input);
如果不延迟(!bdata->release_delay)
马上上报"松开的值":input_event(input, EV_KEY, button->code, 0); input_sync(input);
如果延迟(bdata->release_delay)
启动定时器,过若干毫秒再上报"松开的值"
所以,使用gpio_keys_irq_isr时,一次中断就会导致上报2个事件:按下、松开
缺点:无法准确判断一个按键确实已经被松开了
- QEMU上机实验
IMX6ULL、STM32MP157的出厂系统都已经配置的GPIO按键。 可以执行以下命令确认设备节点:
cat /proc/bus/input/devices
然后执行hexdump /dev/input/event?(?表示某个数值),并且操作按键来观察输出信息。
也可以在QEMU上做实验:原理图如下:
4.1 设置工具链
在Ubuntu中执行:
export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
4.2 配置内核
QEMU的内核里已经配置了GPIO按键的设备树,只需要编译出gpio_keys驱动程序即可。
配置内核:执行make menuconfig
-> Device Drivers
-> Input device support
-> Generic input layer
-> Keyboards
GPIO Buttons 4.3 编译驱动
book@100ask:~/100ask_imx6ull-qemu$ cd linux-4.9.88 book@100ask:~/100ask_imx6ull-qemu/linux-4.9.88$ make modules
成功的话,可以得到:
drivers/input/keyboard/gpio_keys.ko
复制到如下目录:
$ cp drivers/input/keyboard/gpio_keys.ko ~/nfs_rootfs/
4.4 启动QEMU
在Ubuntu中执行:
$ cd ubuntu-18.04_imx6ul_qemu_system $ ./qemu-imx6ull-gui.sh
4.5 挂载NFS、实验
在QEMU中执行:
$ mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt $ insmod /mnt/gpio_keys.ko $ cat /proc/bus/input/devices // 确认设备节点 $ hexdump /dev/input/event3
在QEMU的GUI界面操作:
# 虚拟化
# linux
# git
# 浏览器
# 工具
# ai
# 结构体
# 循环
# Event
# 事件
# input
# ubuntu
# 按下
# 才会
# 再上
# 都是
# 引脚
# 就会
# 有个
# 那就
# 多个
# 您可以
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何配置Horizon来管理队列?(安装和使用)
如何在阿里云域名上完成建站全流程?
js实现点击每个li节点,都弹出其文本值及修改
清除minerd进程的简单方法
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
使用Dockerfile构建java web环境
Win11怎么开启自动HDR画质_Windows11显示设置HDR选项
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?
详解CentOS6.5 安装 MySQL5.1.71的方法
Android仿QQ列表左滑删除操作
如何正确下载安装西数主机建站助手?
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口
如何生成腾讯云建站专用兑换码?
用v-html解决Vue.js渲染中html标签不被解析的问题
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
如何有效防御Web建站篡改攻击?
Laravel如何使用Blade组件和插槽?(Component代码示例)
laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Laravel中的withCount方法怎么高效统计关联模型数量
无锡营销型网站制作公司,无锡网选车牌流程?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
Bootstrap CSS布局之列表
利用python获取某年中每个月的第一天和最后一天
如何在IIS中配置站点IP、端口及主机头?
如何用PHP快速搭建CMS系统?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
网站制作价目表怎么做,珍爱网婚介费用多少?
长沙企业网站制作哪家好,长沙水业集团官方网站?
南京网站制作费用,南京远驱官方网站?
昵图网官网入口 昵图网素材平台官方入口
使用C语言编写圣诞表白程序
魔毅自助建站系统:模板定制与SEO优化一键生成指南
Python并发异常传播_错误处理解析【教程】
如何用搬瓦工VPS快速搭建个人网站?
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
Laravel怎么判断请求类型_Laravel Request isMethod用法
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
Laravel如何升级到最新版本?(升级指南和步骤)
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】

