前面从具体(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等相关的宏的含义及设置方法。

事件省略了一些内容:

struct input_dev {

    unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];

    unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
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)];



};

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

void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)
{
switch (type) {
case EV_KEY:
__set_bit(code, dev->keybit);
break; case EV_REL:
__set_bit(code, dev->relbit);
break; case EV_ABS:
input_alloc_absinfo(dev);
if (!dev->absinfo)
return; __set_bit(code, dev->absbit);
break; case EV_MSC:
__set_bit(code, dev->mscbit);
break; case EV_SW:
__set_bit(code, dev->swbit);
break; case EV_LED:
__set_bit(code, dev->ledbit);
break; case EV_SND:
__set_bit(code, dev->sndbit);
break; case EV_FF:
__set_bit(code, dev->ffbit);
break; case EV_PWR:
/* do nothing */
break; default:
pr_err("input_set_capability: unknown type %u (code %u)\n",
type, code);
dump_stack();
return;
} __set_bit(type, dev->evbit);
}

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

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



//相对坐标
#define REL_X 0x00 //这个代表x轴位移
#define REL_Y 0x01 //这个代表y轴位移
#define REL_Z 0x02 //代表z轴位移
#define REL_RX 0x03 //也是一种轴吧
#define REL_RY 0x04
#define REL_RZ 0x05
#define REL_HWHEEL 0x06
#define REL_DIAL 0x07
#define REL_WHEEL 0x08
#define REL_MISC 0x09 //绝对坐标,具体含义基本可以通过名字看出来也不完全列出来
#define ABS_X 0x00
#define ABS_Y 0x01
#define ABS_Z 0x02
#define ABS_RX 0x03
#define ABS_RY 0x04
#define ABS_RZ 0x05
#define ABS_THROTTLE 0x06
#define ABS_RUDDER 0x07
#define ABS_WHEEL 0x08
#define ABS_GAS 0x09
#define ABS_BRAKE 0x0a
#define ABS_HAT0X 0x10
//其余的还有开关类的,杂项类,LED的等,同时设备的总线输入子系统也定义了就如下几种类型
#define BUS_PCI 0x01
#define BUS_ISAPNP 0x02
#define BUS_USB 0x03
#define BUS_HIL 0x04
#define BUS_BLUETOOTH 0x05
#define BUS_VIRTUAL 0x06 #define BUS_ISA 0x10
#define BUS_I8042 0x11
#define BUS_XTKBD 0x12
#define BUS_RS232 0x13
#define BUS_GAMEPORT 0x14
#define BUS_PARPORT 0x15
#define BUS_AMIGA 0x16
#define BUS_ADB 0x17
#define BUS_I2C 0x18
#define BUS_HOST 0x19
#define BUS_GSC 0x1A
#define BUS_ATARI 0x1B
#define BUS_SPI 0x1C

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

struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};

其中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. Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节

    目录 Java优先队列PriorityQueue的各种打开方式以及一些你不知道的细节 优先队列的默认用法-从小到大排序 对String类用优先队列从大到小排序 通过自定义比较器对自定义的类进行从小到大 ...

  2. 目标检测的评价指标(TP、TN、FP、FN、Precision、Recall、IoU、mIoU、AP、mAP)

    1. TP TN FP FN ​ GroundTruth 预测结果 TP(True Positives): 真的正样本 = [正样本 被正确分为 正样本] TN(True Negatives): 真的 ...

  3. C++旋转数组(三种解法详解)

    题目描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 附加要求 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 ...

  4. REST 架构的替代方案 为什么说GraphQL是API的未来?

    Managing enterprise accounts - GitHub Docs https://docs.github.com/en/graphql/guides/managing-enterp ...

  5. Enables DNS lookups on client IP addresses 域名的分层结构

    虚拟域名访问,路由可以到达,但无输出. http://httpd.apache.org/docs/2.2/mod/core.html#hostnamelookups 移动解析 HttpDNS_域名解析 ...

  6. loj10008家庭作业

    题目描述 老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分.每个作业的截止日期和学分可能是不同的.例如如果一个作业学分为10 ,要求在6 天内交,那么要想拿到这 10 ...

  7. 图文并茂-超详解 CS:APP: Lab3-Attack(附带栈帧分析)

    CS:APP:Lab3-ATTACK 0. 环境要求 关于环境已经在lab1里配置过了.lab1的连接如下 实验的下载地址如下 说明文档如下 http://csapp.cs.cmu.edu/3e/at ...

  8. Spark Dataset DataFrame空值null,NaN判断和处理

    Spark Dataset DataFrame空值null,NaN判断和处理 import org.apache.spark.sql.SparkSession import org.apache.sp ...

  9. Scala:case class

    Scala:case class 1.Scala中class.object.case class.case object区别 1.1 class 和 object 关系 1.2 case class ...

  10. Effective Java读书笔记--创建和销毁对象

    1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build() ...