Linux输入子系统(Input Subsystem)

1.1.input子系统概述

输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中断(或驱动通过timer定时查询),然后cpu通过SPI,I2C或者外部存储器总线读取键值,坐标等数据,放一个缓冲区,字符设备驱动管理该缓冲区,而驱动的read()接口让用户可以读取键值,坐标等数据。

在Linux中,输入子系统是由输入子系统设备驱动层、输入子系统核心层(Input Core)和输入子系统事件处理层(Event Handler)组成。其中设备驱动层提供对硬件各寄存器的读写访问和将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层提交给事件处理层;而核心层对下提供了设备驱动层的编程接口,对上又提供了事件处理层的编程接口;而事件处理层就为我们用户空间的应用程序提供了统一访问设备的接口和驱动层提交来的事件处理。所以这使得我们输入设备的驱动部分不在用关心对设备文件的操作,而是要关心对各硬件寄存器的操作和提交的输入事件。

1.2. input子系统结构图

input子系统结构图如下图1所示:

图1 输入子系统结构图

1.3.linux中输入设备驱动的分层

linux中输入设备驱动的分层如下图2所示:

图2 linux中输入设备的分层

1.4. 输入子系统设备驱动层实现原理

在Linux中,Input设备用input_dev结构体描述,定义在input.h中。设备的驱动只需按照如下步骤就可实现了。
1).在驱动模块加载函数中设置Input设备支持input子系统的哪些事件;
2).将Input设备注册到input子系统中;
3).在Input设备发生输入操作时(如:键盘被按下/抬起、触摸屏被触摸/抬起/移动、鼠标被移动/单击/抬起时等),提交所发生的事件及对应的键值/坐标等状态。

1.5.软件设计流程

软件设计流程如下图3所示

图 3 input子系统软件设计流程

1.6.与软件设计有关的API函数

1.6.1.分配一个输入设备

Struct input_dev *input_allocate_device*(void);

1.6.2.注册一个输入设备

Int input_register_device(struct input_dev *dev);

1.6.3.驱动实现-事件支持

Set_bit告诉inout子系统它支持哪些事件
Set_bit(EV_KEY,button_dev.evbit)
Struct input_dev中有两个成员,一个是evbit;一个是keybit.分别用来表示设备所支持的事件类型和按键类型。

1.6.3.1事件类型

Linux中输入设备的事件类型有(这里只列出了常用的一些,更多请看linux/input.h中):EV_SYN 0x00 同步事件
EV_KEY 0x01 按键事件
EV_REL 0x02 相对坐标
EV_ABS 0x03 绝对坐标
EV_MSC 0x04 其它
EV_LED 0x11 LED
EV_SND 0x12 声音
EV_REP 0x14 Repeat
EV_FF 0x15 力反馈

1.6.4.驱动实现-报告事件

Void input_event(struct input_dev *dev,unsigned int type,unsigned int code,int value);//报告指定type,code的输入事件
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);//报告绝对坐标
Void input_sync(struct input_dev *dev);//报告同步事件
在触摸屏驱动设计中,一次坐标及按下状态的整个报告过程如下:
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,pres);//压力
input_sync(struct input_dev *dev);//同步

1.6.5释放与注销设备

Void input_free_device(struct input_dev *dev);
Void input_unregister_device(struct input_dev *);

最新文章

  1. javascript 实现tab菜单切换
  2. SQL Server 2008 R2没有卸载干净
  3. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)
  4. 【转】B树、B-树、B+树、B*树
  5. nargin函数的用法
  6. ubuntu系统安装的MySql数据库,远程不能访问的几种可能问题
  7. 在程序中用new ClassPathXmlApplicationContext()的注意事项
  8. Java算法-------无序数组中的最长连续序列---------leetcode128
  9. 【转载】MySQL5.6.27 Release Note解读(innodb及复制模块)
  10. Nero8刻录引导系统光盘镜像图文教程
  11. vue--组件基础
  12. C# string.format用法详解
  13. 20145212 罗天晨 MSF基础应用
  14. Ansible 插件 之 【CMDB】【转】
  15. PHP视频学习一 mysql
  16. EF框架 对字段属性为NULL的空值处理 类型前面加上?保证EF列表读取显示数据不会报异常
  17. 升级 Elasticsearch 集群数量实战记录
  18. linux克隆机器
  19. socket--多进程,多线程服务器
  20. Oracle电子商务套件版本12.1.3自述文件 (Doc ID 1534411.1)

热门文章

  1. mime类型表
  2. 《深度探索C++对象模型》1
  3. jquery中用jqzoom实现放大镜效果
  4. 【转】Android WebView 播放视频总结
  5. YTU 2973: C语言习题5.25--文件操作2
  6. Cube Stacking
  7. python中给for循环增加索引
  8. 走进Linux之systemd启动过程
  9. C#大纲
  10. 曲线救国,解决Mac系统下,Android sdk下载失败的问题