Linux 输入子系统原理理解(原创)
linux 输入子系统原理理解(原创)
以前学了单独的按键设备驱动以及鼠标驱动,实际上,在linux中实现这些设备驱动,有一种更为推荐的方法,就是input输入子系统。平常我们的按键,触摸屏,鼠标等输入型设备都可以利用input接口来简化驱动程序并实现设备驱动。
输入子系统原理
linux输入子系统的体系结构可以分为三个层面,分别为:驱动层、输入核心层、事件处理层,三个有点类似PHP的MVC模式,意思就是每个层次只是负责单独的一个功能,无需参与其他的功能,有点类似函数的封装,好了,废话不多说,三个层面具体的功能如下:
(1)驱动层:将底层的硬件输入转化为统一的事件类型,向输入核心(input core)汇报0,简单来说,驱动层就是负责汇报事情。
(2)输入核心层:为驱动层提供输入设备的注册和操作接口。
比如: 1. 用input_register_device函数对设备进行注册;
2. 通知事件处理层对事件进行处理;
3. 在/proc下产生相应的设备信息。
(3)事件处理层:主要作用就是与用户空间进行交互。包含提供驱动程序的fops接口,在/dev下生成相应的设备文件节点nod等功能。
总的来说,归纳一下上面的一大段内容:
一个事件,如鼠标移动,键盘按下事件,首先通过
驱动层Driver --> 输入核心层 InputCore-->事件处理层Event handler-->用户空间userspace的顺序来完成事件的响应。
设备描述
Input设备用input_dev结构体来描述。
在input子系统实现设备驱动程序中,驱动的核心工作是向系统报告按键,触摸屏,鼠标等事件,无须关心文件操作接口,因为这些接口是有事件处理层Event handler来实现的。
好了,原理讲的差不多了,接下来讲一下驱动的实现
驱动实现
1.事件支持
首先一个设备驱动,我们应该通过set_bit()函数来告诉输入子系统它支持哪些事件,哪些按键,例如:
Set_bit(EV_KEY,button_dev.evbit); 告诉输入子系统支持按键的时间
Struct input_dev中有两个成员:
Evbit: 事件类型
Keybit: 按键类型
事件类型:
EV_RST reset EV_KEY 按键
EV_REL 相对坐标 EV_ABS 绝对坐标
EV_MSC 其他 EV_LEC LED
EV_SND 声音 EV_REP repeat
EV_FF 力反馈
但事件类型为EV_KEY时,还需指明按键类型:
BTN_LEFT: 鼠标左键 BTN_0:数字0键
BTN_RIGHT: 鼠标右键 BTN_1:数字1键
BTN_MIDDLE: 鼠标中键
2.报告事件
当事件真的发生的时间,我们的驱动层应该向输入核心层Input Core来报告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)
Code: 事件的代码:如果事件类型是EV_KEY, 则该代码则为设备的键盘代码,例如键盘上按键代码值为0~127 ,鼠标键代码值为0x110 ~ 0x116 具体请参考include/linux/input.h文件
Value:事件的值。如果事件类型是EV_KEY, 按键按下时值为1,松开即为0
3.报告结束
Input_sync()用于告诉输入核心层input core:此次报告已经结束
例如,在触摸屏设备驱动中,一次点击的整个报告事件过程如下:
Input_report_abs(input_dev, ABS_X, x); //报告X坐标
Input_report_abs(input_dev, ABS_Y, y); //报告Y坐标
Input_report_abs(input_dev, ABS_PRESSURE, 1); //报告事件类型为按下,且value值为1
Input_sync(input_dev); //报告完毕,同步事件
一个按键驱动程序的局部函数:
//在按键中断中报告事件
Static void buton_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
//注意,此处所有的按键都要报告,无论是0号按键还是1号按键
Input_report_key(&button_dev, BTN_0, inb(BUTTON_PORT0));
Input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT1));
Input_sync(&button_dev); //报告完毕,同步事件
//此时,输入核心层和事件处理层就会将收集的事件类型形成相应的数据,放到file operation 中和 buffer中,以用用户空间读取
}
//驱动初始化函数
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); //告诉输入子系统支持0号键
Set_bit(BTN_1, button_dev.keybit); //告诉输入子系统支持1号键
Input_register_device(&button_dev); //注册input设备
}
应用程序实现
当相应的时间响应,用户空间读取事件是,所读取到的是 input_event 结构的信息,不再是一个单纯的数字,
在input_event 结构中,已经包含 按键类型type, 按键键值code等信息。
用户需要对input_event 进行相应的解析,获得相应的信息。
Struct input_event ev_key; //声明结构体
Button_fd = open(“/dev/event0”,O_RDWR);
While(1){
Count = read(button_fd, &ev_key, sizeof( struct input_event ));
for( i=0; i<(int)count/sizeof( struct input_event ); i++ ){
if(EV_KEY == ev_key.type) //确定类型是否相同
printf(“type:%d, code:%d, value:%d \n”,ev_key.type,ev_key.code,ev_key.value);
If( EV_SYN == ev_key.type )
Printf(“syn event \n”);
}
}
Close(button_fd);
我们都在路上,有时苦有时甜,为此我送给自己以及相同爱好者们两个字:坚持 。
一起加油!!!
2015年1月16日
转载于:https://www.cnblogs.com/lihaiyan/p/4274456.html
Linux 输入子系统原理理解(原创)相关推荐
- 4. Linux - 输入子系统框架详解
输入子系统概述 Linux内核为了能够处理各种不同类型的输入设备,比如 触摸屏 ,鼠标 , 键盘 , 操纵杆 ,设计并实现了为驱动层程序的实现提供统一接口函数:为上层应用提供试图统一的抽象层 , 即是 ...
- [arm 驱动]Linux输入子系统分析
首先说明一下,本文是基于Linux-2.6.38版本内核来分析Linux输入子系统架构和原理的.这阵子本来没有打算花时间来分析Linux input system的,然而当在研究S3C6410触摸屏驱 ...
- 7.Linux 输入子系统分析
为什么要引入输入子系统? 在前面我们写了一些简单的字符设备的驱动程序,我们是怎么样打开一个设备并操作的呢? 一般都是在执行应用程序时,open一个特定的设备文件,如:/dev/buttons 1 .. ...
- Linux输入子系统框架
输入子系统 自己写的驱动程序,自己可以调用,我们自己写驱动的流程一般是,建立fops结构,使用register_chrdev在初始化函数中进行注册,在应用中使用open函数打开该设备.这种驱动不标准只 ...
- linux abs函数怎么用,Linux输入子系统详解
原标题:Linux输入子系统详解 纯手工打造每一篇开源资讯与技术干货,数十万程序员和Linuxer已经关注. 导读 linux输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如 ...
- linux驱动通过地址配置按键,linux输入子系统之多个按键
文章目录 linux输入子系统:驱动多个按键 驱动多个按键 一个按键有多个与其相关的元素: 中断号码 按键状态 按键的值 input_dev的详细描述如下图 在设备树文件中增加以下信息: 按键定义配置 ...
- linux输入子系统
输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动.键盘按下等通过Driver->Inputcore->Event handler->userspac ...
- Linux输入子系统:输入设备编程指南 -- input-programming.txt
输入设备编程指南(Programming input drivers) ~~~~~~~~~~~~~~~~~~~~~~~~~ 1. 新建一个输入设备驱动程序 ~~~~~~~~~~~~~~~~~~~~~~ ...
- 137.Linux输入子系统基本概念
文章目录 0.前言 1.简介 2.框架 3.输入子系统核心层 4.输入子系统驱动编写 4.1 基本变量 4.2 input_dev的注册 4.2.1 设置事件值的方法代码 4.3 上报输入事件 4.4 ...
最新文章
- 架构 php_十年PHP架构师的成长之路,程序员必备
- 图解Linux系统调用
- Python基础教程:自定义函数
- java责任链模式审批请假_Java使用责任链模式处理学生请假问题详解
- java js webservice_java Web技术探路:js Ajax调用WebService
- USACO-Section1.2 Broken Necklace (枚举法)
- 一文介绍备机重建各种方法的实现机制
- java oracle的2种分页方法
- 我的失败与伟大 —— 产品原型的打造
- delphi获取本地外网ip_中小企业网络架构:内网安全部署之DHCP,防止恶意DHCP与IP冲突...
- 服务器集群虚拟机,服务器集群虚拟机
- 画以载道:艺术演变的动力与社会思潮的嬗变
- UE4 坐标系 坐标轴旋转轴
- BT401蓝牙模块KT1025A蓝牙芯片用户修改BLE的广播包数据的说明以及方法
- 正常卸载Microsoft Office后无法重新安装?
- Win11打印机无法打印怎么办?Win11打印机无法打印解决方法
- Socket的用法——普通Socket
- oracle窗口设置,ORACLE安装DISPLAY变量设置 go with
- 工业4.0:换热站最酷设计—— Web SCADA 工业组态软件界面
- 【迅为推荐】适合新手学习的arm开发板-iTOP-4412开发板
热门文章
- hdu 2544 最短路
- Spring boot actuator端点启用和暴露
- bsgs(Baby Steps Giant Steps)算法
- 【转】java提高篇(二)-----理解java的三大特性之继承
- Ubuntu 16.04 搭建Android开发环境
- Delphi iOS 开启文件共享 UIFileSharingEnabled
- 对于SpringMVC框架使用的时候出现“警告: No mapping found for HTTP request with URI [/login]”的问题解决方案...
- 一个TextView使用不同的颜色
- 二叉树学习笔记--先序遍历
- css - clearfix-清除浮动