首页 > 系统相关 >Linux驱动开发十六.input系统——2.input_event

Linux驱动开发十六.input系统——2.input_event

时间:2022-08-28 11:34:32浏览次数:60  
标签:include 0000 Linux 按键 input EV event

我们上一章完成了input子系统的设备构成,并且在用户空间通过hexdump命令拿到了一堆不知道是什么的信息。今天我们就要借助input_event这个结构体来了解内核怎么通过那个结构体了解输入事件。

可能有心人已经发现了,上一章我们在加载完模块以后在/dev/input路径下生成了一个新的event文件

 

 在按键被按下以后,驱动就会向内核上报一个输入事件,而不同的输入设备都会有不同的实际内容上报给内核。所以Linux内核就整定了一个通用的结构体来描述每个事件。我们在用户态的程序就可以通过上面图中的event1来了解按键的实际状态。

input_event结构

想要知道event1文件在按键按下时打印的内容

首先要知道input_event结构体的内容(include/uapi/linux/input.h,注意路径,不要搞错了!)

 1 /*
 2  * The event structure itself
 3  */
 4 
 5 struct input_event {
 6     struct timeval time;
 7     __u16 type;
 8     __u16 code;
 9     __s32 value;
10 };

input_event结构体的内容很简单,先是一个timval结构体,这个结构体也可以展开看看!

1 struct timeval {
2     __kernel_time_t        tv_sec;        /* seconds */
3     __kernel_suseconds_t    tv_usec;      /* microseconds */
4 };

一个秒,一个微秒,查到底两个变量都是long型的数据,也就是32位的数据。

type就是事件类型,在我们驱动中定义的是EV_KEY。16位

code,事件码,在按键驱动中就是我们定义的键值。16位

value,值,在驱动中用来描述按键是否被按下或松开。32位

可以注意到,这个input_event结构体里后三个成员跟前面input_event函数中后面三个参数是一样的。按照上面的数据结构可以分析一下打印出来的信息,可以发现是这种结构的

编号          timeval_sec    timeval_usec     type         code      value
0000000      2217 0000       d132 0005       0001         000b       0001 0000
0000010      2217 0000       d132 0005       0000         0000       0000 0000
0000020      2217 0000       e29b 0006       0001         000b       0000 0000
0000030      2217 0000       e29b 0006       0000         0000       0000 0000

上面的信息都是由16进制来表示的,所以每个0都表示了4个bit。

第一组是编号,表示

第2、3列表示秒,一共8个数字,对应32位

第4、5列表示微秒

第6列为事件类型,对应EV_KEY,第一行是0001,就是对应的EV_KEY的值,第2行的0000对应EV_SYN事件

#define EV_SYN            0x00
#define EV_KEY            0x01

就是说按键在按下的时候,会上报一个EV_KEY事件,然后在定时处理函数里还调用了一个同步函数

input_sync(dev->inputdev);

可以转到这个函数的定义看一下,这个函数会上报一个EV_SYN信号

1 static inline void input_sync(struct input_dev *dev)
2 {
3     input_event(dev, EV_SYN, SYN_REPORT, 0);
4 }

所以就会有第2行那个0000,对应的type就是EV_SYN。

第7列是code,对应我们定义的key_value,我们在初始化input_dev的时候定义的事件code是keybit,值为KEY_0,KEY_0是个宏
#define KEY_0            11

十进制值为11,对应的code就是000b。

最后是value的值,表示我们上报的按键值,1对应按键按下,0表示释放。但是在不松开的时候这个值是1和2来回变化,我不知道是怎么来的。(这个值我感觉是个小端模式,0001在左边,包括前面那个时间的数据,感觉也是左边4个数先跳,后面的再变)。所以打印出来的这4行数据分别表示了按键按下事件——同步事件——按键弹起事件——同步事件。

应用程序编写

在前面写驱动的时候我们把文件操作集合以及对应的函数都删掉了,通过input子系统操作的输入设备对应的文件就是前面我们关注的/dev/input/路径下的event文件,也就是如果我们想要获取按键的状态,就要在用户态程序中将前面通过hexdump命令打印出的数据解析出来。

先放代码

 1 /**
 2  * @file inputAPP.c
 3  * @author your name ([email protected])
 4  * @brief input子系统测试APP
 5  * @version 0.1
 6  * @date 2022-08-28
 7  * 
 8  * @copyright Copyright (c) 2022
 9  * 
10  */
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <sys/ioctl.h>
18 #include <linux/input.h>
19 
20 /**
21  * @brief 
22  * 
23  * @param argc                      //参数个数 
24  * @param argv                      //参数
25  * @return int 
26  */
27 int main(int argc,char *argv[])
28 {
29     char *filename;                 //文件名
30     int ret = 0;                    //初始化操作返回值
31     int f = 0;                      //初始化文件句柄
32 
33     struct input_event inputevent;  //inputevent事件结构体
34 
35     if(argc != 2){
36         printf("format err!\r\n");
37         return -1;
38     }
39     
40     filename = argv[1];             //
41     f = open(filename, O_RDWR);     //打开文件
42     if(f < 0){
43     printf("file open error\r\n");
44     return -1;
45     }
46 
47     while(1){
48         ret = read(f,&inputevent,sizeof(inputevent));       //读取文集
49         if(ret<0){
50             //读取错误
51             printf("data read err\r\n");
52         }
53         else{
54             switch(inputevent.type) {
55                 case EV_SYN:
56                     break;
57                 case EV_KEY:
58                     printf("btn event\r\n");
59                     if(inputevent.code< BTN_MISC){
60                         //按键键值为KEY_xxx
61                         printf("key %d %s\r\n",inputevent.code,inputevent.value?"pressed":"released");
62                     }
63                     else{
64                         //按键键值为BTN_xxx
65                         printf("button %d %s\r\n",inputevent.code,inputevent.value?"pressed":"released");
66                     }
67                     break;
68                 case EV_REL:
69                     break;
70             }
71         }
72         }
73     close(f);                       //关闭文件
74     return 0;
75 }

整个应用程序的思路还是比较清晰度,主要就是在主程序里声明了一个inputevent结构体变量(教程里是按照全局变量的方法声明在主函数外部的)。打开文件什么的就不说了,我们要关注的就是从54行开始的switch结构,如果inputevent的type是EV_KEY的话,就按照键值读取。并且在case里做了一个判断,inputevent的value在0~255之间是对应的是键盘的键值,否则是button(如果我们只是当个按键使用不建议把按钮模拟成键盘,所以在写驱动的时候可以把bitkey的值放在btn区间)。

有意思的是即便我们并没有在驱动或应用程序中定义文件读写的阻塞或非阻塞的模式,但是我感觉实际状态下应该是按照阻塞模式读取的文件,可以在程序以后台模式运行以后通过top命令查询一下

/lib/modules/4.1.15 # ./inputAPP /dev/input/event1 &

 

可以看出来,程序并没有占用过多的资源。

标签:include,0000,Linux,按键,input,EV,event
From: https://www.cnblogs.com/yinsedeyinse/p/16631438.html

相关文章

  • 【Linux】tmux & vim
    tmux功能​(1)分屏。​(2)允许断开Terminal连接后,继续运行进程。结构​一个tmux可以包含多个session,一个session可以包含多个window,一个window可以包含......
  • archlinux下安装和配置cockpit简单记录
    使用如下命令安装,pacockpit端口查找,vim/usr/lib/systemd/system/cockpit.socketinstallmoretools,yaycockpit234567等。包括Podman管理容器,管理虚拟机,管理软件包更......
  • Linux应急响应学习
    Linux应急响应-系统日志排查-溯源溯源找到攻击者。系统日志分析攻击者的ip 攻击者可能留下了一些代码样本网上的信息很大程度上是不可信的。方法:蜜罐 高交互的蜜......
  • net/net core 压缩和解压文件类—完美支持Linux
    ///<summary>///文件压缩类///</summary>publicclassZipHelper{///<summary>///单文件压缩成ZIP///</summary>///<paramname="fileSou......
  • Linux之父:找份Linux工作是明智选择
    非盈利机构Linux基金会为宣传推广Linux,在最新上传的视频中邀请了Linux之父-LinusTorvalds出演。尽管这段视频只有1分钟左右,但对于那些想要从事IT行业的人来说是非常具......
  • linux系统mysql数据库目录迁移
    1、关闭mysqlsudo/etc/init.d/mysqlstop或systemctlstopmysql 2、移动数据存储位置mv/var/lib/mysql/*/media/mysqldata3、修改my.cnf配置文件......
  • Linux驱动开发十六.input系统——1.input子系统
    我们在前面通过pin控制学习了LInux内核的GPIO和Pinctrl子系统。GPIO主要用作简单的引脚控制驱动,今天我们来了解一下一组新的子系统:input子系统。input子系统是Linux内核专......
  • win10、win11安装子系统kali linux、图形化界面的安装
    1.开启安装Linux子系统需要的扩展Win+Q搜索功能勾选需要的扩展,Hyper-V、Windows虚拟机监控平台、适用于Linux的Windows子系统、虚拟机平台反正这些有关于虚拟机的全部......
  • Linux三剑客 之 awk学习与应用
    最近在调gps模块,要把代码里打印的NMEA的msg给抓出来,单独存在一个文件里,素来听闻awk的强大,这次打算借这个机会学习一波:也就是说,大概是从下面这样的log中,过滤出$开头的所有......
  • Linux centos7 如何配置静态ip(Nat模式)
    今天来讲下如何在vmware虚拟机Nat网络下配置静态ip地址。......