查看: 1781|回复: 0

[原创] S5PV210(TQ210)学习笔记——输入子系统驱动

[复制链接]
  • TA的每日心情
    奋斗
    2018-3-5 10:57
  • 签到天数: 112 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2015-12-25 11:07:17 | 显示全部楼层 |阅读模式
    分享到:
    [size=12.380952835083px]   前面的文章简单的讲述了字符设备驱动程序的编写,用字符设备驱动的方式实现了按键驱动,但是,出了我们的自己编写的针对我们的这个驱动程序的应用程序之外,其他应用程序都无法接收我们这个驱动的键值输入,为了让所有应用程序都可以接收我们的按键驱动解析的键值,Linux内核定义了“输入子系统”的概念,也就是说,只要我们按照这个模型进行驱动开发,并为其提供必须的接口函数,那么,Linux内核就可以正常来获取我们的键盘值了。
    [size=12.380952835083px]  输入子系统的原理分析强烈推荐观看韦东山老师的视频讲座,讲的非常清楚,我这里是按照输入子系统的方式实现的按键驱动,下面是源码,放在这里做个备份:
    • #include <linux/types.h>  
    • #include <linux/module.h>  
    • #include <linux/input.h>  
    • #include <linux/timer.h>  
    • #include <linux/interrupt.h>  
    • #include <linux/gpio.h>  
    •   
    • static struct input_dev *buttons_dev;  
    • static struct timer_list timer;  
    • struct button_desc* button_desc = NULL;  
    •   
    • struct button_desc{  
    •     char* name;  
    •     unsigned int pin;  
    •     unsigned int irq;  
    •     unsigned int val;  
    • };  
    •   
    • static struct button_desc buttons_desc[8] = {  
    •     [0] = {  
    •         .name = "S1",  
    •         .pin = S5PV210_GPH0(0),  
    •         .irq = IRQ_EINT(0),  
    •         .val = KEY_L,  
    •     },  
    •   
    •     [1] = {  
    •         .name = "S2",  
    •         .pin = S5PV210_GPH0(1),  
    •         .irq = IRQ_EINT(1),  
    •         .val = KEY_S,  
    •     },  
    •   
    •     [2] = {  
    •         .name = "S3",  
    •         .pin = S5PV210_GPH0(2),  
    •         .irq = IRQ_EINT(2),  
    •         .val = KEY_C,  
    •     },  
    •   
    •     [3] = {  
    •         .name = "S4",  
    •         .pin = S5PV210_GPH0(3),  
    •         .irq = IRQ_EINT(3),  
    •         .val = KEY_ENTER,  
    •     },  
    •   
    •     [4] = {  
    •         .name = "S5",  
    •         .pin = S5PV210_GPH0(4),  
    •         .irq = IRQ_EINT(4),  
    •         .val = KEY_LEFTCTRL,  
    •     },  
    •   
    •     [5] = {  
    •         .name = "S6",  
    •         .pin = S5PV210_GPH0(5),  
    •         .irq = IRQ_EINT(5),  
    •         .val = KEY_MINUS,  
    •     },  
    •   
    •     [6] = {  
    •         .name = "S7",  
    •         .pin = S5PV210_GPH2(6),  
    •         .irq = IRQ_EINT(22),  
    •         .val = KEY_CAPSLOCK,  
    •     },  
    •   
    •     [7] = {  
    •         .name = "S8",  
    •         .pin = S5PV210_GPH2(7),  
    •         .irq = IRQ_EINT(23),  
    •         .val = KEY_SPACE,  
    •     },  
    • };  
    •   
    • static void timer_function(unsigned long data){  
    •     if(button_desc == NULL)  
    •         return;  
    •   
    •     if(gpio_get_value(button_desc->pin)){  
    •         input_event(buttons_dev, EV_KEY, button_desc->val, 0);  
    •     }  
    •     else{  
    •         input_event(buttons_dev, EV_KEY, button_desc->val, 1);  
    •     }  
    •     input_sync(buttons_dev);  
    • }  
    •   
    • static irqreturn_t irq_handler(int irq, void *devid){  
    •     button_desc = (struct button_desc*)devid;  
    •     mod_timer(&timer, jiffies + HZ/100);  
    •     return IRQ_RETVAL(IRQ_HANDLED);  
    • }  
    •   
    • static int buttons_init(void){  
    •     int i;  
    •       
    •     buttons_dev = input_allocate_device();  
    •     if(buttons_dev == NULL){  
      前面的文章简单的讲述了字符设备驱动程序的编写,用字符设备驱动的方式实现了按键驱动,但是,出了我们的自己编写的针对我们的这个驱动程序的应用程序之外,其他应用程序都无法接收我们这个驱动的键值输入,为了让所有应用程序都可以接收我们的按键驱动解析的键值,Linux内核定义了“输入子系统”的概念,也就是说,只要我们按照这个模型进行驱动开发,并为其提供必须的接口函数,那么,Linux内核就可以正常来获取我们的键盘值了。

    [size=12.380952835083px]  输入子系统的原理分析强烈推荐观看韦东山老师的视频讲座,讲的非常清楚,我这里是按照输入子系统的方式实现的按键驱动,下面是源码,放在这里做个备份:
    •      printk(KERN_ERR "Error: allocate input device failed!\n");  
    •         return -ENOMEM;  
    •     }  
    •   
    •     __set_bit(EV_KEY, buttons_dev->evbit);  
    •     __set_bit(EV_REP, buttons_dev->evbit);  
    •   
    •     __set_bit(KEY_L,        buttons_dev->keybit);  
    •     __set_bit(KEY_S,        buttons_dev->keybit);  
    •     __set_bit(KEY_C,        buttons_dev->keybit);  
    •     __set_bit(KEY_SPACE,    buttons_dev->keybit);  
    •     __set_bit(KEY_MINUS,    buttons_dev->keybit);  
    •     __set_bit(KEY_ENTER,    buttons_dev->keybit);  
    •     __set_bit(KEY_LEFTCTRL, buttons_dev->keybit);  
    •     __set_bit(KEY_CAPSLOCK, buttons_dev->keybit);  
    •   
    •     printk("1\n");  
    •     if(input_register_device(buttons_dev)){  
    •         goto error_1;  
    •     }  
    •   
    •     printk("2\n");  
    •     init_timer(&timer);  
    •     timer.function = timer_function;  
    •     add_timer(&timer);  
    •   
    •     printk("3\n");  
    •     for(i = 0; i != 8; ++i){  
    •         if(request_irq(buttons_desc.irq, irq_handler,   
    •             IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, buttons_desc.name, &buttons_desc)){  
    •             goto error_2;  
    •         }  
    •     }  
    •     printk("4\n");  
    •       
    •     return 0;  
    •   
    • error_2:  
    •     for(--i; i >= 0; --i){  
    •         free_irq(buttons_desc.irq, &buttons_desc);  
    •     }  
    •     input_unregister_device(buttons_dev);  
    •   
    • error_1:  
    •     input_free_device(buttons_dev);  
    •   
    •     return -EBUSY;  
    • }  
    •   
    • static void buttons_exit(void){  
    •     int i;  
    •     for(i = 0; i != 8; ++i){  
    •         free_irq(buttons_desc.irq, &buttons_desc);  
    •     }  
    •   
    •     input_unregister_device(buttons_dev);  
    •     input_free_device(buttons_dev);  
    • }  
    •   
    • module_init(buttons_init);  
    • module_exit(buttons_exit);  
    • MODULE_LICENSE("GPL");  
    [size=12.380952835083px]
    [size=12.380952835083px]
    [size=12.380952835083px]  很显然,基于输入子系统的按键驱动比起直接编写的字符驱动设备要简单的多,不过按键消抖还是要加的,上面的代码加上了按键消抖。
    [size=12.380952835083px]
    [size=12.380952835083px]TQ210v4开发板:http://www.embedsky.com/index.php?s=/Product/show/id/47.html
    [size=12.380952835083px]TQ210v3开发板:http://www.embedsky.com/index.php?s=/Product/show/id/43.html
    [size=12.380952835083px]TQ210v6开发板:http://www.embedsky.com/index.php?s=/Product/show/id/80.html

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2025-1-12 07:55 , Processed in 0.123143 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.