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结构描述),不再需要关心文件操作接口。驱动报告事件经过inputCore和Eventhandler到达用户空间。
注册输入设备函数:
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_dev是struct 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
input子系统详解的更多相关文章
- input子系统详解2
上一节大概了解了输入子系统的流程 这一节认真追踪一下代码 input.c: input_init(void)函数 static int __init input_init(void) { int er ...
- linux input子系统详解
首先,什么是linux的子系统: 输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动通过Driver->Input core->Event handler- ...
- Linux内核驱动学习(十)Input子系统详解
文章目录 前言 框架 如何实现`input device` 设备驱动? 头文件 注册input_dev设备 上报按键值 dev->open()和dev->close() 其他事件类型,处理 ...
- driver: Linux设备模型之input子系统详解
本节从整体上讲解了输入子系统的框架结构.有助于读者从整体上认识linux的输入子系统.在陷入代码分析的过程中,通过本节的知识能够找准方向,明白原理. 本节重点: 输入子系统的框架结构 各层对应内核中的 ...
- Linux输入子系统详解
input输入子系统框架 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Input ...
- 嵌入式Linux内核I2C子系统详解
1.1 I2C总线知识 1.1.1 I2C总线物理拓扑结构 I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通过对SCL和SDA线高 ...
- PhoenixFD插件流体模拟——UI布局【Input】详解
Liquid Input 流体输入 本文主要讲解Input折叠栏中的内容.原文地址:https://docs.chaosgroup.com/display/PHX3MAX/Liquid+Input 主 ...
- vue中ref在input中详解
当我们在项目中遇见文本输入框的时候,获取时刻输入框中的值 1.v-model <template> <input type="text" v-model=&quo ...
- input表单的type属性详解,不同type不同属性之间区别
目标:详解表单input标签type属性常用的属性值 一.input标签和它的type属性 PS:input 元素可以用来生成一个供用户输入数据的简单文本框. 在默认的情况下, 什么样的数据均可以输入 ...
随机推荐
- K2任命新的亚太区高级副总裁
K2, 一个屡获殊荣的企业应用软件公司宣布,任命陈光明(Tan Kwang Meng, KM)为亚太区高级副总裁.这次任命是对公司持续发展的肯定,同时也是对将亚太区作为全球扩张战略的关键市场的承诺. ...
- 各种注释--------html,jsp
1. <!--到梦之都XHTML教程的链接--> <a href="http://www.dreamdu.com/xhtml/"> 学习XHTML < ...
- UTF-8 有BOM和无BOM
BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order).微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 AS ...
- Linux Program
vhost : web.myftp.com storage.myftp.com ...... not vhost : storage.myftp.com eg : top eg : htop eg : ...
- Javascript使用总结
Javascript(简称JS)简介 JavaScript是一门广泛用于浏览器客户端的脚本语言,由Netspace公司设计,当时跟Sun公司(已经被oracle收购)合作,所以名字起得像Java,业内 ...
- pyqt5 笔记(二)实现http请求发送
上个图~ index.py 文件 # -*- coding: utf-8 -*- from PyQt5 import QtWidgets,QtCore #从pyqt库导入QtWindget通用窗口类 ...
- Ubuntu 14.10 下安装java反编译工具 jd-gui
系统环境,Ubuntu 14.10 ,64位 1 下载JD-GUI,网址http://221.3.153.126/1Q2W3E4R5T6Y7U8I9O0P1Z2X3C4V5B/jd.benow.ca/ ...
- 2016 - 1 - 19NSOpertation的依赖关系和监听
一:NSOperation的依赖: 1.概念:队列中的A操作需要等其他B操作或者某些操作执行完毕后才执行,就叫做A依赖与B或者A依赖于其他某些操作. 2.注意点:不能循环依赖,否则卡死.如: [op2 ...
- MagSpoof:能预测并窃取你下一张信用卡号码的廉价设备
想象一下,你丢失了信用卡,并从银行申请了一张新的信用卡.但是,如果在你收到这张新卡之前,一些网络罪犯就已经在使用你的新信用卡,此时你作何感想?是的,这完全是可以实现的,至少使用这个仅仅10美元的设备M ...
- php大力力 [014节] 八杆子打不着的非技术文章,哈哈
今天似乎是个值得纪念的日子 一个创业失败者的忠告:请不要再参加创业活动 PHP mysql_connect() 函数 mysql默认用户 随意发几个链接,没任何意义