ImageVerifierCode 换一换
格式:DOCX , 页数:37 ,大小:236.04KB ,
资源ID:10084220      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-10084220.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ARMLinux内核Input输入子系统浅析.docx)为本站会员(b****0)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

ARMLinux内核Input输入子系统浅析.docx

1、ARMLinux内核Input输入子系统浅析-以触摸屏驱动为例第一章、了解linux input子系统Linux输入设备总类繁杂,常见的包括有按键、键盘、触摸屏、鼠标、摇杆等等,他们本身就是字符设备,而linux内核将这些设备的共同性抽象出来,简化驱动开发建立了一个input子系统。子系统共分为三层,如图1所示。图1input输入子系统驱动层和硬件相关,直接捕捉和获取硬件设备的数据信息等(包括触摸屏被按下、按下位置、鼠标移动、键盘按下等等),然后将数据信息报告到核心层。核心层负责连接驱动层和事件处理层,设备驱动(device driver)和处理程序(handler)的注册需要通过核心层来完成

2、,核心层接收来自驱动层的数据信息,并将数据信息选择对应的handler去处理,最终handler将数据复制到用户空间。先了解三个定义在/linux/input.h下重要的结构体input_dev、input_handler、input_handle。struct input_dev void *private;const char *name;const char *phys;const char *uniq;struct input_id id;/与input_handler匹配用的idunsigned long evbitNBITS(EV_MAX);/设备支持的事件类型unsigned l

3、ong keybitNBITS(KEY_MAX);/按键事件支持的子事件类型unsigned long relbitNBITS(REL_MAX);unsigned long absbitNBITS(ABS_MAX);/绝对坐标事件支持的子事件类型unsigned long mscbitNBITS(MSC_MAX);unsigned long ledbitNBITS(LED_MAX);unsigned long sndbitNBITS(SND_MAX);unsigned long ffbitNBITS(FF_MAX);unsignedlongswbitNBITS(SW_MAX);int ff_e

4、ffects_max;unsigned int keycodemax;unsigned int keycodesize;void *keycode;unsigned int repeat_key;struct timer_list timer;struct pt_regs *regs;int state;int sync;int absABS_MAX + 1;int repREP_MAX + 1;unsigned long keyNBITS(KEY_MAX);unsigned long ledNBITS(LED_MAX);unsigned long sndNBITS(SND_MAX);unsi

5、gnedlongswNBITS(SW_MAX);int absmaxABS_MAX + 1;/绝对坐标事件的最大键值int absminABS_MAX + 1;/绝对坐标事件的最小键值int absfuzzABS_MAX + 1;int absflatABS_MAX + 1;int (*open)(struct input_dev *dev);void (*close)(struct input_dev *dev);int (*accept)(struct input_dev *dev, struct file *file);int (*flush)(struct input_dev *dev

6、, struct file *file);int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect);int (*erase_effect)(struct input_dev *dev, int effect_id);struct input_handle *grab;/当前占有该设备的handlestruct mutex mutex;/* ser

7、ializesopenand close operations */unsigned int users;/打开该设备的用户量struct class_device cdev;struct device *dev;/* will be removed soon */int dynalloc;/* temporarily */struct list_headh_list;/该链表头用于链接该设备所关联的input_handlestruct list_headnode;/该链表头用于将设备链接到input_dev_list;Input_dev是一个很强大的结构体,它把所有的input设备(触摸屏、

8、键盘、鼠标等)的信息都考虑到了,对于触摸屏来说只用到它里面的一部分而已,尤其是加粗的部分,注意该结构体中最后两行定义的两个list_head结构体,list_head在/linux/list.h中有定义,深入跟踪struct list_head struct list_head *next, *prev;该结构体内部并没有定义数据而只定义了两个指向本身结构体的指针,预先说明一下,所有的inputdevice在注册后会加入一个input_dev_list(输入设备链表),所有的eventhandler在注册后会加入一个input_handler_list(输入处理程序链表),这里的list_he

9、ad主要的作用是作为input_dev_list和input_handler_list的一个节点来保存地址。Input_dev_list和input_handler_list之间的对应关系由input_handle结构体桥接,具体后面说明。struct input_handler void *private;void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);struct input_handle* (*connect)(struct input_handler

10、*handler, struct input_dev *dev, struct input_device_id *id);void (*disconnect)(struct input_handle *handle);const struct file_operations *fops;/提供给用户对设备操作的函数指针int minor;char *name;struct input_device_id *id_table;/与input_dev匹配用的idstruct input_device_id *blacklist;/标记的黑名单struct list_headh_list;/用于链接

11、和该handler相关的handlestruct list_headnode;/用于将该handler链入input_handler_list;input_handler顾名思义,它是用来处理input_dev的一个结构体,相关的处理函数在结构里内部都有定义,最后两行定义的list_head结构体作用同input_dev所定义的一样,这里不再说明。注:input_device_id结构体在/linux/mod_devicetable.h中有定义struct input_handle void *private;intopen;/记录设备打开次数char *name;struct input_d

12、ev *dev;/指向所属的input_devstruct input_handler *handler;/指向所属的input_handlerstruct list_headd_node;/用于链入所指向的input_dev的handle链表struct list_headh_node;/用于链入所指向的input_handler的handle链表;可以看到input_handle中拥有指向input_dev和input_handler的指针,即input_handle是用来关联input_dev和input_handler。为什么用input_handle来关联input_dev和inpu

13、t_handler而不将input_dev和input_handler直接对应呢?因为一个device可以对应多个handler,而一个handler也可处理多个device。就如一个触摸屏设备可以对应event handler也可以对应tseve handler。input_dev、input_handler、input_handle的关系如下图2所示。图2input_dev,input_handler,input_handle关系图第二章、inputdevice的注册Inputdevice的注册实际上仅仅只有几行代码,因为在input.c中已经将大量的代码封装好了,主需要调用几个关键的函数

14、就能完成对input device的注册。在xxx_ts.c中预先定义全局变量struct input_devtsdev;然后进入到初始化函数static int _init xxx_probe(struct platform_device *pdev)if (!(tsdev = input_allocate_device()printk(KERN_ERR tsdev: not enough memoryn);err = -ENOMEM;goto fail;tsdev-name = xxx TouchScreen;/xxx为芯片型号tsdev -phys = xxx/event0;tsdev

15、-id.bustype = BUS_HOST;/设备id,用于匹配handler的idtsdev -id.vendor= 0x0005;tsdev -id.product = 0x0001;tsdev -id.version = 0x0100;tsdev -open= xxx_open;tsdev -close=xxx_close;tsdev -evbit0 = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_SYN);/设置支持的事件类型tsdev -keybitLONG(BTN_TOUCH) = BIT(BTN_TOUCH);input_set_abs_params(

16、tsdev, ABS_X, 0, 0x400, 0, 0);/限定绝对坐标X的取值范围input_set_abs_params(tsdev, ABS_Y, 0, 0x400, 0, 0);/同上input_set_abs_params(tsdev, ABS_PRESSURE, 0, 1000, 0, 0);/触摸屏压力值范围If(input_register_device(tsdev) = error)/注册设备goto fail;fail:input_free_device(tsdev);printk(“ts probe failedn”);return err;先看该函数中的tsdev =

17、 input_allocate_device(),深入最终,该函数在input.c中有定义struct input_dev *input_allocate_device(void)struct input_dev *dev;dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);if (dev) dev-dynalloc = 1;dev-cdev.class = &input_class;class_device_initialize(&dev-cdev);INIT_LIST_HEAD(&dev-h_list);INIT_LIST_HEAD(&d

18、ev-node);return dev;学过C语言应该都知道malloc函数(开辟内存空间),而这里的kzalloc也类似于C语言中的malloc一样,是linux内核空间分配内存函数,后面的GFP_KERNEL标志意为常规的内存分配,更多的分配标志可参阅先关资料(我也不懂)。再回到前面的函数中来,接着后面的代码为对tsdev结构体中的成员进行赋值初始化,赋值完成后就要开始进入主题:注册设备了,进入到函数input_register_device(tsdev),该函数在input.c中有定义。int input_register_device(struct input_dev *dev)sta

19、tic atomic_t input_no = ATOMIC_INIT(0);/定义原子变量,禁止线程并发访问struct input_handle *handle;/定义一些变量备后文使用struct input_handler *handler;struct input_device_id *id;const char *path;int error;if (!dev-dynalloc) printk(KERN_WARNING input: device %s is statically allocated, will not registernPlease convert to inpu

20、t_allocate_device() or contact*n,dev-name ? dev-name : );return -EINVAL;mutex_init(&dev-mutex);/互斥锁初始化,防止临界区代码被并发访问set_bit(EV_SYN, dev-evbit);/设置支持同步事件,input设备全部默认支持同步事件/* If delay and period are pre-set by the driver, then autorepeating* is handled by the driver itself and we dont do it in input.c.

21、*/init_timer(&dev-timer);if (!dev-repREP_DELAY & !dev-repREP_PERIOD) dev-timer.data = (long) dev;dev-timer.function = input_repeat_key;dev-repREP_DELAY = 250;dev-repREP_PERIOD = 33;INIT_LIST_HEAD(&dev-h_list);/初始化需要关联的handle链表头list_add_tail(&dev-node, &input_dev_list);/将设备添加到input_dev_list中dev-cdev.

22、class = &input_class;snprintf(dev-cdev.class_id, sizeof(dev-cdev.class_id),input%ld, (unsignedlong) atomic_inc_return(&input_no) - 1);error = class_device_add(&dev-cdev);if (error)return error;error = sysfs_create_group(&dev-cdev.kobj, &input_dev_attr_group);if (error)goto fail1;error = sysfs_create

23、_group(&dev-cdev.kobj, &input_dev_id_attr_group);if (error)goto fail2;error = sysfs_create_group(&dev-cdev.kobj, &input_dev_caps_attr_group);if (error)goto fail3;_module_get(THIS_MODULE);path = kobject_get_path(&dev-cdev.kobj, GFP_KERNEL);printk(KERN_INFO input: %s as %sn,dev-name ? dev-name : Unspe

24、cified device, path ? path : N/A);kfree(path);/*遍历input_handler_list上全部的handler,寻找与该设备匹配的handler*/list_for_each_entry(handler, &input_handler_list, node)if (!handler-blacklist | !input_match_device(handler-blacklist, dev)if (id = input_match_device(handler-id_table, dev)if (handle = handler-connect(

25、handler, dev, id)input_link_handle(handle);input_wakeup_procfs_readers();return 0;fail3:sysfs_remove_group(&dev-cdev.kobj, &input_dev_id_attr_group);fail2:sysfs_remove_group(&dev-cdev.kobj, &input_dev_attr_group);fail1:class_device_del(&dev-cdev);return error;先看函数中前面代码加粗的部分mutex_init(&dev-mutex),与互斥锁相关的东西(我也不太懂),set_bit(EV_SYN, dev-evbit)设置支持同步事件,linux的input子系统默认

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2