前面从具体(Linux 驱动框架---input子系统)的工作过程学习了Linux的input子系统相关的架构知识,但是前面的学习比较实际缺少总结,所以今天就来总结一下输入子系统的架构分层,站到远处来看输入子系统。总得来说输入子系统由设备驱动层(input_dev的注册),输入子系统核心层(input core),事件处理层(handler),和用户空间四部分。这一部分类别platform驱动框架的内容来学习。

设备驱动层(类似于platform_device)
       就是前面描述的gpio_keys.c 中的probe接口中的处理过程主要负责不同硬件的底层相关的中断,IO等具体硬件相关的配置和对应接口的开发,并负责将不同硬件设备的数据转换为统一的事件,
通过子系统提供的API接口向输入核心汇报。

输入核心参(类似platform_bus)
承上启下的作用上到用户空间的lient,同时提供设备注册和事件层注册并负责设备和事件层的匹配,同时负责通知事件层处理事件,并在、proc等目录下产生相应的信息文件接口。

事件层(platform_drivers)
       负责对设备上报的事件进行处理,中间还引入了input_client的概念,input设备的时间层负责上对接用户空间下对接输入核心层,一个输入设备每次被打开依次设备驱动驱动层就会创建一个client,
事件处理层就负责将设备上报的事件放到每个client然后由用户读写。

中间链接件
      输入子系统的几个部分其中的input_dev(输入设备)和input_handler(事件处理层),当他们俩任何一个新注册进子系统时由子系统核心进行匹配,如果匹配成功将创建一个handle用来绑定dev和handler
这里要注意区分handler和handle 这两个太像了。

总体用一个图片来表示就是:

参考:https://www.sohu.com/a/128794317_610671

再来看一点输入子系统core的相关内容----事件和事件map等相关的宏的含义及设置方法。

事件省略了一些内容:

  1. struct input_dev {
  2.  
  3. unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
  4.  
  5. unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
  6. unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
  7. unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
  8. unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
  9. unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
  10. unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
  11. unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
  12. unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
  13. unsigned long swbit[BITS_TO_LONGS(SW_CNT)];



  14. };

具体是怎么描述的设备的的可以从如下接口“可见一斑”:

  1. void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)
  2. {
  3. switch (type) {
  4. case EV_KEY:
  5. __set_bit(code, dev->keybit);
  6. break;
  7.  
  8. case EV_REL:
  9. __set_bit(code, dev->relbit);
  10. break;
  11.  
  12. case EV_ABS:
  13. input_alloc_absinfo(dev);
  14. if (!dev->absinfo)
  15. return;
  16.  
  17. __set_bit(code, dev->absbit);
  18. break;
  19.  
  20. case EV_MSC:
  21. __set_bit(code, dev->mscbit);
  22. break;
  23.  
  24. case EV_SW:
  25. __set_bit(code, dev->swbit);
  26. break;
  27.  
  28. case EV_LED:
  29. __set_bit(code, dev->ledbit);
  30. break;
  31.  
  32. case EV_SND:
  33. __set_bit(code, dev->sndbit);
  34. break;
  35.  
  36. case EV_FF:
  37. __set_bit(code, dev->ffbit);
  38. break;
  39.  
  40. case EV_PWR:
  41. /* do nothing */
  42. break;
  43.  
  44. default:
  45. pr_err("input_set_capability: unknown type %u (code %u)\n",
  46. type, code);
  47. dump_stack();
  48. return;
  49. }
  50.  
  51. __set_bit(type, dev->evbit);
  52. }

可以从输入设备的结构体定义内容看到,输入系统共支持的输入类型有事件设备,按键设备,相对坐标,,,,声音控制,,开关等类型事件。也可以从头文件中的定义看到

  1. #define EV_SYN 0x00 //同步事件
  2. #define EV_KEY 0x01 //按键事件
  3. #define EV_REL 0x02 //相对坐标
  4. #define EV_ABS 0x03 //绝对坐标
  5. #define EV_MSC 0x04 //杂项事件
  6. #define EV_SW 0x05 //开关类型事件
  7. #define EV_LED 0x11 //led展示事件(如键盘状态灯)
  8. #define EV_SND 0x12 //声音事件
  9. #define EV_REP 0x14 //重复事件
  10. #define EV_FF 0x15 //力反馈事件
  11. #define EV_PWR 0x16 //电源事件 好像从接口看暂时不支持
  12. #define EV_FF_STATUS 0x17
  13. #define EV_MAX 0x1f
  14. #define EV_CNT (EV_MAX+1)
  15. /*所以通过上面的接口我盟知道设备支持的时间类型是由evbit位图来标记的,对于具体设备的code则有具体的设备类型的位图来记录。比如前面的gpio_key调用传入的事件类型是按键,而code就是具体按键的键值这个有设备平台信息携带。接下来看一下常见类型的code首先是容易理解的按键当然code就是键值如下不完全列出也不详细解释具体含义。*/
  16.  
  17. #define KEY_ESC 1
  18. #define KEY_1 2
  19. #define KEY_2 3
  20. #define KEY_3 4
  21. #define KEY_4 5
  22. #define KEY_5 6



  23. //相对坐标
  24. #define REL_X 0x00 //这个代表x轴位移
  25. #define REL_Y 0x01 //这个代表y轴位移
  26. #define REL_Z 0x02 //代表z轴位移
  27. #define REL_RX 0x03 //也是一种轴吧
  28. #define REL_RY 0x04
  29. #define REL_RZ 0x05
  30. #define REL_HWHEEL 0x06
  31. #define REL_DIAL 0x07
  32. #define REL_WHEEL 0x08
  33. #define REL_MISC 0x09
  34.  
  35. //绝对坐标,具体含义基本可以通过名字看出来也不完全列出来
  36. #define ABS_X 0x00
  37. #define ABS_Y 0x01
  38. #define ABS_Z 0x02
  39. #define ABS_RX 0x03
  40. #define ABS_RY 0x04
  41. #define ABS_RZ 0x05
  42. #define ABS_THROTTLE 0x06
  43. #define ABS_RUDDER 0x07
  44. #define ABS_WHEEL 0x08
  45. #define ABS_GAS 0x09
  46. #define ABS_BRAKE 0x0a
  47. #define ABS_HAT0X 0x10
  48. //其余的还有开关类的,杂项类,LED的等,同时设备的总线输入子系统也定义了就如下几种类型
  49. #define BUS_PCI 0x01
  50. #define BUS_ISAPNP 0x02
  51. #define BUS_USB 0x03
  52. #define BUS_HIL 0x04
  53. #define BUS_BLUETOOTH 0x05
  54. #define BUS_VIRTUAL 0x06
  55.  
  56. #define BUS_ISA 0x10
  57. #define BUS_I8042 0x11
  58. #define BUS_XTKBD 0x12
  59. #define BUS_RS232 0x13
  60. #define BUS_GAMEPORT 0x14
  61. #define BUS_PARPORT 0x15
  62. #define BUS_AMIGA 0x16
  63. #define BUS_ADB 0x17
  64. #define BUS_I2C 0x18
  65. #define BUS_HOST 0x19
  66. #define BUS_GSC 0x1A
  67. #define BUS_ATARI 0x1B
  68. #define BUS_SPI 0x1C

最后再来看一下输入子系统上报的事件的封装结构体,这结构体定义在\include\uapi\linux\input.h 说明用户也是可以使用上面这些内容和定义的如事件

  1. struct input_event {
  2. struct timeval time;
  3. __u16 type;
  4. __u16 code;
  5. __s32 value;
  6. };

其中type和code就是前面提及的时间类型和code最后的value就是事件的具体值,到这里输入子系统的相关内容就算基本结束了,很多细节没有去仔细的看还是我自己的习惯
学习时关注重点粗线条,使用中熟悉细节。

Linux 驱动框架---input子系统框架的更多相关文章

  1. 【Linux高级驱动】input子系统框架【转】

    转自:http://www.cnblogs.com/lcw/p/3802617.html [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架?    1) 通过网 ...

  2. 【Linux高级驱动】input子系统框架

    [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架?    1) 通过网络搜索    2) 自己想办法跟内核代码!         2.1 定位此驱动是属于哪种类 ...

  3. Linux 驱动框架---input子系统

    input 子系统也是作为内核的一个字符设备模块存在的,所以他也是字符设备自然也会有字符设备的文件接口.input子系统的注册过程主要分为两步,先注册了一个input class然后再注册一个字符设备 ...

  4. 【驱动】input子系统全面分析

    初识linux输入子系统 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputC ...

  5. input子系统框架

    废话不多说,直接进入主题.在驱动insmod后,我们应用层对input设备如何操作?以下以全志a64为实例. 在/dev/input/eventX下(X的形成为后续会分析),是内核把接口暴露给应用层, ...

  6. 【驱动】input子系统整体流程全面分析(触摸屏驱动为例)【转】

    转自:http://www.cnblogs.com/lcw/p/3294356.html input输入子系统整体流程 input子系统在内核中的实现,包括输入子系统(Input Core),事件处理 ...

  7. linux内核中有哪些子系统(框架)呢?

    注意: 分析用的linux内核版本为5.1.3 1. RTC子系统 2. Remote Processor子系统 3. Remote Processor Message子系统 4. SCSI子系统 5 ...

  8. linux驱动模型<输入子系统>

    在linux中提供一种输入子系统的驱动模型,其主要是实现在input.c中. 在输入子系统这套模型中,他把驱动分层分类.首先分为上下两层,上层为input.c .下层为驱动的实现,下层分为两部分,一部 ...

  9. Linux驱动之输入子系统简析

    输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动.键盘按下等通过Driver->Inputcore->Event handler->userspac ...

随机推荐

  1. 小白都看得懂的Javadoc使用教程

    Javadoc是什么 官方回答: Javadoc is a tool for generating API documentation in HTML format from doc comments ...

  2. CentOS7,非LVM根分区扩容步骤:

    1.查看现有的分区大小 非LVM分区,目前磁盘大小为40G,根分区总容量为40G,(是自定义分区安装的) 2.关机增加磁盘大小至100G 如果你们是vmwaer虚拟软件安装的那如下入扩容: 3.查看磁 ...

  3. Spring Data JPA基本增删改查和JPQL查询(含完整代码和视频连接)

    问题:SpringDataJPA怎么使用? 一.考察目标 主要考核SpringDataJPA的用法 二.题目分析 spring data jpa 的使用步骤(下面有具体实现细节) 1.创建maven工 ...

  4. 服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决

    https://mp.weixin.qq.com/s/VRQ_12tzy3gRYD091cI7Ew

  5. 记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c359719435/article/details/80300433

    记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c3 ...

  6. Python的交互模式和直接运行.py文件有什么区别

    使用文本编辑器 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/wiki/1016959663602400/1017024645952992 直接输入python进入交互 ...

  7. 不识Netty真面目,只缘未读此真经

    Netty官网:https://netty.io/ Netty is an asynchronous event-driven network application framework for ra ...

  8. python基础三---- time模块,函数的定义和调用

    此处重点说明一下: 注意: 1.用例之间不要存在依赖关系,每个用例都可以单独运行 2.用例不要互相调用,需要调用的公共方法可以写成方法去调用 1.等待 (在脚本运行的时候,有些线程之间需要间隔时间,可 ...

  9. 关于ckfinder上传文件时不能根据结果返回自定义操作问题?

    最近项目中为了便于文件的管理,所以CMS项目中使用到了ckfinder插件,但是在使用的过程中,发现其自带的上传事件,如果上传重名的文件,该工具会自动提示错误,显示上传失败.但是如果想要自己去处理重名 ...

  10. Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作

    Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作 1.sparkstreaming实时写入Hbase(saveAsNewAPIHadoopDataset方法 ...