ARM Linux内核Input输入子系统浅解(4)

2020-05-05 15:57

if (handler->fops != NULL)

input_table[handler->minor >> 5] = handler;

list_add_tail(&handler->node, &input_handler_list);

list_for_each_entry(dev, &input_dev_list, node) if (!handler->blacklist

|| !input_match_device(handler->blacklist, dev))

if ((id = input_match_device(handler->id_table, dev))) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle);

input_wakeup_procfs_readers(); }

该函数中代码加粗的部分,与input_register_device()函数里的如出一辙,这里不再做说明。

至此input_handler的注册已经结束。

第四章、input子系统数据结构

下图3是以触摸屏设备为例子的input子系统数据结构图。

图3 input子系统数据结构图

进行到这里,又多冒出来了一个struct evdev_list的结构体,这在之前并没有提到过,因为在注册input_dev和input_handler过程中并没有用到过,查看该结构体:

struct evdev_list {

struct input_event buffer[EVDEV_BUFFER_SIZE]; //存放设备数据信息

int head; //buffer的下标,标识从设备中过来要存放到buffer的数据的位置

int tail; //buffer的下标,标识用户读取buffer中数据的下标位置 struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; };

注意里面的input_event结构体,在/linux/input.h中有定义: struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };

该input_event结构体就是存放着用户层所需的数据信息,这里想必我们都明白,则在struct evdev_list结构体中的struct input_event buffer[EVDEV_BUFFER_SIZE];就是存放着用户所需的数据信息,从硬件设备(触摸屏)获取得到的数据信息最终会存放到该数组中,而struct evdev_list结构体是在什么时候定义的呢?

当然是在被open的时候,查看open函数:

static int evdev_open(struct inode * inode, struct file * file) {

struct evdev_list *list; //定义一个evdev_list结构体 int i = iminor(inode) - EVDEV_MINOR_BASE; int accept_err;

if (i >= EVDEV_MINORS || !evdev_table[ i] || !evdev_table[ i]->exist) return -ENODEV;

if ((accept_err = input_accept_process(&(evdev_table[ i]->handle), file))) return accept_err;

if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) //开辟evdev_list结构体内存空间 return -ENOMEM;

list->evdev = evdev_table[ i]; //令结构体中的evdev指针指向evdec_table[ i]

list_add_tail(&list->node, &evdev_table[ i]->list); //加入链表 file->private_data = list;

if (!list->evdev->open++) //如果设备没有被open,则继续if操作

if (list->evdev->exist)

input_open_device(&list->evdev->handle); //打开设备

return 0; }

注意函数中代码加粗的部分,都有注释说明,在最后以一个操作

input_open_device(&list->evdev->handle);继续跟踪进入该函数 int input_open_device(struct input_handle *handle) {

struct input_dev *dev = handle->dev; int err;

err = mutex_lock_interruptible(&dev->mutex); if (err)

return err;

handle->open++; //handle的内部成员open++ if (!dev->users++ && dev->open) err = dev->open(dev); if (err)

handle->open--;

mutex_unlock(&dev->mutex);

return err; }

函数中加粗的部分,为什么要让open++呢?因为数据要从device传到handler过程中有一个环节需要判断handle->open是否为真,为真表示设备已经打开数据可以传递,这点在下一章将会介绍到。

第四章、数据传递过程

正如图1所示,从硬件设备(触摸屏)中获得的数据需要经过input.c选择相应的handler进行处理,最后上报到用户空间。如何从硬件设备(触摸屏)中获得数据,那就得看xxx_ts.c中的代码了,在xxx_ts.c中的源代码是直接和硬件设备相关的。在xxx_ts.c中我们一方面要完成触摸屏设备相关的寄存器配置,另一方面要完成将获得的数据上报。

至于设备初始化配置方面,根据每个人使用的ARM芯片的Datasheet去初始化配置寄存器,这里也不需要多说了。不管是通过查询法还是中断法(我没见过用查询的),当触摸屏按下时候我们会得到触摸屏被按下的相关数据(主要是被

按下的X和Y坐标值),然后需要将数据信息上报,在触摸屏被按下的时候需要上报:

input_report_key(tsdev, BTN_TOUCH, 1); //报告按键被按下事件 input_report_abs(tsdev, ABS_X, x); //报告触摸屏被按下的x坐标值

input_report_abs(tsdev, ABS_Y, y); //报告触摸屏被按下的y坐标值

input_report_abs(tsdev, ABS_PRESSURE, 1); //报告触摸屏被按下的压力值(0或者1)

input_sync(tsdev); //报告同步事件,表示一次事件结束

当触笔从触摸屏上抬起时需要上报:

input_report_key(tsdev, BTN_TOUCH, 0); //报告按键被松开事件 input_report_abs(tsdev, ABS_PRESSURE, 0); //报告触摸屏被按下的压力值(0或者1)

input_sync(tsdev); //报告同步事件,表示一次事件结束

先不管input_sync()函数,先来看input_report_key()和input_report_abs(),这两个函数在/linux/input.h中有定义:

static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) {

input_event(dev, EV_KEY, code, !!value); }

static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value) {

input_event(dev, EV_ABS, code, value); }

太坑爹了,这两个函数里面也就值调用了一个函数(我也不明白linux内核开发者为什么要这么做),继续跟踪查看input_event()函数,在input.c中有定义: void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) {

struct input_handle *handle;

if (type > EV_MAX || !test_bit(type, dev->evbit)) return;

add_input_randomness(type, code, value);

switch (type) {

case EV_KEY: //判断为按键事件


ARM Linux内核Input输入子系统浅解(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:行政村(居)基本情况进行调查摸底表

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: