免费com域名网站网站建设制作设计营销 中山
web/
2025/10/1 6:33:47/
文章来源:
免费com域名网站,网站建设制作设计营销 中山,应用市场华为,建网络商城网站我们新项目硬件设计上使用gpio口做按键#xff0c;所以我就需要搞定这个驱动#xff0c;本来想自己写一个gpio口的按键驱动#xff0c;然后看了下内核下面的代码#xff0c;已经有现成的了。Linux内核下游很多很多的现成驱动#xff0c;只要你想得到的#xff0c;基本都是… 我们新项目硬件设计上使用gpio口做按键所以我就需要搞定这个驱动本来想自己写一个gpio口的按键驱动然后看了下内核下面的代码已经有现成的了。Linux内核下游很多很多的现成驱动只要你想得到的基本都是有现成的当然了不包括一些非正常的需求性问题学会在Linux下找驱动看驱动和内核代码我觉得是一件享受和快乐的事情。不过我还是在使用这个驱动上遇到了问题。1. 先说ADC 按键之前的文章有写过adc按键的实现无非就是为了省点GPIO口。RK 利用SARADC 来做多个按键2. GPIO 按键硬件原理图3. 驱动代码kernel-4.4/drivers/input/keyboard/gpio_keys.c
完整代码可查看https://gitee.com/weiqifa/gpio_key/blob/master/gpio_keys.c
驱动代码流程从probe处开始刚开始的时候我连dts文件都不会写因为之前没有接触过这个驱动。然后看了gpio_keys_get_devtree_pdata函数之后又看了内核代码下其他项目其他平台的dts文件才知道怎么写这个驱动的dts文件。实话说这个驱动完成了很多我们需要的功能比如防抖比如中断比如按键label等等。3.1 gpio_keys_get_devtree_pdata 函数解析dts文件这个文件解析的dts 有两种方式一种是直接传入irq的一种是只传入gpio口的。我们的这个项目就只传入了gpio口。3.2 gpio_keys_setup_key 函数这个函数用来设置gpio口的中断的直接看代码会比较清楚。下面这个函数我还没有想清楚它的作用看了回调函数里面的实现是为了把开启的工作队列停止掉。但是我加了打印并没有打印我猜测是为了防止误触发就是按键按下的时间非常短的时候才会调用这个。/*** devm_add_action() - add a custom action to list of managed resources* dev: Device that owns the action* action: Function that should be called* data: Pointer to data passed to action implementation** This adds a custom action to the list of managed resources so that* it gets executed as part of standard resource unwinding.*/
int devm_add_action(struct device *dev, void (*action)(void *), void *data)
{struct action_devres *devres;devres devres_alloc(devm_action_release,sizeof(struct action_devres), GFP_KERNEL);if (!devres)return -ENOMEM;devres-data data;devres-action action;devres_add(dev, devres);return 0;
}
3.3 驱动修改驱动修改的代码如下--- a/kernel-4.4/drivers/input/keyboard/gpio_keys.cb/kernel-4.4/drivers/input/keyboard/gpio_keys.c-32,6 32,11 #include linux/of_irq.h#include linux/spinlock.h
#define LOG_TAG [BUTTON]: %s() line: %d
#define PRINTK_T(fmt, args...) printk(KERN_INFO LOG_TAG fmt, __FUNCTION__, __LINE__, ##args)struct gpio_button_data {const struct gpio_keys_button *button;struct input_dev *input;-462,9 467,8 static int gpio_keys_setup_key(struct platform_device *pdev,spin_lock_init(bdata-lock);if (gpio_is_valid(button-gpio)) {
-
- error devm_gpio_request_one(pdev-dev, button-gpio,
- GPIOF_IN, desc);PRINTK_T(gpio:%d\n,button-gpio);error devm_gpio_request(pdev-dev, button-gpio,desc);if (error 0) {dev_err(dev, Failed to request GPIO %d, error %d\n,button-gpio, error);-483,7 487,9 static int gpio_keys_setup_key(struct platform_device *pdev,if (button-irq) {bdata-irq button-irq;} else {gpio_direction_input(button-gpio);irq gpio_to_irq(button-gpio);PRINTK_T(weiqifa irq :%d\n,irq);if (irq 0) {error irq;dev_err(dev,-540,8 546,10 static int gpio_keys_setup_key(struct platform_device *pdev,if (!button-can_disable)irqflags | IRQF_SHARED;- error devm_request_any_context_irq(pdev-dev, bdata-irq,
- isr, irqflags, desc, bdata);PRINTK_T(weiqifa devm_request_threaded_irq()\n);error devm_request_threaded_irq(pdev-dev, bdata-irq,NULL,isr, irqflags| IRQF_ONESHOT, desc, bdata);if (error 0) {dev_err(dev, Unable to claim irq %d; error %d\n,bdata-irq, error);-709,6 717,8 static int gpio_keys_probe(struct platform_device *pdev)int i, error;int wakeup 0; PRINTK_T(start.\n);
if (!pdata) {pdata gpio_keys_get_devtree_pdata(dev);if (IS_ERR(pdata))-779,6 789,8 static int gpio_keys_probe(struct platform_device *pdev)device_init_wakeup(pdev-dev, wakeup); PRINTK_T(end.\n);
return 0;err_remove_group:
可以确定的是如果不修改的话肯定是会出错的。你要知道这个驱动是在2005年就完成编写了中间经过了多少次的系统升级而且很多厂商主推的还是ADC按键驱动GPIO口驱动默认情况下是会被抛弃的厂商释放的SDK根本就不会记得修改这个驱动代码所以别以为你的手机运行正常里面就没有bugbug无处不在只是我们有了重启大法而已。4. dts 代码gpio-keys {compatible gpio-keys;#address-cells 1;#size-cells 0;autorepeat;//pinctrl-names default;//pinctrl-0 pwrbtn;button0 {gpios pio 49 IRQ_TYPE_EDGE_BOTH;linux,code KEY_F13;label GPIO F13 Power;linux,input-type 1;gpio-key,wakeup 1;debounce-interval 100;};button1 {gpios pio 48 IRQ_TYPE_EDGE_BOTH;linux,code KEY_F14;label GPIO F14 Power;linux,input-type 1;gpio-key,wakeup 1;debounce-interval 100;};button2 {gpios pio 51 IRQ_TYPE_EDGE_BOTH;linux,code KEY_F15;label GPIO F15 Power;linux,input-type 1;gpio-key,wakeup 1;debounce-interval 100;};};
5. 测试驱动烧录后按下按键可以看到键值上报.推荐阅读专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈关注公众号后台回复「1024」获取学习资料网盘链接。欢迎点赞关注转发在看您的每一次鼓励我都将铭记于心~嵌入式Linux微信扫描二维码关注我的公众号
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84894.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!