首页 > 其他分享 >符合input子系统的设备驱动之按键驱动(三)

符合input子系统的设备驱动之按键驱动(三)

时间:2023-07-12 18:11:44浏览次数:39  
标签:input dev buttons handler timer 按键 驱动 子系统

作者:Bright-Ho

联系方式:[email protected]



符合input子系统的设备驱动之按键驱动(三)


前两节我们回顾了按键实现的硬件原理,这一节我们就实现input系统的设备硬件层的内容;


(1)首先看入口函数做了哪些事情?


46 static struct input_dev *buttons_dev;

47 static struct pin_desc *irq_pd;

48 static struct timer_list buttons_timer; /*定时器*/


85 static int buttons_init(void){

86

87 int i;

89 /*1. 分配一个input_dev结构体*/

90 buttons_dev = input_allocate_device();

92 /*2. 设置*/

93 /*2.1 能产生按键类事件*/

94 set_bit(EV_KEY,buttons_dev->evbit);

95

96 /*2.2 能产生按键类事件里面的哪些按键,L S ENTER SHIFT*/

97 set_bit(KEY_L,buttons_dev->keybit);

98 set_bit(KEY_S,buttons_dev->keybit);

99 set_bit(KEY_ENTER,buttons_dev->keybit);

100 set_bit(KEY_LEFTSHIFT,buttons_dev->keybit);

101

102 /*3. 注册,会把buttons_dev放入设备链表*/

103 input_register_device(buttons_dev);

104 /*4. 硬件相关的操作*/

105

106 /*4.1 初始化定时器*/

107 init_timer(&buttons_timer);

108 buttons_timer.function = buttons_timer_function;

109 add_timer(&buttons_timer);

110

111 for(i = 0; i < 4, i++){

112 /*注册按键中断*/

113 request_irq(pins_desc[i].irq, buttons_irq_func,IRQT_BOTHEDGE,pins_desc[i].name, &pins_desc[i])

114 }

115

116 return 0;

117 }



input_dev结构体原型如下:

927 struct input_dev {

928

929 void *private;

930

931 const char *name;

932 const char *phys;

933 const char *uniq;

934 struct input_id id;

935

936 unsigned long evbit[NBITS(EV_MAX)]; /*表示能产生哪类事件,同步类,按键类,相对位移类,绝对位移*/

937 unsigned long keybit[NBITS(KEY_MAX)]; 按键事件

938 unsigned long relbit[NBITS(REL_MAX)]; 相对位移事件

939 unsigned long absbit[NBITS(ABS_MAX)]; 绝对位移事件

940 unsigned long mscbit[NBITS(MSC_MAX)]; 鼠标事件

941 unsigned long ledbit[NBITS(LED_MAX)]; led

942 unsigned long sndbit[NBITS(SND_MAX)]; 声音

943 unsigned long ffbit[NBITS(FF_MAX)];

944 unsigned long swbit[NBITS(SW_MAX)];

945 。。。。

};

 

设备层就是:

(1)通过核心层提供的input_allocate_device()函数,分配一个input_dev结构体;

(2)分配好了之后,就开始设置产生什么事件,比如按键类事件,按键类事件的哪些按键; (3)通过核心岑提供的input_register_device(buttons_dev)注册函数,把初始化好input_dev结构,放入设备链表;

(4)硬件相关的操作,初始化定时器,注册按键中断;这部分由于硬件设备不同,相关操作就不一样。这里分析的是按键相关的操作;


总结:

input_dev结构是对硬件设备抽象出来的一个结构;当分配,设置,注册好input_dev结构后,就把该结构加入设备链表;之后就会一一从handler链表中取出每一个input_handler处理事件,使用“核心层”提供的input_attach_handler()绑定函数和input_match_device(handler->id_table, dev)匹配函数,与input_dev匹配,它们两者之间通过id_table来匹配;匹配成功后,就直接调用“事件处理层”中input_handler里面的connect函数来建立连接;

connect(handler,dev,id)函数做哪些事情?

(1)分配一个evdev结构体

evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);

(2)设置该结构体,让handle的dev指向传进来的dev,handle的handler指向传进来的handler;

646 evdev->exist = 1;

647 evdev->minor = minor;

648 evdev->handle.dev = dev;

649 evdev->handle.name = evdev->name;

650 evdev->handle.handler = handler;

651 evdev->handle.private = evdev;

(3)通过MDEV机制,在dev/下生成设备接口,以便应用层调用;为什么在这里生成接口,之前有分析过;

devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),

class_device_create(&input_class, &dev->cdev, devt, dev->cdev.dev, evdev->name);

 

(4)调用核心层提供的input_register_handle(&evdev->handle)函数;

1227 list_add_tail(&handle->d_node, &handle->dev->h_list);

1228 list_add_tail(&handle->h_node, &handler->h_list);

把handle分别放入input_dev自己的链表和input_handler自己的链表中,这样dev和handler就真正的建立了联系; input_dev可以通过从自己的链表h_list找到handle,根据handle.handler找到对该设备的处理事件handler;反过来, input_handler可以通过从自己的链表h_list找到handle,根据handle.dev找到事件处理对应的设备input_dev;


input子系统dev与handler匹配连接图:





这里再着重的分析一下,硬件相关操作的定时器和按键中断处理;


定时器和中断处理,定时器主要就是按键防抖动;中断处理就是获取按键值;


定时器两要素:

(1)定时器超时时间;

(2)定时器的处理函数;


106 /*4.1 初始化定时器*/

107 init_timer(&buttons_timer);

108 buttons_timer.function = buttons_timer_function;

109 add_timer(&buttons_timer);

110

111 for(i = 0; i < 4, i++){

112 /*注册按键中断*/

113 request_irq(pins_desc[i].irq, buttons_irq_func,IRQT_BOTHEDGE,pins_desc[i].name, &pins_desc[i])

114 }

115


中断处理函数: buttons_irq_func;

50 /*中断处理函数*/

51 static irqreturn_t buttons_irq_func(int irq, void *dev_id){

52

53 /*10ms后启动定时器*/

54 irq_pd = (struct pin_desc *)dev_id;

55 mod_timer(&buttons_timer, jiffies+HZ/100);

56 return IRQ_RETVAL(IRQ_HANDLED);

57 }


中断处理函数里面主要就是来设置定时器的超时时间,定时器超时时间一到,就会调用定时器处理函数;设置超时时间就是防止抖动,等待按键按下或者松开时,让按键值趋于稳定后,在去获取按键值;


定时器处理函数: buttons_timer_function;

59 /*定时器处理函数*/

60 static void buttons_timer_function(unsigned long data){

61

62 struct pin_desc *pindesc = irq_pd;

63 unsigned int pinval;

64

65 if(!pindesc)

66 return;

67

68 pinval = s3c2410_gpio_getpin(pindesc->pin);

69

70 if(pinval){

71

72 /*松开:最后一个参数:0-松开, 1-按下*/

73 input_event(buttons_dev,EV_KEY,pindesc->key_val,0);

74 input_sync(buttons_dev);

75 }

76 else{

77

78 /*按下:最后一个参数:0-松开, 1-按下*/

79 input_event(buttons_dev,EV_KEY,pindesc->key_val,1);

80 input_sync(buttons_dev);

81 }

82

83 }


定时器处理函数做的事:

(1)通过内核gpio函数.获取按键值

pinval = s3c2410_gpio_getpin(pindesc->pin);

(2)获取到按键值后,上报数据

input_event(buttons_dev,EV_KEY,pindesc->key_val,1);

按下和松开都会上报数据;其原因是中断注册时,按键是双边沿触发触发中断;

所谓上报数据,就是数据准备好了,通知等待的进程去读数据了;上报函数具体做了哪些事,之前也分析过了;

标签:input,dev,buttons,handler,timer,按键,驱动,子系统
From: https://www.cnblogs.com/Bright-Ho/p/17548474.html

相关文章

  • 字符设备驱动之输入子系统分析(四)
    作者:Bright-Ho联系方式:[email protected]这一节主要讲解“设备硬件层”;这一层的内容就需要我们自己来实现;这里主要讲解框架;在“核心层”里面会提供一个input_register_device()这样一个函数;在“设备硬件层”先构造并初始化一个structinput_dev*dev结构,通过input_regist......
  • 字符设备驱动之输入子系统分析(三)
     作者:Bright-Ho联系方式:[email protected]输入子系统之“事件处理层”分析:注意:我们现在只是涉及输入子系统的框架;具体细节会涉及到硬件的工作原理,在后面我们写驱动的时候会说到细节方面;这一节,我们接触到了“事件处理层”;事件处理层包含了evdev.c(事件设备),tsdev.c......
  • Windows 驱动程序签名教程(一) --- 开发测试篇
    一、内核驱动签名初篇1.大概聊一聊现有驱动情况1.开启安全启动(SecureBoot)1.使用微软WHQL签名2.使用2013-2015年签发的驱动签名,已过期未吊销未拉黑(不知道什么时候打个补丁会修复).2.关闭安全启动(SecureBoot)1.使用微软WHQL签名2.使用过期签名的sha1sha256都可以正常......
  • 高通个别驱动创建Buffer耗时高问题的解决
    前言最近在优化游戏的时候,发现在在高通特定驱动版本的机器上(855,855+等),创建VB的耗时跟VB的数量成正比,这个应该是驱动的bug。跟官方人员确认过,确实是有这个问题,他们给的解决方案是减少Buffer的数量,经过一轮优化后,Buffer数量减少了将近30%,但是这个耗时的问题还是没能解决,在正常机......
  • 如何实现mysql驱动的具体操作步骤
    MySQL驱动简介及使用示例1.什么是MySQL驱动?MySQL驱动是用于连接和操作MySQL数据库的软件模块。MySQL是一种常用的关系型数据库管理系统,而驱动则是用于连接不同编程语言和MySQL数据库之间的桥梁。驱动有助于程序员使用编程语言操作MySQL数据库,例如执行查询、插入、更新和删除数据......
  • elementUI远程搜索功能遇到的坑(el-autocomplete) 如果是提前加载出全量数据 去掉v-mode
    elementUI远程搜索功能遇到的坑(el-autocomplete)如果是提前加载出全量数据去掉v-model.trim换为v-model=“nameinputvalue”原文链接:https://blog.csdn.net/CuiCui_web/article/details/95939746本文主要是解决下拉框根据返回值隐藏   动态设置建议列表值等问题结构写......
  • element-ui带输入建议的input框踩坑(输入建议空白以及会闪出上一次的输入建议问题)
    element-ui带输入建议的input框踩坑(输入建议空白以及会闪出上一次的输入建议问题)原文链接:https://blog.csdn.net/wyhstars/article/details/81672195前段时间,在实现带输入建议并且支持模糊查询输入框的时候,发现了两个值得注意的小地方。整理出来,以供借鉴。废话不多说,直......
  • 使用input标签的时候报错,提示Form elements must have labels: Element has no title
    使用input标签的时候报错,提示Formelementsmusthavelabels:ElementhasnotitleattributeElementhasnoplaceholderattribute大概就是下面这样其实规范化一下,加个label就可以了......
  • VMware ESXi 7.0 U3n macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动
    VMwareESXi7.0U3nmacOSUnlocker&OEMBIOS集成网卡驱动和NVMe驱动(集成驱动版)ESXi7U3标准版集成Intel网卡、USB网卡和NVMe驱动请访问原文链接:https://sysin.org/blog/vmware-esxi-7-u3-sysin/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2023......
  • t113-c-led驱动篇(调用设备树)
    既然已经学会了调用驱动,那么接下来简单点个灯查看led所在寄存器我板子的led所控制的是pd22,所在寄存器应该是0x02000098然而这和我在设备树上找到的地址有出入,很奇怪,那就不管这个了自己添加一个吧。自己在board.dts上加一个ledio:我们看见这里有个&pio,而pio又是在dtsi中的so......