完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/************************************************************************ author: 安徽理工大学——刘成 funtion: Linux的输入子系统详解 instruction: 配合linux—2.6.22.6内核 date: 2014-8-14 ************************************************************************/ Linux的输入子系统可支持鼠标、键盘,触摸屏等设备.网上资料较多而过于繁杂,今天我来做一个总结: 以前我们写一个驱动如xxx_driver.c(所涉及就这么一个文件,做实验直接insmod xxx_driver.KO即可)在该源文件中我们会初始化一个file_operations结构,以使该设备具备可以被打开,读,写等等,然后module_init函数会注册这个驱动,创建类,创建设备,最后我们做实验直接insmod,在应用程序的测试程序中open,然后读写以观察效果。 linux输入子系统采用了分离分层的理念,我们关心的是自己的input_device(内核中为input_dev结构),但是对于input-core和input_handler的工作框架需掌握其工作流程,现在以可支持所有设备的edev.c为例,配合input.C描述其过程: 第一阶段: 首先input.c和edev.C的module_init会被放在初始化代码段中,在内核启动后自动被调用然后释放函数及数据占用的内存,故而这两个内核模块已经在一开始就被动态加载进内核了(还可以查看源码顶层目录中的.config文件可以看到关于input和edev已经被选编进内核)。在input.c中初始化file_operations,其只有一个open函数即input_open_file,但是稍安勿躁,这里的input_open_file结构会在以后被重新充实。在input的init中会创建类,注册以13主设备号,input为驱动名以及input_fops,(此时就可以用cat /proc/devices 看到内核中已经有了主设备号为13的input的驱动程序。)且input_fops已经被注册进内核。随着edev.C在内核启动时也被自动调用,其init中的input_register_handler被调用,此函数将本edev的handler放在input_table[2],并将本edev的handler加入input_handler_list(此链表中有多个handler如joy_handler,keyboard.handler等等)然后将针对设备队列中的每个设备调用input_attatch_handler,用input_match_device根据该edev_handler的id_table(包含了该驱动可以处理的设备的信息)与每个设备进行比对后(这里的设备会发生何种事件,这种事件里的哪个具体事件发生会在我们自己写的device中的init中用set_bit来通过input_dev结构告诉内核。并且在自己的device的init中会调用input_register_device注册该input_dev结构,从而会试图遍历input_handler_list中的每个handler,以找到能够处理该设备的handler,然后该handler的connect,这里为edev_connnect函数建立起该设备input_dev与该驱动handler的联系,此时将handle结构初始化,且将其分别放入凭id_table功能匹配完毕的dev和handler的h_list中,这样设备和驱动便建立了联系)能够处理这个设备则进行连接,即调用该handler的connect函数,该connect函数会创建一个edev结构体并且初始化其handle结构,以让该结构指向匹配成功的dev和handler,随后会创建一个以该edev.程序中标定的设备名的设备节点,此设备节点主设备号为13,此设备号为65,然后注册该handle,使该handle节点存于该input_dev的h_list和该input_handler的h_list中。此时相当于完成了普通字符设备驱动程序的驱动注册,类的创建,设备的创建(但注意此时进入内核中的input_fops还没有被完善)。 第二阶段: 当我们去查看设备时,会看到刚开始由edev.C中connect函数创建的设备,我们打开该设备,此时会调用input.C中的input_open_file,input_open_file函数会在input_table[2]中找到一个handler(因为该input_table[]数组已经被edev.C中的init函数调用input_register_handler时设置),即找到了这个input_handler结构,此时会将内核中的input_fops充实。并将调用这个handler中的open函数打开该文件,打开时会调用input_open_device函数将edev结构中的handle加一 当我们读这个文件时,会调用edev_handler中的读函数,会发生阻塞等事件。在我们自己写的device中若按下按键会触发中断,中断函数调用input_event上报事件,它会将该设备的h_list中的每一个handle拿出来,看哪个被加一了,说明就该调用那个驱动的event函数,则通过该handle找到其handler成员且调用其event,即调用了edev_event,从而在可以在这个函数中存储数据,唤醒中断。
|
|
|
|
只有小组成员才能发言,加入小组>>
「含关键代码」基于AM3352/AM3354/AM3359的Linux开发案例分享
4868 浏览 0 评论
87358 浏览 0 评论
【高手问答】如何做到精通linux技术?资深工程师带你突破难点
4680 浏览 2 评论
3567 浏览 2 评论
解读Linux :先从创建一个文件夹用来存放jdk压缩文件开始
2453 浏览 0 评论
1951浏览 3评论
这是i.mx6ull的关于usb的宏定义,能解释下这些宏定义的意思
1319浏览 1评论
1230浏览 1评论
求解:aarch64交叉编译工具已经安装成功,环境变量已经配置,怎么将系统架构切换为ARM的架构
1295浏览 0评论
电脑和虚拟机可以互ping,电脑和开发板也可以互ping,但是虚拟机和开发板ping不通是什么原因
1212浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 23:15 , Processed in 1.190034 second(s), Total 42, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号