LINUX IIO子系统分析之六 iio device的驱动开发流程说明
前面五章我们基本上把IIO 子系统的内部设计实现均作了说明,本章我们将说明iio device的驱动开发流程,本章的主要内容大致安排如下:
一、IIO子系统的关键技术点总结
二、IIO DEVICE的注册与注销接口说明
三、IIO DEVICE的驱动开发流程
一、IIO子系统的关键技术点总结
以上几篇文章已经对IIO子系统的设计实现做了大致说明,IIO子系统主要使用如下几个关键技术点实现其主要功能:
- 借助sysfs、kobject机制,实现IIO DEVICE各类的设备属性,并借助于sysfs暴露给应用程序。
- 实现iio event相关的设备属性,并将属性参数以sysfs文件的形式显示在IIO DEVICE的events子目录(/sys/bus/iio/devices/iio:deviceX/events),包括event的使能、event参数设置与读取文件等;
- 实现iio trigger设备及其属性,并将属性参数以sysfs文件的显示在trigger子目录(/sys/bus/iio/devices/triggerX),可查看trigger的名称;而iio device则可以通过文件/sys/bus/iio/devices/iio:deviceX/trigger查看或修改当前iio device绑定的trigger;
- 实现iio buffer相关的设备属性,用于进行iio buffer的使能与否、各channel 相关的数据采集缓存使能等,主要在目录/sys/bus/iio/devices/iio:deviceX/scan_elements、/sys/bus/iio/devices/iio:deviceX/buffer下;
- 实现iio device相关的raw 数据读取等设备属性(在目录/sys/bus/iio/devices/iio:deviceX/下),实现读取各channel的raw数据信息(可理解单次数据采集,其与iio buffer采集是互斥的,即一个channel若开启了iio buffer进行数据采集及缓存,则无法通过dir_type_raw文件获取该通道的raw data);
- 借助于字符设备文件机制,应用程序可获取到iio buffer缓存的采集数据以及iio device触发的iio event信息,这两个信息目前仅能通过字符设备文件进行获取;
- iio trigger内部通过实现虚拟的irq chip,实现iio trigger与iio trigger consumer的1:N绑定,而不需要关注iio trigger consumer具体的数据类型等信息;
IIO子系统实现以上三种技术完成了iio device及其内部iio buffer、iio event、iio trigger等模块的功能实现。
二、IIO DEVICE的注册与注销接口说明
iio device注册接口为devm_iio_device_register、iio_device_register,而devm_iio_device_register接口则实现了iio device的自动注销功能,因此iio device driver尽量使用该接口进行iio device的注册
iio_device_register实现的主要功能
iio device register主要实现如下几个功能:
- 完成该iio device对应的字符设备文件的创建,字符设备文件的操作接口为iio_buffer_fileops;
- 完成iio buffer对象指针的创建及iio buffer相关的设备属性的创建(主要通过函数iio_buffer_alloc_sysfs_and_mask实现);
- 完成iio event interface的内存申请及初始化,并完成iio event相关的设备属性的创建(iio_device_register_eventset);
- 完成iio device相关的设备属性的创建(即是上面所说的raw data获取相关的属性文件,通过iio_device_add_channel_sysfs、iio_device_register_sysfs接口调用实现);
- 若iio device支持trigger-buffer、trigger-event,则通过iio_device_register_trigger_consumer完成current_trigger属性的创建,以便进行iio device与trigger的绑定与解绑操作;
- 调用device_add完成iio device对应struct device类型变量的注册,因为上面所需创建的设备属性均是指struct device类型变量;
iio device register主要就完成以上6步的操作,也就是我们上面一中所说的大部分内容,而iio device的注销则主要完成相反的功能。
三、IIO DEVICE的驱动开发流程
以上主要讲的是iio 子系统内部的实现,下面我们说下如何实现一个iio device driver,iio device driver的实现相对来说还是比较清晰明了的。
- 针对iio device的每一个channel,定义其支持设备属性参数( struct iio_chan_spec类型的变量),以便在iio_device_register时,完成各类设备属性的创建,下图是我实现的虚拟iio temp device的channel定义,若某一channel支持iio buffer,则设置scan_index、scan_type信息;若支持iio event,则需要实现event_spec变量( struct iio_event_spec类型的变量,定义event类型等,以便生成iio event设备属性)
- 定义iio device相关info的读写接口,主要是struct iio_info类型的变量,如下即为struct iio_info定义的实例,其中read_raw、write_raw用于raw data 的读写操作(单次数据采集);而read_event_config、write_event_config、read_event_value、write_event_value接口则主要用于event使能控制、event相关值的读写(如温度告警阈值设置等)
- 调用devm_iio_device_alloc接口,申请一个iio device的内存空间;
- 根据上述步骤1、2定义的变量,初始化该iio device;
- 若该设备支持iio trigger-buffer,则调用iio_triggered_buffer_setup,完成iio trigger-buffer的初始化操作;
- 若该iio device提供iio trigger,则调用iio_trigger_register完成iio trigger的注册,并与iio device进行绑定;
- 若该iio device提供中断用于iio buffer的采集,则完成该中断的中断申请,并在中断处理函数中调用iio_trigger_poll,由iio trigger模块调用iio buffer的处理接口,实现iio device 使能channel的采集操作,并存储在iio buffer中
- 调用devm_iio_device_register完成iio device的注册。
完成以上几步,基本上也就可以实现一个iio device driver,下一章我们将通过一个虚拟的iio device driver实例进行动手实践,该虚拟iio device driver涉及虚拟i2c adapter driver、虚拟irq controller,可以实现数据的采集与温度告警中断触发操作。
更多推荐
所有评论(0)