上一章我們介紹了iio子系統中的iio trigger模塊,本章我們將介紹iio event模塊,iio event主要用於閾值監測、自由落體監測等監測功能。因為IIO EVENT涉及IIO DEVICE字符設備文件操作,因此本章內容主要分為如下幾部分:
一、 IIO DEVICE字符設備文件操作接口
二、IIO EVENT設計分析
三、IIO EVENT相關接口說明
在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對應的字符設備文件節點主要提供哪些服務呢?
主要提供兩方面的內容:
struct iio_event_interface是iio event相關的數據結構,該數據結構的定義如下
該數據結構主要是對event子模塊的定義,其中:
IIO event數據信息也是通過字符設備文件節點與應用程式進行交互的,但就像上面所說的,iio event數據讀取對應的字符設備文件節點是一個匿名字符設備文件節點,且必須藉助字符設備文件節點/dev/iio:deviceX的ioctl方可創建。創建流程如下圖所示。藉助字符設備文件/dev/iio:deviceX提供的ioctl,即創建一個匿名的文件節點,並返回該文件節點對應的event detect fd。
而event detect fd的文件操作接口的定義如下,提供event detect信息的讀取及是否可讀監控接口poll。
針對event 信息而言,主要就涉及event檢測、event信息讀取兩部分,這兩部分的關聯如下圖所示:
備註:在IIO子系統中,針對iio event,也設計與iio trigger的關聯,即由iio trigger觸發event的detect操作。若將iio event與iiotrigger關聯,則執行的流程大致如下所述:
以下即是使用trigger-event方式的event detect檢測及讀取流程,相比上面的流程而言,則增加了虛擬irq的中斷處理流程,而針對event信息而言,一般也就是出現告警等信息而檢測的,並不像連續的數據採集那樣頻繁讀取,因此這一種方式的event信息檢測及讀取流程並沒有多少iio device driver採用,iio device driver一般使用上面設計的檢測及讀取流程。
iio_device_register_eventset接口用於創建iio event相關的event屬性,該接口主要由iio_device_register接口調用,主要是根據struct iio_event_spec *event_spec中定義的變量,創建對應的event屬性,
下面是我實現的虛擬溫度傳感器晶片定義的event信息,其創建了溫度上限告警、溫度下限告警相關的屬性,主要包括溫度上限檢測使能、溫度下限檢測使能、溫度上限告警值設置及讀取、溫度下限告警值設置及讀取等屬性。
event屬性的名稱格式為{iio_dir}_{iio_channel_type}{channel-Index/channel_modify}_{ev_type}_{ev_dir}_{ev_info}),針對我們上述定義的event屬性,其生成的屬性文件名稱如下所示,生成的屬性文件也是符合該格式
的。
iio_event_poll接口主要實現將event信息放入event的kfifo中,並wakeup event wait queue,然後應用程式即可讀取該event信息。
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的設計實現。