input子系统详解

一、初识linux输入子系统

linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler)、输入子系统核心层(InputCore)和输入子系统设备驱动层。

对于输入子系统设备驱动层而言,主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层。即将底层的硬件输入转化为统一事件形式,想输入核心(Input Core)汇报。

对于核心层而言,为设备驱动层提供了规范和接口。设备驱动层只要关心如何驱动硬件并获得硬件数据(例如按下的按键数据),然后调用核心层提供的接口,核心层会自动把数据提交给事件处理层。承上启下。为驱动层提供输入设备注册与操作接口,如:input_register_device;通知事件处理层对事件进行处理;在/Proc下产生相应的设备信息

对于事件处理层而言,则是用户编程的接口(设备节点),并处理驱动层提交的数据处理。和用户空间交互。(Linux中在用户空间将所有的设备都当初文件来处理,由于在一般的驱动程序中都有提供fops接口,以及在/dev下生成相应的设备文件nod,这些操作在输入子系统中由事件处理层完成)

对于linux输入子系统的框架结构如下图1所示:

由上图所展现的内容就是linux输入子系统的分层结构。

/dev/input目录下显示的是已经注册在内核中的设备编程接口,用户通过open这些设备文件来打开不同的输入设备进行硬件操作。

事件处理层为不同硬件类型提供了用户访问及处理接口。例如当我们打开设备/dev/input/mice时,会调用到事件处理层的Mouse Handler来处理输入事件,这也使得设备驱动层无需关心设备文件的操作,因为Mouse Handler已经有了对应事件处理的方法。

输入子系统由内核代码drivers/input/input.c构成,它的存在屏蔽了用户到设备驱动的交互细节,为设备驱动层和事件处理层提供了相互通信的统一界面。

由上图可知输入子系统核心层提供的支持以及如何上报事件到input event drivers。

作为输入设备的驱动开发者,需要做以下几步:

  在驱动加载模块中,设置你的input设备支持的事件类型,类型参见表1设置

注册中断处理函数,例如键盘设备需要编写按键的抬起、放下,触摸屏设备需要编写按下、抬起、绝对移动,鼠标设备需要编写单击、抬起、相对移动,并且需要在必要的时候提交硬件数据(键值/坐标/状态等等)

将输入设备注册到输入子系统中

表1  Linux输入子系统支持的数据类型


EV_SYN     0x00    同步事件

EV_KEY     0x01    按键事件

EV_REL     0x02    相对坐标(如:鼠标移动,报告相对最后一次位置的偏移)

EV_ABS     0x03    绝对坐标(如:触摸屏或操作杆,报告绝对的坐标位置)

EV_MSC     0x04    其它

EV_SW      0x05    开关

EV_LED     0x11    按键/设备灯

EV_SND     0x12    声音/警报

EV_REP     0x14    重复

EV_FF      0x15    力反馈

EV_PWR    0x16    电源

EV_FF_STATUS    0x17   力反馈状态

EV_MAX    0x1f    事件类型最大个数和提供位掩码支持

由表1可知,设备所能表示的事件种类,一个设备可以选择一个或多个事件类型上报给输入子系统。

Linux输入子系统提供了设备驱动层上报输入事件的函数,在include/linux/input.h中:

voidinput_report_key(struct input_dev *dev, unsigned int code, int value);      //上报按键事件

voidinput_report_rel(struct input_dev *dev, unsigned int code, int value);       //上报相对坐标事件

voidinput_report_abs(struct input_dev *dev, unsigned int code, int value);       //上报绝对坐标事件

……

当提交输入设备产生的输入事件之后,需要调用下面的函数来通知输入子系统,以处理设备产生的完整事件:

void input_sync(struct input_dev *dev);

 设备描述:

input_dev结构

 实现设备驱动核心工作是:向系统报告按键、触摸屏等输入事件(event,通过input_event结构描述),不再需要关心文件操作接口。驱动报告事件经过inputCoreEventhandler到达用户空间。

注册输入设备函数:

int input_register_device(struct input_dev *dev)

 

注销输入设备函数:

void input_unregister_device(struct input_dev *dev)

驱动实现——初始化(事件支持)

set_bit()告诉input输入子系统支持哪些事件,哪些按键。例如:

 

set_bit(EV_KEY,button_dev.evbit)  (其中button_devstruct input_dev类型)

struct input_dev中有两个成员为:

evbit:

事件类型(包括

EV_RST,EV_REL,EV_MSC,EV_KEY,EV_ABS,EV_REP等)

keybit:

按键类型(当事件类型为EV_KEY时包括

BTN_LEFT,BTN_0,BTN_1,BTN_MIDDLE等)

驱动实现——报告事件:

用于报告EV_KEY,EV_REL,EV_ABS事件的函数分别为void input_report_key(struct

  input_dev *dev,unsigned int code,int value)

void input_report_rel(struct

  input_dev *dev,unsigned int code,int value)

void input_report_abs(struct

  input_dev *dev,unsigned int code,int value)

 

驱动实现——报告结束:

input_sync()同步用于告诉input core子系统报告结束。

 

实例:触摸屏设备驱动中,一次点击的整个报告过程如下:

input_reprot_abs(input_dev,ABS_X,x);   //x坐标

input_reprot_abs(input_dev,ABS_Y,y);   // y坐标

input_reprot_abs(input_dev,ABS_PRESSURE,1);

input_sync(input_dev);//同步结束

 

 

实例分析(按键中断程序):

//按键初始化

static int __init button_init(void)

{//申请中断

if(request_irq(BUTTON_IRQ,button_interrupt,0,”button”,NUll))

      return –EBUSY;

set_bit(EV_KEY,button_dev.evbit); //支持EV_KEY事件

 

set_bit(BTN_0,button_dev.keybit); //支持设备两个键

 

set_bit(BTN_1,button_dev.keybit); //

 

input_register_device(&button_dev);//注册input设备

}

/*在按键中断中报告事件*/

Static void button_interrupt(int irq,void *dummy,struct pt_regs *fp)

{

input_report_key(&button_dev,BTN_0,inb(BUTTON_PORT0));//读取寄存器BUTTON_PORT0的值

input_report_key(&button_dev,BTN_1,inb(BUTTON_PORT1));

input_sync(&button_dev);

}

总结:input子系统仍然是字符设备驱动程序,但是代码量减少很多,input子系统只需要完成两个工作:初始化和事件报告(这里在linux中是通过中断来实现的)。读者不妨用sourceinsignt 输入input_init去搜关于输入子系统的实现

http://blog.csdn.net/ielife/article/details/7798952

http://www.cnblogs.com/deng-tao/p/6094049.html

http://www.cnblogs.com/myblesh/articles/2367648.html

时间: 2024-10-31 11:31:00

input子系统详解的相关文章

input子系统详解2

上一节大概了解了输入子系统的流程 这一节认真追踪一下代码 input.c: input_init(void)函数 1 static int __init input_init(void) 2 { 3 int err; 4 5 err = class_register(&input_class); 6 if (err) { 7 printk(KERN_ERR "input: unable to register input_dev class\n"); 8 return err;

vue中ref在input中详解

当我们在项目中遇见文本输入框的时候,获取时刻输入框中的值 1.v-model <template> <input type="text" v-model="inputval"> </template> export default { data(){ return { inputval:'', } }, watch:{ inputval(){ console.log(this.inputval) } } } 2.ref自定义一个方

OS X系统审计子系统详解

OS X是下了基本安全模块BSM.审计系统的作用是跟踪用户和进程的操作.类似于Windows系统里面的日志功能. 出于安全性考虑,审计系统必须在内核层次执行,在OS X中,审计是通过Mach实现的. 默认情况下,审计日志存放在/var/audit目录下.命名方式是start_time.stop_time.其中的start_time是起始时间戳,精度为秒.最后一个日志文件的stop_time是not_terminated. 在terminal输入以下命令可以看到/var/aduit目录的基本信息:

嵌入式Linux内核I2C子系统详解

1.1 I2C总线知识 1.1.1  I2C总线物理拓扑结构     I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递.在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平. 1.1.2  I2C总线特征    I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(可以从I2C器件的数据手册得知),主

Java笔记---Hadoop 2.7.1下WordCount程序详解

一.前言 在之前我们已经在 CenOS6.5 下搭建好了 Hadoop2.x 的开发环境.既然环境已经搭建好了,那么现在我们就应该来干点正事嘛!比如来一个Hadoop世界的HelloWorld,也就是WordCount程序(一个简单的单词计数程序) 二.WordCount 官方案例的运行 2.1 程序简介 WordCount程序是hadoop自带的案例,我们可以在 hadoop 解压目录下找到包含这个程序的 jar 文件(hadoop-mapreduce-examples-2.7.1.jar),

Android4.0 input事件输入流程详解(中间层到应用层)

在Android系统中,类似于键盘按键.触摸屏等事件是由WindowManagerService服务来管理的,然后再以消息的形式来分发给应用程序进行处理.系统启动时,窗口管理服务也会启动,该服务启动过程中,会通过系统输入管理器InputManager来负责监控键盘消息.当某一个Activity激活时,会在该Service下注册一个接收消息的通道,表明可以处理具体的消息,然后当有消息时,InputManager就会分发给当前处于激活状态下的Activity进行处理. InputManager的启动

Angularjs 事件指令 input 相关指令 和样式指令 DOM 操作指令详解

Angularjs 事件指令 input 相关指令 和样式指令DOM 操作指令详解学习要点:1. AngularJs 事件指令2. input 相关指令3. 样式指令4. DOM 操作指令5. ngBind/ngBindHtml/ngBindTemplate 重点6. ng-init ng-mode ng-model-options ng-controler 1. Angularjs 事件指令自己研究:ng-click/dbclickng-mousedown/upng-mouseenter/le

25.Unity3D手机中Input类touch详解-Unity触屏事件解析到底(Twisted Fate)

首先贴一下Unity支持的模型文件类型,以前没有收集过. Unity支持两种类型的3D文件格式: 1.  通用的"出口型"3D文件 如.fbx..dae..3ds..dxf..obj等文件格式. 2.  3D软件专用的3D文件格式 如Max, Maya, Blender,Cinema4D, Modo, Lightwave & Cheetah3D 等软件所支持的格式,如.MAX, .MB, .MA等等. Unity3D手机中Input类touch详解: 1.Input.touch

13.Linux键盘按键驱动 (详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的4个按键代表键盘中的L.S.空格键.回车键 1.先来介绍以下几个结构体使用和函数,下面代码中会用到 1)input_dev驱动设备结构体中常用成员如下: struct input_dev { void *private; const char *name; //设备名字 const char *ph