当前位置: 首页 > news >正文

网站建设艾瑞市场分析做铝材哪些网站招聘

网站建设艾瑞市场分析,做铝材哪些网站招聘,腾讯云wordpress对象储存,试卷页面设计模板简单分层 应用层 内核层 --------------------------- input handler 数据处理层 driver/input/evdev.c1.和用户空间交互,实现fops2.不知道数据怎么得到的,但是可以把数据上传给用户--------------------------- input core层1.维护上面和下面的两个链表2.为上下两层提供接口--…简单分层 应用层 内核层 --------------------------- input handler 数据处理层 driver/input/evdev.c1.和用户空间交互,实现fops2.不知道数据怎么得到的,但是可以把数据上传给用户--------------------------- input core层1.维护上面和下面的两个链表2.为上下两层提供接口---------------------------- input device层---driver/input/input.c1.初始化硬件,获取硬件数据2.知道数据是什么样,不知道如何把数据给用户具体 第一步 注册顺序最开始应该是 input_coer层,锁定函数 input/input.c 核心层,得创建链表把,图中的两个链表,方便进行匹配 class_register() //注册这个输入子系统类,同时这个类的主设备号都分配为13 同时这里两个链表 第一个是 input_handler_list 存放结构体 input_handler 可以理解是对这个输入dev的操作实例或方案 第二个是 input_dev_list 这么多输入设备,需要放进来和第一个链表进行匹配 1.input_coer应该是第一个核心层,得创建链表把,看看input_.c文件 同时input.c中还注册了主设备号为13的类和fopsinput_init(void)class_register(input_class);err input_proc_init();//感觉像bus总线的新玩法,注册bus总线上的input子系统proc_bus_input_dir proc_mkdir(bus/input, NULL);entry proc_create(devices, 0, proc_bus_input_dir,input_devices_fileops);//应该是bus总线里面的注册device文件夹static const struct file_operations input_devices_fileops { //对这个文件夹里面的文件增加fops.owner THIS_MODULE,.open input_proc_devices_open,.poll input_proc_devices_poll,.read seq_read,.llseek seq_lseek,.release seq_release,};entry proc_create(handlers, 0, proc_bus_input_dir,input_handlers_fileops);//应该是bus总线里面的注册handlers文件夹err register_chrdev_region(MKDEV(INPUT_MAJOR, 0),INPUT_MAX_CHAR_DEVICES, input);//这里的主设备号是13 static LIST_HEAD(input_dev_list); //全局static 初始化链表 static LIST_HEAD(input_handler_list);//全局static 初始化链表第二步 input handler 数据处理层 input/evdev.c 为了构建input_handler 先看看handler结构体里面有些什么 里面有主次设备号,还有fops操作参数,看起来就是能创建设备节点的 这里的主设备号 同时次设备号还是64 64那就是/dev/input/event 开始的次设备号 //如果看struct input_handler 有下面这些成员 和/dev/input/event 13 64 里面次设备一致 struct input_handler(void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);file_operation *fops evdev_opsint minor; EVDEV_MINOR_BASE 64.connect evdev_connect,.event evdev_event,} 上面构造号后 就注册到 input_hadle_list 链表中 input_handler层中 叫数据处理者 注册进core层的链表 就是看看哪些数据能被处理假如上面的handler和下面的input_dev匹配成功 就直接调用 handler中的connect()方法 connect()方法会做以下事情,1 创建设备节点 如/dev/event0 主次设备编号13 64 2 创建创建input_dev对象 1.input_dev里面有event clinet(描述的缓冲区对象) 这个缓冲区是个队列 每个队列都是struct input_dev结构体2.input_dev里面有handle 对象 里面放了handler指针和dev指针 我也画了图了 所以说 evdev对象就能有handle 就能找到input_dev* 和event_hadle*connect完就等下一层上报数据了 好开始读代码 一步一步来 static int __init evdev_init(void) //驱动程序的函数,自动注册return input_register_handler(evdev_handler);//注册了一个 evdev_handler结构体static struct input_handler evdev_handler {.event evdev_event,.events evdev_events,.connect evdev_connect, 第三步 input_coer层 上面第二步调用了input_register_handler()函数 这个函数其实在 input_coer层 为了把上面的 evdev_handler 注册进链表 struct input_dev *dev; input_register_handler(struct input_handler *handler) //就是我们的handlerlist_for_each_entry(dev, input_dev_list, node) input_attach_handler(dev, handler);//遍历链表,就是把core层两个链表进行匹配id input_match_device(handler, dev);//根据id进行匹配error handler-connect(handler, dev, id); //这里调用了 handler的connect函数第四步 input handler 数据处理层 input/evdev.c 匹配成功后,注册进入链表的 evdev_handler结构体的.connect函数被调用 好的又回去 input handler 层了 重点看图中 这里调用了connect函数后 1.生成了 对象 evdev 2.创建设备节点 /dev/input/event0 先说第一点生成了 对象 evdev 生成了 对象 evdev 这个evdev对象 里面会有两个对象 evdedv_client 和 input_handle 注意这个地方是handle input_handler evdev_handler.connect evdev_connect, evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id)evdev kzalloc(sizeof(struct evdev), GFP_KERNEL);//初始化evdev结构体INIT_LIST_HEAD(evdev-client_list); //初始化里面的client_list ,也就是后面说的bufinit_waitqueue_head(evdev-wait); //初始化里面的等待队列//下面是初始化evdev的handle 也就是用 handle 连接了handler层和input device层evdev-handle.dev input_get_device(dev);evdev-handle.name dev_name(evdev-dev);evdev-handle.handler handler; //handle的作用是能指向handlerevdev-handle.private evdev; //handle的作用是能指向evdev//注册这个handleinput_register_handle(evdev-handle); 第五步 input handler 数据处理层 input/evdev.c 上面的connect的第二点还没说完 2.创建设备节点 /dev/input/event0 input_handler evdev_handler.connect evdev_connect, evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id)minor input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);//查找次设备号看哪个能用//注意这里的dev是device 就是字符设备哪个device//创建设备节点,之前我们都是用device_create(),其实就是做了下面的事情dev_set_name(evdev-dev, event%d, dev_no);evdev-dev.devt MKDEV(INPUT_MAJOR, minor);//这里主设备号13 次设备号从65开始evdev-dev.class input_class;evdev-dev.parent dev-dev;evdev-dev.release evdev_free;device_initialize(evdev-dev);device_add(evdev-dev)cdev_init(evdev-cdev, evdev_fops); //cdev的fops在这里cdev_device_add(evdev-cdev, evdev-dev); note:以前用device_create()创建设备节点 device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)//这个函数要的参数上面竟然都有device_create_vargs(class, parent, devt, drvdata, fmt, vargs);device_initialize(dev);dev kzalloc(sizeof(*dev), GFP_KERNEL);dev-devt devt;dev-class class;dev-parent parent;dev-groups groups;dev-release device_create_release;device_add(dev);//所以知道了 上面就是在创建设备节点 做完那不就/dev/input/event0 就出来了 第六步 device层 注册自己写的函数 module_init(simple_btn_input_init); static int __init simple_btn_input_init(void)//a, 分配一个input device对象btn_input input_allocate_device();//b, 初始化input device对象//该设备能够产生哪种数据类型---EV_KEY表示产生按键数据btn_input-evbit[0] | BIT_MASK(EV_KEY);//能够产生哪个按键---比如能够产生下键 KEY_DOWN, KEY_ESC// btn_input-keybit[108/32] | 1(108%32);btn_input-keybit[BIT_WORD(KEY_DOWN)] | BIT_MASK(KEY_DOWN);//c, 注册input device对象ret input_register_device(btn_input);//这个函数里面最后也是调用了handler-connect(handler, dev, id);//匹配成功就是handle的connect方法,也就是 evdev_connect()note: 可能这里要问了,有没有和palntfrom一样的匹配规则呢 啥设备树匹配 name匹配的 我们看到handler层的注册的结构体 input_handler evdev_handler evdev_handler.id_table evdev_ids static const struct input_device_id evdev_ids[] { { .driver_info 1 }, /* Matches all devices / //这里的意思是匹配所有设备,来了就匹配,我不要规则 { }, / Terminating zero entry */ }; 那为啥还有个idtable 拿来匹配呢 是因为我们用的是公共驱动,所有都匹配 但是有其他的handler驱动,需要用支持哪些输入事件和键值对 来看是否能匹配这个设备了 举个例子在input_hadler这一层 我们看的是evdev.c这个万能驱动 起始还有mousedevhandler mousedev.c鼠标handler 和joydey_handle游戏杆的handler 所以鼠标设备会和 evdev.c匹配 也会和鼠标handler匹配 所以鼠标插入的时候 有个/dev/input/event0 和 /dev/input/mouse0 起始两个是同一个设备 所以用哪个都可以 第7步 应用程序调用open() 到vfsopen 根据设备号找到cdev 到驱动的open函数 我们之前是在core层 申请的设备号 所以找到了 input.c的代码 这个地方也要回顾为啥是到这里!!! 有可能推理错了,应该是open直接调用evdev的open,需要回去看cdev那节 因为这里又register_chrdev_region() err register_chrdev_region(MKDEV(INPUT_MAJOR, 0), INPUT_MAX_CHAR_DEVICES, “input”); 在input_open函数中 找到input_hadle 那么也能找到input_hadler层的fops register_chrdev(Input_major,“input”,input_fops) input_fops.open() new_fops fops_get(hadler-fops) //把文件节点的fop全改成了 handler层的fop了 file_fop new_file 第八步 input handler 数据处理层 input/evdev.c 上一步找到了 input handler的open() //当时的fop是这样注册的evdev_connect() //造connect注册了fopcdev_init(evdev-cdev, evdev_fops);evdev_fops.open evdev_open() //open函数这里 初始化client struct evdev_client *client;client kzalloc(size, GFP_KERNEL | __GFP_NOWARN);client-bufsize bufsize;client-evdev evdev;evdev_attach_client(evdev, client);//把文件节点的fop全改成了 handler层的fop了file_fop new_file //使用file节点私有空间传输数据,那read,write都能拿到了clientevdev_open_device() //查看第三层 input_dev xx层有没有open函数,有的话继续调用 但这里没有第九步 app开始read vfs_erad 到evdev.c 开始进行evdev_read 也就是调用到evdev_read() 从之前的client中 拿取最新的上报数据 返回给用户层 evdev_read()evdev_client *client file-private_data;//从fd文件的私有属性拿到clientevdev *evdev client-evdev; //从clinet拿到evdevstruct input_event event;//构造一个要返换给用户空间的结构体 input_eventif (client-packet_head client-tail (file-f_flags O_NONBLOCK))//如果当前用非阻塞的方式,还没有数据,那应该马上返回return -EAGAIN;if (!(file-f_flags O_NONBLOCK)) //正常的阻塞形式error wait_event_interruptible(evdev-wait,client-packet_head ! client-tail ||!evdev-exist || client-revoked);//这个进程丢进等待队列把,等中断唤醒继续往下走//下面是有中断了,阻塞解除,进程继续往下走//下面的进行用户空间数据发送while()evdev_fetch_next_event(client, event)*event client-buffer[client-tail];//这里构造input_event,也就是从client里面拿一个bufferinput_event_to_user(buffer read, event)copy_to_user(buffer, event, sizeof(struct input_event)//拿了buffer后给到用户空间第十步 那么中断是谁发起的 就到了我们写的程序 input_device 层 //按下 input_event(btn_input, EV_KEY, KEY_DOWN, 1); input_sync(btn_input); //我们的中断函数执行上报数据INPUT.C //跑到中间层进行数据封装input_handle_event(struct input_dev *dev,unsigned int type, unsigned int code, int value)input_pass_values(dev, dev-vals, dev-num_vals);struct input_handle *handle; struct input_value *v;handle rcu_dereference(dev-grab);//从dev中拿到handlelist_for_each_entry_rcu(handle, dev-h_list, d_node)//这个也是想办法拿到handlehandle_event(handle,type,code,value) 第十一步 input handler 数据处理层 input/evdev.c 第11步,就把中断传输来的 evdev_event数据放入了 event_client队列里面 就等着 app被唤醒后来拿数据就行了 调用到 input_handler evdev_handler-event evdev_eventstruct evdev *evdev handle-private; //通过private找到evdevstruct evdev_client *client;list_for_each_entry_rcu(client, evdev-client_list, node)//也找到clinet
http://www.zqtcl.cn/news/544603/

相关文章:

  • 先做网站再付款 怎么回答设计方案步骤
  • 汕头建站模板济南网站建设富库网络
  • 创业网站建设方案项目书手机app设计软件
  • 建设端午节网站的目的主题wordpress语法高亮插件
  • 做网站开发使用百分比的好处深圳建设网站公司简介
  • 行距网站上海专业网站建设机构
  • 闵行手机网站建设鲅鱼圈规划建设局网站
  • 合肥市城乡和建设网站网页设计与网站建设区别
  • 青岛网站建设企业建站北京网站模仿
  • 广州建设网站的公司简介湛江建设厅网站
  • 做网站不赚钱了网站关键词排行查询
  • 印度人通过什么网站做国际贸易三门峡做网站
  • 网站排名快速提升工具招远建网站首选公司
  • 手机网站格式商城网游开发公司
  • 手机怎样创建网站长春网站建设哪家专业
  • 做pop网站定制开发教程
  • 成都响应式网站建报告问题
  • 做设计找素材的+网站有哪些建立平台什么意思
  • 网站设置在哪里找宁德网站建设制作
  • logo网站设计素材品牌高端网站建设公司
  • 芙蓉区乡建设局网站郑州网站建设qicaizz
  • 网站建设的缺陷个人网站制作图片
  • 四川省建设厅注册管理中心网站设计上海2021门票
  • 帝国cms做微网站人力资源公司怎么开
  • 网站建设学徒松江品划做网站公司
  • 灯饰网站需要这么做深圳专业网站设计公司
  • 政务网站设计wordpress 嵌入html5
  • 移动网站 pc网站的区别吗网站建设工厂
  • 有意义网站织梦圈子如何调用网站默认模板
  • 南京公司网站模板建站网页制作中的网站维护