Linux系统当中,具备连接物理按键与系统响应要职的是按键驱动,它身为硬件输入设备与操作系统之间的桥梁,还决定着用户交互的实时性以及准确性,从一般的键盘按键一直到复杂的嵌入式设备控制,按键驱动的实现方式对用户体验有着直接影响,今天我会从实际开发的角度出发,朝着Linux按键驱动的核心实现要点深入探究 。

Linux按键驱动的基本原理

Linux内核把按键当作输入设备对待,借由输入子系统予以统一管理,当物理按键被按下之时也好,被释放之际也罢linux 按键驱动,均会产生中断信号,驱动得要捕获这些中断,并且转化成标准的输入事件,此一过程涵盖硬件寄存器操作、中断处理、输入事件上报等诸多环节,这就要求开发者对于硬件特性以及内核机制都得有清晰的理解才行。

按键驱动程序_按键驱动芯片_linux 按键驱动

于实际开发里头,按键驱动一般采用平台设备驱动模型,借由设备树去描述硬件连接信息。比如说,一个GPIO按键得清楚指明所使用的GPIO引脚,触发方式,按键键值等参数。驱动初始化之际会剖析这些信息,登记中断处理函数,并且创建相应的输入设备。这般设计致使驱动拥有良好的可移植性,同一套驱动代码只要修改设备树配置便能适配各异的硬件平台。

如何编写简单的按键驱动

去编写一个被称作为基础的按键驱动,是需要去完成几个处于关键状态之时的步骤的。首先,是有必要去定义并且初始化一个input_dev结构体的,借此来设置其能力位图,以此告知内核该此设备,可以去产生哪些类型的事件。针对于按键驱动来讲,通常是需要去设置一个名为EV_KEY的事件类型的,并且要明确地表明支持哪些具体的按键码。此种过程看起来好像是比较简单的,不过是需要认真仔细地去核对每一个跟按键相对应的键值定义的,以此来避免与标准键值产生冲突。

linux 按键驱动_按键驱动芯片_按键驱动程序

再往后要着手去申请,还要进行配置硬件资源,其中最为关键重要的是GPIO以及中断,借由devm_gpio_request申领GPIO资源哩,得保证资源管理实现自动化,而后运用request_irq或者devm_request_irq去注册中断处理函数,明确指定触发条件是上升沿、下降沿或者双边沿,在中断处理函数里头,要读取GPIO状态,判别按键是按下还是释放了,并且通过input_report_key和input_sync去上报相应的事件。

按键去抖动处理的实现方法

当机械按键在接触的瞬间之时,会产生好几次的通断情况,而把这种现象称作抖动,要是不进行处理的话,那系统就会错误认定为是多次的按键操作了,软件去抖动是最为常见的解决办法,它是借助定时器延迟判断来达成的linux操作系统安装,在检测到按键状态出现变化的时候,不会马上上报事件,而是开启一个定时器,等待10至20毫秒之后再去检测GPIO状态,只有状态稳定了才会上报事件。

按键驱动程序_按键驱动芯片_linux 按键驱动

一种不同的做法是,硬件进行去抖动,借助RC滤波电路将抖动信号消除掉。然而在实际的项目当中,软件方案被更多地采用,原因在于其成本低并且具备灵活性。Linux内核给出了专门的按键去抖动框架,开发者能够直接运用struct gpio_keys_platform_data里的debounce_interval字段来设置去抖时间,不需要自行去实现定时器的逻辑suse linux,这极大地简化了驱动开发的流程。

如何处理多个按键的驱动设计

若设备存在多个按键,那么驱动设计之时要考虑资源管理以及代码复用。理想的方案是运用gpio -- keys驱动模块 ,借由设备树一并配置全部按键参数。每一个按键都作为一个子节点 ,去指定GPIO、键值、标签还有去抖时间等属性。如此这般的方式减少了重复代码 ,提升了驱动稳定性。

要是自行去实现多按键驱动,那就要留意中断处理函数的共享方面的问题。能够给所有GPIO按键去注册同一个中断处理函数,在这个函数里面借助irq号来判断到底是哪一个按键触发了,或者是为每个按键注册单独的中断。不管采用哪一种方式,都得保证可以精准识别按键并且上报正确的键值,与此同时处理好并发访问的情形。

如何调试按键驱动问题

按键驱动芯片_按键驱动程序_linux 按键驱动

处理按键驱动调试事宜,最为直截的办法乃是去查看系统输入设备的相关信息。借由cat /proc/bus/input/devices能够将所有注册了的输入设备给罗列出来,进而确认按键设备是不是成功完成了注册。运用evtest此一工具能够对输入事件进行实时的监视哟,一旦按键被按下linux 按键驱动,该工具便会展示出具体的事件类型、键值以及值,这可是用来验证驱动是否正常运作的一种有效方式呢。

要是按键没了响应,头先得去检查硬件连接以及GPIO配置,去确认GPIO工作模式是正确的。随后得查看中断是不是能正常触发,去借助cat /proc/interrupts来查看中断统计。要是中断正常然而事件却不上报,那么问题有可能出在去抖动处理或者事件上报逻辑方面。内核的dynamic debug功能能够协助在驱动里添加调试输出,而用不着重新编译内核。

按键驱动在实际项目中的优化技巧

linux 按键驱动_按键驱动芯片_按键驱动程序

于实际的产品里头,按键驱动得要去考量功耗的优化事宜,具体尤其是在移动设备之上。当系统进入到休眠状态的时候,按键驱动应当具备能够使其振奋系统的能力。这就需要在设备树里为按键节点增添上”wakeup -- source”属性,并且在驱动当中准确无误地达成电源管理回调函数。与此同时,中断处理应当尽可能做到迅速,防止长时间占用CPU资源。

在存在特殊需求的场景方面,像是长按、连按等功能,一般并非于驱动层去达成,而是在应用层予以处理。驱动所要做的仅仅是精准上报每一次按键事件,由上层依据时间间隔来判定操作类型。这样的分层设计契合Linux的设计思想,维持驱动的简洁,与此同时为应用开发者供给充足的灵活性。

于你而言,在开展Linux设备按键驱动开发之时,所碰到的极具挑战性的难题究竟是哪一种呢?怀有分享自身经验之意向者,可在评论区域踊跃发言,要是自认为此文具备一定助益,烦请进行点赞这一操作,并将其分享给数量更多的开发者们!

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复