您的位置:首页 > 运维架构 > Linux

从一个简单的sensor驱动看linux输入子系统框架。

2016-07-31 17:49 323 查看
最近学习一个简单的心率计驱动,在学习驱动源码的过程中,体验了linux驱动中input子系统框架及其它一些知识点,现在记录下来可供以后复习参考学习。1. sensor数据的获取,一般的做法是注册中断,在中断里面做处理,中断注册函数主要做的事情就是唤醒等待队列。1)注册中断:request_irq(hwmon->irq, jz_hwmon_irq_handler, 0, pdev->name, hwmon);     2)在中断处理函数里面唤醒等待队列:__wake_up_common(&x->wait, TASK_NORMAL, 1, 0, NULL);2.在sensor数据的读取函数里面阻塞,当等待队列被唤醒后去读取sensor数据     1)阻塞等待:wait_for_completion_interruptible_timeout(&hwmon->read_completion, HZ);2)读取sensor数据readw(hwmon->base) & 0xfff;上面两步封装在read函数里面在字符设备框架里面就已经实现了对数据的阻塞读取。3. 为了实现对sensor数据的定时获取,并且由程序员对获取时机做控制,可以采用延时工作队列。    1)初始化:INIT_DELAYED_WORK(&hwmon->input_hwork, hwmon_input_hwork_func);    2)在hwmon_input_hwork_func处理函数中做延时调度:schedule_delayed_work(&hwmon->input_hwork,msecs_to_jiffies(hwmon->poll_interval_volt));这样就实现了每隔一段时间去做相关的任务。4.任务拆分:1)完成上面第二步的工作,就阻塞等待硬件中断发生,发生中断后去读取sensor数据。2)输入子系统数据上报:input_report_abs(hwmon->idev, ABS_GAS, ret);input_sync(hwmon->idev);5.在输入子系统中注册设备:input_register_device(hwmon->idev);以上在驱动中就能实现sensor数据的通过输入子系统上报用户。下面就是针对该驱动具体分析一下input子系统:input子系统分三块:1. 设备驱动层,就是在设备驱动层需要驱动工程师去实现的1)为输入设备结构体申请内存资源</span>hwmon->idev = input_allocate_device();    2) 初始化设备结构体hwmon->idev->name = "ADC_heart_rate";hwmon->idev->id.bustype = BUS_I2C;hwmon->idev->dev.parent = &pdev->dev;input_set_drvdata(hwmon->idev, hwmon);    3)设置事件类型,其实就是把对应的位置1set_bit(EV_ABS, hwmon->idev->evbit);4)设置EV_ABS类型事件的属性,比如code,最大值最小值等,其中ABS_GAS是codeinput_set_abs_params(hwmon->idev, ABS_GAS,-MAG_MAX_NEG, MAG_MAX_POS, 0, 0);    5)注册设备,其中主要做了三件事:1.把要注册的设备结构放入input_dev_list链表中2.在input_handler_list链表中查找对应的handler3.根据input_handler的id_table查找匹配的dev,匹配成功后会调用handler中的connect函数,并注册handle,后面具体分析。input_attach_handler(dev, handler);2. input 子系统核心层初始化。在系统初始化的时候回调用input_init来初始化input子系统,在这里注册了一个主设备号是13,设备名是input的字符设备,注册了input_open_file函数。input_open_file中最终取调用handler中的open函数。</span>3. input子系统事件输入层。在层主要实现了和用户层交互的调用接口evdev_fops,这是一个接口结合,实现read,open,write等标准系统调用,以及和input子系统相关的函数,如event,connect,这个connect就是在input设备注册的时候如果和handler匹配上了就会被回调,event在设备驱动层上报事件时会被调用。实现了这些函数接口后,就可以注册handler:input_register_handler(&evdev_handler);这样通过这三层的协同就能实现输入事件能实时的上报给用户层。在下一篇文章在重点分析input子系统中dev和handler的匹配过程以及输入事件上报的细节。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: