android输入子系统(以矩阵按键为例)

输入子系统有输入子系统核心层(input core),驱动层和事件处理层(event handler)三部分组成。一个输入事件,如如鼠标移动,键盘按键按下等等通过Driver->inputCore->Eventhandler->userspace的顺序打到用户空间传给应用程序。其中Inputcore由driver/input/input.c及相关头文件实现。对下提供了设备驱动的接口,多上提供了eventhandler层的编程接口。驱动层负责和底层的硬件设备打交道,将底层对用户输入的响应转换成标准事件输入后再向上发给inputcore层。驱动层通过调用Input_register_device和Input_unregister_device函数来向输入子系统注册和注销输入设备。这两个参数调用的是一个Input_dev结构,这个结构在diver/input/input.h中定义。驱动层在调用input_register_device之前需要填充该结构体的部分字段。

1、 输入子系统架构

  输入子系统架构(inputsubsystem)如图所示



1.1、 主要数据结构

  主要数据结构如表所示:


二、输入链路的创建过程

由于input子系统通过分层将一个输入设备的输入过程分割为两个独立的两部分:驱动到inputcore,input core到eventhandler。所以整个链路的这两部分的创建是独立的。

 

1、硬件设备的注册

驱动层负责和底层的硬件设备打交道,将底层对用户输入的响应转换为标准的输入时间以后再向上发送给 inputcore。驱动层通过调用Input_register_device和Input_unregister_device函数来向输入子系统注册和注销输入设备。这两个参数调用的是一个Input_dev结构,这个结构在diver/input/input.h中定义。驱动层在调用input_register_device之前需要填充该结构体的部分字段。

 

以下代码摘自矩阵键盘驱动里的部分代码,具体内容请看完整代码:

input_dev = input_allocate_device();
……
input_dev->name = DEVICE_NAME;
	input_dev->phys = "s3c-keypad/input0";

	input_dev->id.bustype = BUS_HOST;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0001;

	input_dev->keycode = keypad_keycode;
ret = input_register_device(input_dev);
	if (ret) {
		pr_err("Unable to register s3c-keypad input device!!!\n");
		goto out;
	}

2、设置所支持的事件

Input子系统通过函数set_bit()告诉input core它支持哪些事件,set_bit()有两个参数,第二个参数为有两个成员,一个是evbit:事件类型,另一个是keybit:按键类型。其中比较重要的是evbit成员,它的子集为以下参数组成。

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_LED     0x11   /*LED 灯设备*/
7. #define EV_SND     0x12  /*蜂鸣器,输入声音*/
8. #define EV_REP     0x14   /*允许重复按键类型*/
9. #define EV_PWR     0x16   /*电源管理事件*/

一个设备可以支持多个事件类型。每个事件类型下面还需要设置具体的触发事件,比如EV_KEY ,支持哪些按键等。

 

以下代码摘自矩阵键盘驱动里的部分代码,具体内容请看完整代码:

for (key = 0; key < s3c_keypad->total_keys; key++)
	{
		code = s3c_keypad->keycodes[key] = keypad_keycode[key];
		if (code <= 0)
			continue;
		set_bit(code & KEY_MAX, input_dev->keybit);
	}

3、事件的上报

那么当在底层驱动事件发生了的时候,如何用户空间如何知道呢?这就需要input core提供的接口函数来向input_core报告 。

不同的事件需要用不同的接口函数来向上层报告事件的发生,具体有以下几个上报函数。

void input_report_key();   /*用于上报EV_KEY事件*/

void input_report_rel();   /*用于上报EV_REL事件*/

void input_report_abs();   /*用于上报EV_ABS事件*/

    其中矩阵键盘驱动代码用到的是input_report_key()函数。

 

以下代码摘自矩阵键盘驱动里的部分代码,具体内容请看完整代码:

while (release_mask)
		{
			if (release_mask & 1)
			{
				input_report_key(dev, pdata->keycodes[i], 0);
				pr_debug("key Released : %d map %d\n",i, pdata->keycodes[i]);
			}
			release_mask >>= 1;
			i++;
		}

在完成了事件的上报了之后,还必须要需要告诉input_core本次的时间已经的完成

所使用的函数为 input_sync() 。 

 

4、输入子系统总结

在键盘驱动代码分中,接触采用了input子系统机制。键盘驱动将检测到的所有按键都上报给了input子系统。Input子系统是所有I/O设备驱动的中间层,为上层提供了一个统一的界面。例如,在终端系统中,我们不需要去管有多少个键盘,多少个鼠标。它只要从input子系统中去取对应的事件(按键,鼠标移位等)就可以了。今天就对input子系统做一个详尽的分析

这样,可以简化驱动程序,而且可以简单地完成按键的工作,省去了设备驱动的中间层的编写。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键矩阵按键

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值