LINUX IIO子系统分析之四 IIO EVENT介绍

      上一章我们介绍了iio子系统中的iio trigger模块,本章我们将介绍iio event模块,iio event主要用于阈值监测、自由落体监测等监测功能。因为IIO EVENT涉及IIO DEVICE字符设备文件操作,因此本章内容主要分为如下几部分:

一、 IIO DEVICE字符设备文件操作接口

 

二、IIO EVENT设计分析

 

三、IIO EVENT相关接口说明

 

一、 IIO DEVICE字符设备文件操作接口

       在IIO 子系统中,每一个IIO DEVICE均会创建一个字符设备文件,名称为/dev/iio:deviceX,该字符设备文件节点在iio_device_register中调用cdev_init、cdev_add完成字符设备文件节点的创建,且文件操作接口为iio_buffer_fileops(而借助sysfs的kobject uevent,则会将cdev add的信息发送给应用程序,应用层的mdev/udev接收到cdev add的uevent之后,则会调用mknod完成字符设备文件节点的创建,详细内容可参考我之前写的字符设备文件专栏的内容《》)。如下即是/dev/iio:deviceX的访问流程,应用程序通过open/read/poll/ioctl接口则会调用内核中VFS提供的操作接口,最终则调用iio_buffer_fileops中定义的接口。

 

 

iio_buffer_fileops的定义如下

 

问题来了,iio device对应的字符设备文件节点主要提供哪些服务呢?

主要提供两方面的内容:

  1. 提供对iio device各通道连续采集数据的读取操作(前提是该iio device的某些通道提供了iio buffer功能);
  2. 提供创建event数据读取对应的匿名字符设备文件节点的功能(通过ioctl功能,则创建一个匿名的字符设备文件节点,用于进行iio device各通道相关的event数据的读取功能)。所谓匿名即该字符设备文件节点并不会显示在文件系统中(无法在应用层中找到该文件名称),且一个iio device同一时刻仅可创建一个匿名字符设备文件节点。

 

二、IIO EVENT设计分析

iio event相关的数据结构

struct iio_event_interface是iio event相关的数据结构,该数据结构的定义如下

该数据结构主要是对event子模块的定义,其中:

  1. 等待队列wait,当应用程序读取触发事件信息时,若当前无数据可读,则将当前进程加入到该等待队列,待调用iio_push_event将触发事件信息加入kfifo后,则wakeup该队列中的进程;
  2. 定义kfifo,存储所有触发的事件信息,供应用程序获取;
  3. 将even子模块动态定义的event attribute均添加至该链表中(属性名称格式为{iio_dir}_{iio_channel_type}{channel-Index/channel_modify}_{ev_type}_{ev_dir}_{ev_info});
  4. flags标记该event是否已使能(即应用程序是否通过ioctl调用创建一个匿名fd,若使能则置位IIO_BUSY_BIT_POS)

 

 

iio event fd创建

      IIO event数据信息也是通过字符设备文件节点与应用程序进行交互的,但就像上面所说的,iio event数据读取对应的字符设备文件节点是一个匿名字符设备文件节点,且必须借助字符设备文件节点/dev/iio:deviceX的ioctl方可创建。创建流程如下图所示。借助字符设备文件/dev/iio:deviceX提供的ioctl,即创建一个匿名的文件节点,并返回该文件节点对应的event detect fd。

 

 

而event detect fd的文件操作接口的定义如下,提供event detect信息的读取及是否可读监控接口poll。

 

 

event 检测及读取流程

针对event 信息而言,主要就涉及event检测、event信息读取两部分,这两部分的关联如下图所示:

  1. 应用程序可直接通过read接口读取event信息(若event信息存在则读取检测到的event信息;若event信息不存在且fd设置为阻塞读方式,则将该读取进程休眠,加入到event的wait队列中);
  2. 应用程序可通过select或者epoll检测event fd是否可读,最终会调用event fd的poll接口,加入到event的等待队列中;
  3. 当iio device检测到某一个事件后,则通过中断(或其他的方式通知cpu)通知cpu,cpu则调用中断处理函数处理中断,在中断处理函数中读取检测到的event,然后调用iio_push_event将event加入到iio device对应event子模块的kfifo中,并wakeup event的wait队列,这样就唤醒了上述1和2中sleep的进程,进程即可进行event事件的读取操作。

 

 

 

 

备注:在IIO子系统中,针对iio event,也设计与iio trigger的关联,即由iio trigger触发eventdetect操作。若将iio eventiiotrigger关联,则执行的流程大致如下所述:

  1. iio event定义中断处理接口,并赋值给struct iio_devpollfunc_event成员(struct iio_poll_func *;
  2. iio trigger中申请一个虚拟的irq,并完成对应中断处理函数的注册(即上述1中的pollfunc_event);
  3. 注册一个iio trigger,用于处理iio device检测的event,则调用iio trigger 提供的iio_trigger_poll接口,由该接口调度iio trigger中所有申请的虚拟irq的中断处理函数;
  4. pollfunc_event接口中读取检测的event接口,然后wakeup event wait队列。

 

       以下即是使用trigger-event方式的event detect检测及读取流程,相比上面的流程而言,则增加了虚拟irq的中断处理流程,而针对event信息而言,一般也就是出现告警等信息而检测的,并不像连续的数据采集那样频繁读取,因此这一种方式的event信息检测及读取流程并没有多少iio device driver采用,iio device driver一般使用上面的检测及读取流程。

 

 

 

三、IIO EVENT相关接口说明

 

iio event相关的sysfs属性的创建接口

       iio_device_register_eventset接口用于创建iio event相关的event属性,该接口主要由iio_device_register接口调用,主要是根据struct iio_event_spec *event_spec中定义的变量,创建对应的event属性,

       下面是我实现的虚拟温度传感器芯片定义的event信息,其创建了温度上限告警、温度下限告警相关的属性,主要包括温度上限检测使能、温度下限检测使能、温度上限告警值设置及读取、温度下限告警值设置及读取等属性。


static const struct iio_event_spec virt0824_temp_event[] = {

 {

     .type = IIO_EV_TYPE_THRESH,

     .dir = IIO_EV_DIR_RISING,

     .mask_separate = BIT(IIO_EV_INFO_VALUE) |

         BIT(IIO_EV_INFO_ENABLE),

 },

 {

     .type = IIO_EV_TYPE_THRESH,

     .dir = IIO_EV_DIR_FALLING,

     .mask_separate = BIT(IIO_EV_INFO_VALUE) |

         BIT(IIO_EV_INFO_ENABLE),

 },

    event属性的名称格式为{iio_dir}_{iio_channel_type}{channel-Index/channel_modify}_{ev_type}_{ev_dir}_{ev_info}),针对我们上述定义的event属性,其生成的属性文件名称如下所示,生成的属性文件也是符合该格式的。

 

 

event push接口

     iio_event_poll接口主要实现将event信息放入event的kfifo中,并wakeup event wait queue,然后应用程序即可读取该event信息。

 

event chrdev ops

iio_event_chrdev_fileops即为event fd的文件操作接口,我们在上面已经说明,此处不再赘述。

 

 

         以上即是iio event的主要内容,针对iio device driver而言,仅需要实现struct iio_event_spec *类型的变量定义event的sysfs属性,并在检测到event之后,调用iio_event_poll将event信息压入event kfifo中即可。相对来说这部分驱动实现还是很简单的,而我们上面介绍的则是iio event内部的设计实现。下一章介绍iio buffer的设计实现。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值