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

来源:互联网 发布:discover it 编辑:程序博客网 时间:2024/06/03 18:53

最近学习一个简单的心率计驱动,在学习驱动源码的过程中,体验了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)设置事件类型,其实就是把对应的位置1
set_bit(EV_ABS, hwmon->idev->evbit);
4)设置EV_ABS类型事件的属性,比如code,最大值最小值等,其中ABS_GAS是code
input_set_abs_params(hwmon->idev, ABS_GAS,-MAG_MAX_NEG, MAG_MAX_POS, 0, 0);
    5)注册设备,其中主要做了三件事:
1.把要注册的设备结构放入input_dev_list链表中
2.在input_handler_list链表中查找对应的handler
3.根据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的匹配过程以及输入事件上报的细节。






0 0
原创粉丝点击