LINUX IIO子系統分析之五 iio buffer介紹

2020-09-05 jerry的編程路

上一章我們介紹了iio子系統中的iio event模塊,本章我們將介紹iio buffer模塊,iio buffer主要用於連續數據採集與緩存功能。IIO buffer模塊藉助IIO DEVICE字符設備文件與應用程式通信,同時藉助iio trigger模塊與iio device進行交互,因此本章內容分為如下幾部分:

一、 IIO DEVICE字符設備文件操作接口

二、iio buffer相關數據結構

三、IIO trigger-buffer介紹

四、IIO buffer相關接口說明

一、 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主要實現兩個功能:

  1. 用於讀取iio device緩存的已採集數據,從而讓應用程式對採集的數據進行分析;
  2. 藉助該字符設備文件的ioctl接口,實現匿名iio event fd的創建,從而讓應用程式藉助select/epoll監控該匿名文件是否有event信息可讀;

如下即是/dev/iio:deviceX的訪問流程,應用程式通過open/read/poll/ioctl接口則會調用內核中VFS提供的操作接口,最終則調用iio_buffer_fileops中定義的接口。

iio_buffer_fileops的定義如下


二、iio buffer相關數據結構

struct iio_buffer與struct iio_buffer_setup_ops

iio_buffer主要是用於存儲連續採集數據的緩存,其主要包括兩個主要的數據結構struct iio_buffer、struct iio_buffer_access_func(其實是三個數據結構,還有數據結構struct iio_kfifo,其內部包含struct iio_buffer類型變量和struct kfifo類型變量用於緩存數據)。

針對struct iio_buffer主要包括如下幾個方面的內容:

  1. iio_buffer緩存數據的個數(即length);
  2. iio_buffer每一次採集數據的長度(bytes_per_datum,而bytes_per_datum*length即為kfifo存儲數據的內存空間大小);
  3. Scan_el_dev_attr_list主要用於將所有iio_buffer子模塊創建的屬性變量集合在一起(iio_buffer);
  4. scan_el_attrs存儲各設備驅動自行定義的靜態屬性(生成的屬性文件在scan_elements子目錄下);
  5. attrs也是存儲存儲各設備驅動自行定義的靜態屬性(該變量定義的屬性文件在buffer子目錄下);
  6. buffer_group、scan_el_group包含iio buffer子模塊下所有屬性,其中buffer_group裡的屬性均在buffer子目錄下創建對應的屬性文件;scan_el_group裡的屬性均在scan_elements子目錄下創建對應的屬性文件;
  7. pollq為等待隊列,主要為iio device的字符設備文件使用(該字符設備文件對應的讀接口和poll接口使用,當buffer中不存在數據時則sleep在該等待隊列中);
  8. watermark為緩存多少個數據後,喚醒pollq(實際內存空間大小為watermark*bytes_per_datum)。


針對struct iio_buffer_access_funcs則是該iio_buffer對應的緩存空間的訪問訪問,目前使用kfifo緩存數據,則其訪問方法為iio_store_to_kfifo、iio_read_first_n_kfifo等,主要是將數據存儲至kfifo或從kfifo中取出緩存數據等


三、IIO trigger-buffer介紹

藉助於IIO trigger機制,iio-device在數據可讀時,將數據push 到iio buffer子模塊的緩存中,實現緩存連續採集的數據。如下圖所示,即為iio trigger-buffer的實現機制,其中紅線部分即是iio trigger的部分,而右邊黃線部分則是iio buffer的部分(關於iio trigger的介紹請參考)。具體說明如下:

  1. 實現iio trigger的註冊,該iio trigger 可支持多個consumer(此處的consumer即為iio buffer),而iio trigger主要是藉助其內部實現的虛擬中斷控制器,從而實現支持多個consumer;而iio trigger需要與iio device進行綁定,僅在iio device與iio trigger綁定後,iio device driver則可以通過監控iio device觸發事件(如中斷),然後調用iio_trigger_poll接口,該接口調度所有虛擬中斷對應的中斷處理函數(即調用iio trigger consumer提供的中斷處理接口,而在該中斷處理接口中從iio device中讀取數據,並調用iio_push_to_buffer,將數據push到iio buffer的kfifo中;
  2. 而應用程式則通過iio buffer 字符設備文件接口,從iio buffer的kfifo中讀取採集的數據信息。)

藉助以上的信息,則實現了iio trigger與iio buffer的結合,並實現iio device 採集數據的緩存與讀取操作。


四、IIO buffer相關接口說明

iio trigger與iiobuffer關聯接口

主要提供接口iio_triggered_buffer_setup用於實現該功能,該接口實現的功能主要包括:

  1. 申請iio buffer類型的變量,同時完成iio_dev->pollfunc的定義(struct iio_poll_func*類型的變量,該變量主要包含iio trigger內部虛擬中斷處理接口的賦值、申請的虛擬中斷id等);


  1. 完成iio_dev->setup_ops的賦值(即struct iio_buffer_setup_ops*類型的變量,該數據結構主要用於實現iio buffer與iiotrigger的綁定與解綁接口,一般使用iio buffer實現的默認變量iio_triggered_buffer_setup_ops), iio_triggered_buffer_setup_ops的定義如下。
    1. 其中iio_triggered_buffer_postenable則實現iio trigger與iio buffer的綁定,即通過調用iio_trigger_attach_poll_func接口從iio trigger中申請一個虛擬的irq,並完成該irq的中斷處理函數的設置;當iio device調用iio_trigger_poll接口將觸發信息發送給iio trigger時,iio trigger則會觸發所有虛擬中斷處理接口,由各中斷的中斷處理函數從iio device中進行數據的採集,並調用iio_push_buffer接口,將採集的數據push到iio buffer的kfifo中。
    2. 而iio_triggered_buffer_predisable則解除iio trigger與iio buffer的綁定,即free申請的虛擬irq。

iio buffer相關的sysfs屬性文件創建接口

iio_buffer_alloc_sysfs_and_mask接口用於實現iio buffer相關sysfs屬性文件的創建,其中創建兩類sysfs屬性文件:

  1. iio buffer使能、iio kfifo長度、應用程式可讀取數據的最小等待個數,主要是在/sys/bus/iio/devices/iio:deviceX目錄下創建子目錄buffer,該子目錄下創建三個屬性文件,分別為enable、length、watermark;
    1. 其中enable用於實現iio buffer使能的設置及查看,當通過該文件使能iio buffer時,則完成iio buffer的kfifo大小申請、單次採集數據大小更新、已使能的採集通道數據等更新,並最終調用iio_buffer_setup_ops->postenable接口,實現iio trigger與iio buffer的綁定;
    2. length主要設置iio buffer的kfifo的容量大小;
    3. watermark則主要修改應用程式一次可讀取數據的最小等待個數,當buffer中存儲的數據個數超過該值後,則在poll接口iio_buffer_poll中標記該文件可讀(epoll、select監控該標記);
  2. iio buffer相關的採集通道的使能與否相關的sysfs屬性文件,主要是在/sys/bus/iio/devices/iio:deviceX目錄下創建子目錄scan_elements,創建採集通道使能屬性文件、採集數據的格式、採集通道的index等,如本專欄實現的虛擬溫度晶片(virt0824型號),為兩個通道創建了採集通道使能相關的屬性文件,如下圖所示:

scan_elements目錄下的屬性文件,則主要是根據iio device driver中定義的struct iio_chan_spec類型變量進行創建,上面的文件主要是根據下面的定義進行創建的(如下藍色陰影部分,定義了scan index的值、scan type,其中scan index即對應io_tempX_index,而in_tempX_type則主要為scan_type定義的值,這兩個屬性文件的屬性為只讀屬性):

此處以該device為例,說明如何開啟iio buffer,主要分為如下幾步:

  1. 使能採集通道:
    1. echo 1 >scan_elements/in_temp0_en
  2. 設置iio buffer kfifo長度
    1. echo 16 > buffer/length
  3. 設置iio buffer watermark
    1. echo 2 > buffer/watermark
  4. 使能iio buffer
    1. echo 1 > buffer/enable

執行以上各步驟,即可完成iio buffer的使能,現在我們讓virt0824xinp觸發兩次中斷,從而觸發iio-trigger-buffer進行數據的採集

然後執行如下命令,看獲取到採集數據:


以上即是iio buffer的主要功能,主要說明了iio trigger與iio buffer的綁定部分、iio buffer字符設備文件訪問流程、iio buffer相關sysfs屬性文件的定義及使用過程。下一章我們分析iio device的註冊流程。

相關焦點

  • LINUX IIO子系統專欄分析之一 IIO子系統概述
    從本章開始,我們進行IIO子系統專欄的分析文檔,本次IIO子系統專欄分析文檔大概包含如下幾章:一、 IIO子系統概述二、IIO子系統相關數據結構分析三、iio trigger 介紹四、iio event介紹五、iio buffer介紹六、iio device的註冊與註銷介紹七、iio trigger
  • LINUX IIO子系統分析之二 IIO子系統數據結構分析
    基本就是這些內容,iio子系統主要藉助字符設備文件以及sysfs屬性文件實現數據的獲取與參數設定等操作。),現在僅需要關注pollfunc即可,基本上沒有使用pollfunc_event的;channels是該iio device所有channel相關的參數信息,我們在iio_chan_spec中將詳細說明;channel_attr_list鍊表包含了IIO子系統為所有channel創建的動態屬性(針對hwmon子系統我們之前也分析過,其主要通過在sysfs下創建屬性文件實現與
  • LINUX IIO子系統分析之四 IIO EVENT設計分析
    上一章我們介紹了iio子系統中的iio trigger模塊,本章我們將介紹iio event模塊,iio event主要用於閾值監測、自由落體監測等監測功能。如下即是/dev/iio:deviceX的訪問流程,應用程式通過open/read/poll/ioctl接口則會調用內核中VFS提供的操作接口,最終則調用iio_buffer_fileops中定義的接口。
  • LINUX IIO子系統分析之三 IIO trigger分析
    上一章我們分析了IIO子系統的數據結構定義,本章我們主要介紹IIO TRIGGER的設計實現,主要內容如下:一、數據結構簡述 二、設計實現說明 三、提供接口說明一、數據結構簡述irq chip,在trigger內部,當多個trigger consumer註冊時,則trigger內部會為其分配一個虛擬的irq,並根據trigger consumer提供給pollfunc,為該irq註冊中斷處理函數,這樣當該trigger觸發後,則會遍歷所有該trigger上已註冊的虛擬irq,調用其中斷處理函數從而執行trigger consumer提供的處理函數(關於linux中斷子系統的內容可參考我之前寫的中斷子系統專欄
  • LINUX IIO子系統分析之六 IIO設備驅動開發流程說明
    前面五章我們基本上把IIO 子系統的內部設計實現均作了說明,本章我們將說明iio device的驅動開發流程,本章的主要內容大致安排如下:一、IIO子系統的關鍵技術點總結 二、IIO DEVICE的註冊與註銷接口說明 三、IIO DEVICE的驅動開發流程
  • LINUX IIO子系統分析之七 虛擬iio設備驅動實現
    buffer對應的數據連續採集功能,實際的晶片可能並不提供該中斷)二、虛擬IIO DEVICE DRIVER實現所需的知識點 為了讓本次實現的IIO DEVICE能夠儘量實現數據單次採集、iio buffer、iio event等功能,本次虛擬iio device driver主要涉及如下幾個知識點:
  • Linux regmap子系統分析之三 regmap bus實例分析
    在前面一章我們分析了regmap子系統的數據結構,基本上熟悉了數據結構的關聯,也就大概理解了regmap子系統的實現流程,本章我們簡要介紹下regmap子系統中接口的調用過程,然後介紹下regmap bus的實現及其提供的regmap的創建及註銷接口。
  • Linux V4l2子系統專欄之一 子系統概述
    從本章開始,我們開始分析V4L2子系統(Video for Linux two),主要用於音視頻設備的框架。V4l2主要用於驅動視頻輸出設備(video outpt interface)、Video overlay interface、Video output overlay device、VBI interface、Radio interface等。
  • linux內核源碼編譯過程分析之Kconfig,Makefile
    在之前的課程裡,當我們在編譯linux內核源碼的時候,不知道大家會不會有一些疑問:1.linux內核源碼那麼多(大概800M),編譯的時候它(編譯系統)怎麼知道應該要編譯哪些文件呢?2.怎樣保證源碼的編譯順序?比如,先編譯A模塊,再編譯B模塊?3.怎麼樣把這些編譯出來的一個一個的目標文件,最終形成一個內核鏡像文件?
  • Linux regulator子系統分析之三 regulator註冊、註銷接口分析
    在上一章我們介紹了regulator子系統相關的數據結構間的關聯以及每一個數據結構的定義。針對數據結構間的關聯則需要regulator子系統提供的接口實現。而本章我們就說明這些接口。本章的章節如下:一、regulator device的註冊與註銷二、regulator的註冊與註銷(regulator device的使用者)三、regulator子系統提供的接口一、regulator device的註冊與註銷針對regulator device的註冊與註銷函數主要涉及regulator_register、regulator_unregister
  • LINUX CommonClock Framework子系統分析之一 系統概述
    本專欄主要介紹linux的ccf子系統,主要用於系統clock的管理等操作。本專欄我們大概分為如下幾章進行學習:一、CCF子系統概述二、CCF子系統數據結構分析及關聯說明三、CCF子系統的clk註冊與註銷接口實現分析四、虛擬的clk設備驅動實現 本章我們主要進行CCF子系統的概述。
  • Linux內存buffer和cache的區別
    有關linux內存機制參考: Linux 內存機制 http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5463790.aspx Mem:表示物理內存統計。 -/+ buffers/cached:表示物理內存的緩存統計 Swap:表示硬碟上交換分區的使用情況。
  • Linux regulator子系統分析之一 總體概述
    Linux regulator 子系統主要用於管理電壓、電流電源設備的電壓、電流輸入使能、動態調整電壓、電流等,屬於電源管理的一部分。從本章開始我們分析regulator子系統。主要分為如下幾部分:一、regulator子系統總體概述二、regulator相關數據結構分析三、regulator相關註冊、註銷函數分析四、regulator設備驅動實現本章主要對regulator子系統進行簡要說明。
  • Linux input子系統編程、分析與模板
    內核中的輸入子系統自底向上分為設備驅動層,輸入核心層,事件處理層。由於每種輸入的設備上報的事件都各有不同,所以為了應用層能夠很好識別上報的事件,內核中也為應用層封裝了標準的接口來描述一個事件,這些接口在"/include/upai/linux/input"中。
  • 手動釋放Linux上的Swap、Buffer和Cache
    本文介紹linux內存機制、虛擬內存swap、buffer/cache釋放等原理及實操。物理內存就是系統硬體提供的內存大小,是真正的內存,相對於物理內存,在linux下還有一個虛擬內存的概念,虛擬內存就是為了滿足物理內存的不足而提出的策略,它是利用磁碟空間虛擬出的一塊邏輯內存,用作虛擬內存的磁碟空間被稱為交換空間(Swap Space)。
  • Linux regmap子系統分析之二 從數據結構分析系統實現
    上一章我們簡要分析了regmap子系統,本章我們將從regmap子系統的數據結構介紹regmap子系統的實現。 一、數據結構間的關聯及說明 針對regmap子系統,我們首先要知道regmap子系統要解決的痛點是什麼?
  • Linux內存、Swap、Cache、Buffer
    在Linux系統下,我們一般不需要去釋放內存,因為系統已經將內存管理的很好,但是凡事也有例外。     Cache(緩存),為了調高CPU和內存之間數據交換而設計,Buffer(緩衝)為了提高內存和硬碟(或其他I/O設備的數據交換而設計)。
  • Linux regmap子系統分析之一 系統概述
    本系統專欄主要涉及如下幾個子章節:一、regmap子系統概述二、regmap子系統數據結構分析三、regmap子系統接口說明四、regmap bus實例說明(以i2c為例)本章我們主要對regmap子系統做一個簡單的說明。
  • Linux regulator子系統分析之二 從數據結構理解系統實現
    上一章我們分析了regulator子系統的總體框架,本章我們將從數據結構入手,從而理解regulator子系統實現。 針對linux 內核各子系統學習而言,在理解了各子系統的實現背景後,再從數據結構入手,可快速理解其子系統的實現流程。因此本章我們從regulator子系統的數據結構入手,從而理解regulator子系統的實現。
  • Linux GUI子系統概述 GUI子系統的構成及工作流程
    : 本文會儘量從初學者的角度去描述整個Linux整個圖形子系統,但由於其複雜性,涉及到的模塊比較多,可能會需要一些相關的先驗知識; 對於系統的介紹,分析的著重點可能不會在於為什麼該這樣設計,而是在於在現有的顯示系統下,我們能做些什麼來適配我們的目的; 1.前言 GUI作為人機互動信息量最大的一種方式,無論在消費還是工業級產品上都大行其道