输入子系统二

简介: 输入子系统二

框架

Linux系统支持的输入设备繁多,例如键盘、鼠标、触摸屏、手柄或者是一些输入设备像体感输入等等,Linux系统是如何管理如此之多的不同类型、不同原理、不同的输入信息的输入设备的呢?其实就是通过input输入子系统这套软件体系来完成的。从整体上来说,input输入子系统分为3层:上层(输入事件驱动层)、中层(输入核心层)、下层(输入设备驱动层),如下图:

  • input driver :主要实现对硬件设备的读写访问,中断设置,并把硬件产生的事件转换为核心层定义的规范提交给事件处理层。
    input device driver 设备驱动程序
    input event driver事件驱动程序
    注意:事件驱动程穿是标准的,对所有的瑜入类都是可用的,所以,我们不需实现事件驱动,为内核里边已经支持所有的事件驱动;我们需实现的是输入设备备驱动程序
  • input core :承上启下。为设备驱动层提供了规范和接口;通知事件处理层对事件进行处理;
  • event handler :提供用户编程的接口(设备节点),并处理驱动层提交的数据处理。

三个重要结构体

struct input_dev

//表示的是一个具体的输入设备,描述设备能够产生什么数据
struct input_dev {
  const char *name;//sysfs中给用户看的信息
  const char *phys;
  const char *uniq;
  struct input_id id;
  unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
  unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
  /*evbit实际是一个位表,描述输入设备能够产生什么数据类型*/
  unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];//能够表示768个bit,直接用24个long来表示,
            //KEY_CNT=768 BITS_TO_LONGS=nr/32   768/32=24
  //表示能够产生哪种按键
  unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
  //表示能够产生哪种相对坐标数据
  unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
  //表示能够产生哪种绝对坐标数据
  unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
  unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
  unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
  unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
  unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
  unsigned int hint_events_per_packet;
  unsigned int keycodemax;
  unsigned int keycodesize;
  void *keycode;
  int (*setkeycode)(struct input_dev *dev,
        const struct input_keymap_entry *ke,
        unsigned int *old_keycode);
  int (*getkeycode)(struct input_dev *dev,
        struct input_keymap_entry *ke);
  struct ff_device *ff;
  unsigned int repeat_key;
  struct timer_list timer;
  int rep[REP_CNT];
  struct input_mt *mt;
  struct input_absinfo *absinfo;
  unsigned long key[BITS_TO_LONGS(KEY_CNT)];
  unsigned long led[BITS_TO_LONGS(LED_CNT)];
  unsigned long snd[BITS_TO_LONGS(SND_CNT)];
  unsigned long sw[BITS_TO_LONGS(SW_CNT)];
  int (*open)(struct input_dev *dev);
  void (*close)(struct input_dev *dev);
  int (*flush)(struct input_dev *dev, struct file *file);
  int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
  struct input_handle __rcu *grab;
  spinlock_t event_lock;
  struct mutex mutex;
  unsigned int users;
  bool going_away;
  struct device dev;//继承device对象
  struct list_head  h_list;
  struct list_head  node;//表示节点
  unsigned int num_vals;
  unsigned int max_vals;
  struct input_value *vals;
  bool devres_managed;
};

struct input_handler

struct input_handler {
  void *private;
  void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
  void (*events)(struct input_handle *handle,
           const struct input_value *vals, unsigned int count);
  bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
  bool (*match)(struct input_handler *handler, struct input_dev *dev);
  int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
  void (*disconnect)(struct input_handle *handle);
  void (*start)(struct input_handle *handle);
  bool legacy_minors;
  int minor;
  const char *name;
  const struct input_device_id *id_table;
  struct list_head  h_list;
  struct list_head  node;
};

struct input_handle

struct input_handle {
  void *private;
  int open;
  const char *name;
  struct input_dev *dev;
  struct input_handler *handler;
  struct list_head  d_node;
  struct list_head  h_node;
};
  • input_dev代表底层的设备,所有设备的input_dev对象保存在一个全局的lnput_dev队列里。
  • input_handler代表某类入设备的处理方法,比如说是专门处理入设备产成的Event〈事件〉,所有的input_handler存放在input_handler队里
  • 一个input_dev可以有多个input_handler,
  • lnput_handle用来关联某个input_dev和某个input_handler。每个input_handle都会生成一个文件节点,比如"/dev/input/event0、1、2、3…"。通过input handle可以找到对应的input handler和input_dev

三个重要结构体关系


目录
相关文章
|
10月前
|
Ubuntu Linux Windows
Linux开发环境配置详细过程--正点原子阿尔法开发板
Linux开发环境配置详细过程--正点原子阿尔法开发板
293 0
|
10月前
|
传感器
STM32F407软件模拟I2C实现MPU6050通讯(CUBEIDE)(下)
STM32F407软件模拟I2C实现MPU6050通讯(CUBEIDE)(下)
232 0
|
7月前
|
存储 缓存 监控
一种基于动态代理的通用研发提效解决方案
作为一名研发人员,除了业务开发之外,研发提效是一个永恒的话题,而女娲正是这一话题下进行的一次全面的剖析和实践。
109858 26
|
存储 缓存 网络协议
从零开始搭建一个通用的业务技术架构,这套架构有点牛逼!
从零开始搭建一个通用的业务技术架构,这套架构有点牛逼!
|
10月前
|
SQL 存储 安全
程序员必须要知道的编程范式,你掌握了吗?
本文给大家介绍了什么是"编程范式",选择合适的编程范式可以提高代码的可读性、可维护性和可扩展性。
33296 42
|
9月前
|
消息中间件 大数据 数据挖掘
深入浅出流批一体理论篇,数据架构的演进
这篇文章的主要内容包括:1、数据架构的演变历史与各种架构的优缺点。2、流批一体的价值。3、流批一体架构中流与批的关系。
49162 74
|
10月前
|
存储
libjpeg库使用实例细节分析
libjpeg库使用实例细节分析
152 0
|
10月前
|
存储 Serverless
FreeType使用实例细节分析
FreeType使用实例细节分析
146 0
|
10月前
|
存储 Linux C语言
模块的加载过程一
模块的加载过程一
102 0
|
10月前
Net: Board Net Initialization Failed No ethernet found.
Net: Board Net Initialization Failed No ethernet found.
150 0