英特爾整合感測器 Hub (ISH)

感測器 Hub 能夠將感測器輪詢和演算法處理解除安裝到專用的低功耗協處理器。 這使得核心處理器能夠更頻繁地進入低功耗模式,從而延長電池續航時間。

有許多供應商提供符合 HID 感測器使用表的外部感測器 Hub。 這些裝置可以在平板電腦、二合一可轉換筆記型電腦和嵌入式產品中找到。 Linux 自 Linux 3.9 以來就支援這一點。

Intel® 推出了整合感測器 Hub,作為從 Cherry Trail 開始的 SoC 的一部分,現在在多代 CPU 封裝上都得到了支援。 許多商業裝置已經配備了整合感測器 Hub (ISH)。 這些 ISH 也符合 HID 感測器規範,但不同之處在於用於通訊的傳輸協議。 目前的外部感測器 Hub 主要使用 HID over I2C 或 USB。 但是 ISH 不使用 I2C 或 USB。

概述

如果與 usbhid 實現進行類比,ISH 遵循類似的模型,以實現非常高速的通訊

-----------------               ----------------------
|    USB HID    |       -->     |    ISH HID         |
-----------------               ----------------------
-----------------               ----------------------
|  USB protocol |       -->     |    ISH Transport   |
-----------------               ----------------------
-----------------               ----------------------
|  EHCI/XHCI    |       -->     |    ISH IPC         |
-----------------               ----------------------
      PCI                                PCI
-----------------               ----------------------
|Host controller|       -->     |    ISH processor   |
-----------------               ----------------------
     USB Link
-----------------               ----------------------
| USB End points|       -->     |    ISH Clients     |
-----------------               ----------------------

與 USB 協議提供裝置列舉、連結管理和使用者資料封裝的方法一樣,ISH 也提供類似的服務。 但它非常輕量級,專門用於管理和與韌體中實現的 ISH 客戶端應用程式進行通訊。

ISH 允許在韌體中執行多個感測器管理應用程式。 就像 USB 端點一樣,訊息可以是傳送到/來自客戶端的。 作為列舉過程的一部分,這些客戶端會被識別。 這些客戶端可以是簡單的 HID 感測器應用程式、感測器校準應用程式或感測器韌體更新應用程式。

實現模型類似,就像 USB 匯流排一樣,ISH 傳輸也被實現為匯流排。 每個在 ISH 處理器中執行的客戶端應用程式都會註冊為該總線上的裝置。 繫結每個裝置(ISH HID 驅動程式)的驅動程式會識別裝置型別並註冊到 HID 核心。

ISH 實現:框圖

       ---------------------------
      |  User Space Applications  |
       ---------------------------

----------------IIO ABI----------------
       --------------------------
      |  IIO Sensor Drivers     |
       --------------------------
       --------------------------
      |        IIO core         |
       --------------------------
       --------------------------
      |   HID Sensor Hub MFD    |
       --------------------------
       --------------------------
      |       HID Core          |
       --------------------------
       --------------------------
      |   HID over ISH Client   |
       --------------------------
       --------------------------
      |   ISH Transport (ISHTP) |
       --------------------------
       --------------------------
      |      IPC Drivers        |
       --------------------------
OS
---------------- PCI -----------------
Hardware + Firmware
       ----------------------------
      | ISH Hardware/Firmware(FW) |
       ----------------------------

以上模組中的高階處理

硬體介面

ISH 作為“非 VGA 未分類 PCI 裝置”暴露給主機。 PCI 產品和供應商 ID 會隨著不同代的處理器而改變。 因此,列舉驅動程式的原始碼需要代代更新。

處理器間通訊 (IPC) 驅動程式

位置:drivers/hid/intel-ish-hid/ipc

IPC 訊息使用記憶體對映 I/O。 暫存器在 hw-ish-regs.h 中定義。

IPC/FW 訊息型別

有兩種型別的訊息,一種用於連結管理,另一種用於傳送到/來自傳輸層的訊息。

傳輸訊息的 TX 和 RX

一組記憶體對映暫存器提供了對多位元組訊息 TX 和 RX 的支援(例如,IPC_REG_ISH2HOST_MSG、IPC_REG_HOST2ISH_MSG)。 IPC 層維護內部佇列以對訊息進行排序,並按順序將其傳送到韌體。 或者,呼叫者可以註冊處理程式以獲取完成通知。 訊息傳遞中使用門鈴機制來觸發主機和客戶端韌體端的處理。 當呼叫 ISH 中斷處理程式時,主機驅動程式使用 ISH2HOST 門鈴暫存器來確定中斷是否用於 ISH。

每一側都有 32 個 32 位訊息暫存器和一個 32 位門鈴。 門鈴暫存器具有以下格式

Bits 0..6: fragment length (7 bits are used)
Bits 10..13: encapsulated protocol
Bits 16..19: management command (for IPC management protocol)
Bit 31: doorbell trigger (signal H/W interrupt to the other side)
Other bits are reserved, should be 0.

傳輸層介面

為了抽象 HW 級別的 IPC 通訊,註冊了一組回撥。 傳輸層使用它們來發送和接收訊息。 請參閱結構 ishtp_hw_ops 以獲取回撥。

ISH 傳輸層

位置:drivers/hid/intel-ish-hid/ishtp/

通用傳輸層

傳輸層是雙向協議,它定義: - 用於啟動、停止、連線、斷開連線和流量控制的一組命令(有關詳細資訊,請參閱 ishtp/hbm.h) - 一種避免緩衝區溢位的流量控制機制

此協議類似於以下文件中描述的匯流排訊息: http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/dcmi-hi-1-0-spec.pdf “第 7 章:匯流排訊息層”

連線和流量控制機制

每個 FW 客戶端和協議都由 UUID 標識。 為了與 FW 客戶端通訊,必須使用連線請求和響應匯流排訊息建立連線。 如果成功,一對(host_client_id 和 fw_client_id)將標識該連線。

建立連線後,對等方會彼此獨立地傳送流量控制匯流排訊息。 只有在之前收到流量控制信用時,每個對等方才能傳送訊息。 一旦傳送了一條訊息,在收到下一個流量控制信用之前,它就不能傳送另一條訊息。 任何一方都可以傳送斷開連線請求匯流排訊息以結束通訊。 如果發生重大 FW 重置,連結也會被丟棄。

對等資料傳輸

對等資料傳輸可以在使用或不使用 DMA 的情況下發生。 根據感測器頻寬要求,可以透過在 intel_ishtp 下使用模組引數 ishtp_use_dma 來啟用 DMA。

每一側(主機和 FW)獨立管理其 DMA 傳輸記憶體。 當來自主機或 FW 側的 ISHTP 客戶端想要傳送某些內容時,它會決定是透過 IPC 還是透過 DMA 傳送; 對於每次傳輸,該決策都是獨立的。 當訊息位於相應的宿主緩衝區中時,傳送方會發送 DMA_XFER 訊息(主機客戶端傳送時為 TX,FW 客戶端傳送時為 RX)。 DMA 訊息的接收者以 DMA_XFER_ACK 響應,表明該訊息的記憶體區域可以重複使用。

DMA 初始化從主機發送 DMA_ALLOC_NOTIFY 匯流排訊息(包括 RX 緩衝區)開始,FW 以 DMA_ALLOC_NOTIFY_ACK 響應。 除了 DMA 地址通訊之外,此序列還檢查功能:如果主機不支援 DMA,則它不會發送 DMA 分配,因此 FW 無法傳送 DMA; 如果 FW 不支援 DMA,則它不會以 DMA_ALLOC_NOTIFY_ACK 響應,在這種情況下,主機將不使用 DMA 傳輸。 在這裡,ISH 充當匯流排主控 DMA 控制器。 因此,當主機發送 DMA_XFER 時,它是執行主機->ISH DMA 傳輸的請求; 當 FW 傳送 DMA_XFER 時,這意味著它已經完成了 DMA,並且該訊息駐留在主機中。 因此,DMA_XFER 和 DMA_XFER_ACK 充當所有權指示器。

在初始狀態下,所有傳出的記憶體都屬於傳送者(TX 給主機,RX 給 FW),DMA_XFER 將包含 ISHTP 訊息的區域的所有權轉移到接收方,DMA_XFER_ACK 將所有權返回給傳送者。 只要其所有權中剩餘的連續記憶體足夠,傳送者無需等待之前的 DMA_XFER 被確認,就可以傳送另一條訊息。 原則上,可以一次傳送多個 DMA_XFER 和 DMA_XFER_ACK 訊息(最多 IPC MTU),從而允許進行中斷抑制。 目前,如果 ISHTP 訊息大於 3 個 IPC 片段,則 ISH FW 決定透過 DMA 傳送,否則透過 IPC 傳送。

環形緩衝區

當客戶端啟動連線時,會分配 RX 和 TX 緩衝區的環形。 環形的大小可以由客戶端指定。 HID 客戶端分別將 TX 和 RX 緩衝區設定為 16 和 32。 在客戶端的傳送請求時,要傳送的資料會被複制到其中一個傳送環形緩衝區,並計劃使用匯流排訊息協議傳送。 需要這些緩衝區是因為 FW 可能尚未處理上一條訊息,並且可能沒有足夠的流量控制信用可以傳送。 相同的情況適用於接收端,並且需要流量控制。

主機列舉

主機列舉匯流排命令允許發現 FW 中存在的客戶端。 可以有多個感測器客戶端和用於校準功能的客戶端。

為了簡化實現並允許獨立的驅動程式處理每個客戶端,此傳輸層利用了 Linux 匯流排驅動程式模型。 每個客戶端都會註冊為傳輸匯流排(ishtp 匯流排)上的裝置。

訊息的列舉序列

  • 主機發送 HOST_START_REQ_CMD,表明主機 ISHTP 層已啟動。

  • FW 以 HOST_START_RES_CMD 響應

  • 主機發送 HOST_ENUM_REQ_CMD(列舉 FW 客戶端)

  • FW 以 HOST_ENUM_RES_CMD 響應,其中包含可用 FW 客戶端 ID 的點陣圖

  • 對於在該點陣圖中找到的每個 FW ID,主機發送 HOST_CLIENT_PROPERTIES_REQ_CMD

  • FW 以 HOST_CLIENT_PROPERTIES_RES_CMD 響應。 屬性包括 UUID、最大 ISHTP 訊息大小等。

  • 一旦主機收到最後一個發現的客戶端的屬性,它就認為 ISHTP 裝置完全正常執行(並分配 DMA 緩衝區)

HID over ISH 客戶端

位置:drivers/hid/intel-ish-hid

ISHTP 客戶端驅動程式負責

  • 列舉 FW ISH 客戶端下的 HID 裝置

  • 獲取報告描述符

  • 將自身註冊為 HID 核心的 LL 驅動程式

  • 處理 Get/Set 功能請求

  • 獲取輸入報告

HID 感測器 Hub MFD 和 IIO 感測器驅動程式

這些驅動程式中的功能與外部感測器 Hub 相同。 請參閱 HID 感測器框架,瞭解 HID 感測器 ABI 檔案測試/sysfs-bus-iio,瞭解 IIO ABI 到使用者空間。

端到端 HID 傳輸序列圖

HID-ISH-CLN                    ISHTP                    IPC                             HW
        |                        |                       |                               |
        |                        |                       |-----WAKE UP------------------>|
        |                        |                       |                               |
        |                        |                       |-----HOST READY--------------->|
        |                        |                       |                               |
        |                        |                       |<----MNG_RESET_NOTIFY_ACK----- |
        |                        |                       |                               |
        |                        |<----ISHTP_START------ |                               |
        |                        |                       |                               |
        |                        |<-----------------HOST_START_RES_CMD-------------------|
        |                        |                       |                               |
        |                        |------------------QUERY_SUBSCRIBER-------------------->|
        |                        |                       |                               |
        |                        |------------------HOST_ENUM_REQ_CMD------------------->|
        |                        |                       |                               |
        |                        |<-----------------HOST_ENUM_RES_CMD--------------------|
        |                        |                       |                               |
        |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
        |                        |                       |                               |
        |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
        |       Create new device on in ishtp bus        |                               |
        |                        |                       |                               |
        |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
        |                        |                       |                               |
        |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
        |       Create new device on in ishtp bus        |                               |
        |                        |                       |                               |
        |                        |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
        |                        |                       |                               |
     probed()
        |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
        |                        |                       |                               |
        |                        |<----------------CLIENT_CONNECT_RES_CMD----------------|
        |                        |                       |                               |
        |register event callback |                       |                               |
        |                        |                       |                               |
        |ishtp_cl_send(
        HOSTIF_DM_ENUM_DEVICES)  |----------fill ishtp_msg_hdr struct write to HW-----  >|
        |                        |                       |                               |
        |                        |                       |<-----IRQ(IPC_PROTOCOL_ISHTP---|
        |                        |                       |                               |
        |<--ENUM_DEVICE RSP------|                       |                               |
        |                        |                       |                               |
for each enumerated device
        |ishtp_cl_send(
        HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW-----  >|
        |                        |                       |                               |
        ...Response
        |                        |                       |                               |
for each enumerated device
        |ishtp_cl_send(
     HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
        |                        |                       |                               |
        |                        |                       |                               |
 hid_allocate_device
        |                        |                       |                               |
 hid_add_device                  |                       |                               |
        |                        |                       |                               |

從主機載入 ISH 韌體的流程

從 Lunar Lake 世代開始,ISH 韌體被分為兩個元件,以實現更好的空間最佳化和更高的靈活性。 這些元件包括一個整合到 BIOS 中的引導載入程式和一個儲存在作業系統檔案系統中的主韌體。

該過程如下所示

  • 最初,ISHTP 驅動程式向 ISH 引導載入程式傳送命令 HOST_START_REQ_CMD。 作為響應,引導載入程式發回 HOST_START_RES_CMD。 此響應包括 ISHTP_SUPPORT_CAP_LOADER 位。 隨後,ISHTP 驅動程式檢查是否設定了此位。 如果是,則從主機開始韌體載入過程。

  • 在此過程中,ISHTP 驅動程式首先呼叫 request_firmware() 函式,然後傳送 LOADER_CMD_XFER_QUERY 命令。 收到來自引導載入程式的響應後,ISHTP 驅動程式傳送 LOADER_CMD_XFER_FRAGMENT 命令。 收到另一個響應後,ISHTP 驅動程式傳送 LOADER_CMD_START 命令。 引導載入程式做出響應,然後繼續執行主韌體。

  • 該過程結束後,ISHTP 驅動程式會呼叫 release_firmware() 函式。

有關更多詳細資訊,請參閱以下提供的流程描述

+---------------+                                                    +-----------------+
| ISHTP Driver  |                                                    | ISH Bootloader  |
+---------------+                                                    +-----------------+
        |                                                                     |
        |~~~Send HOST_START_REQ_CMD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
        |                                                                     |
        |<--Send HOST_START_RES_CMD(Includes ISHTP_SUPPORT_CAP_LOADER bit)----|
        |                                                                     |
****************************************************************************************
* if ISHTP_SUPPORT_CAP_LOADER bit is set                                               *
****************************************************************************************
        |                                                                     |
        |~~~start loading firmware from host process~~~+                      |
        |                                              |                      |
        |<---------------------------------------------+                      |
        |                                                                     |
---------------------------                                                   |
| Call request_firmware() |                                                   |
---------------------------                                                   |
        |                                                                     |
        |~~~Send LOADER_CMD_XFER_QUERY~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
        |                                                                     |
        |<--Send response-----------------------------------------------------|
        |                                                                     |
        |~~~Send LOADER_CMD_XFER_FRAGMENT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
        |                                                                     |
        |<--Send response-----------------------------------------------------|
        |                                                                     |
        |~~~Send LOADER_CMD_START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>|
        |                                                                     |
        |<--Send response-----------------------------------------------------|
        |                                                                     |
        |                                                                     |~~~Jump to Main Firmware~~~+
        |                                                                     |                           |
        |                                                                     |<--------------------------+
        |                                                                     |
---------------------------                                                   |
| Call release_firmware() |                                                   |
---------------------------                                                   |
        |                                                                     |
****************************************************************************************
* end if                                                                               *
****************************************************************************************
        |                                                                     |
+---------------+                                                    +-----------------+
| ISHTP Driver  |                                                    | ISH Bootloader  |
+---------------+                                                    +-----------------+

供應商自定義韌體載入

在 ISH 內部執行的韌體可以由 Intel 提供,也可以由供應商使用 Intel 提供的韌體開發套件 (FDK) 開發。 Intel 會將 Intel 構建的韌體上傳到 linux-firmware.git 儲存庫,該儲存庫位於路徑 intel/ish/ 下。 對於 Lunar Lake 平臺,Intel 構建的 ISH 韌體將被命名為 ish_lnlm.bin。 希望上傳其自定義韌體的供應商應遵循以下命名其韌體檔案的指南

  • 韌體檔名應使用以下模式之一

    • ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin

    • ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin

    • ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin

    • ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin

  • ${intel_plat_gen} 表示 Intel 平臺代(例如,Lunar Lake 的 lnlm),並且長度不得超過 8 個字元。

  • ${SYS_VENDOR_CRC32} 是來自 DMI 欄位 DMI_SYS_VENDORsys_vendor 值的 CRC32 校驗和。

  • ${PRODUCT_NAME_CRC32} 是來自 DMI 欄位 DMI_PRODUCT_NAMEproduct_name 值的 CRC32 校驗和。

  • ${PRODUCT_SKU_CRC32} 是來自 DMI 欄位 DMI_PRODUCT_SKUproduct_sku 值的 CRC32 校驗和。

在系統啟動期間,ISH Linux 驅動程式將嘗試按以下順序載入韌體,優先載入具有更精確匹配模式的自定義韌體

  1. intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}_${PRODUCT_SKU_CRC32}.bin

  2. intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_SKU_CRC32}.bin

  3. intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}_${PRODUCT_NAME_CRC32}.bin

  4. intel/ish/ish_${intel_plat_gen}_${SYS_VENDOR_CRC32}.bin

  5. intel/ish/ish_${intel_plat_gen}.bin

驅動程式將載入第一個匹配的韌體並跳過其餘韌體。 如果找不到匹配的韌體,它將按指定順序繼續執行下一個模式。 如果所有搜尋都失敗,則將載入預設的 Intel 韌體(在上面的順序中最後列出)。

ISH 除錯

要除錯 ISH,請使用事件跟蹤機制。 要啟用除錯日誌

echo 1 > /sys/kernel/tracing/events/intel_ish/enable
cat /sys/kernel/tracing/trace

Lenovo thinkpad Yoga 260 上的 ISH IIO sysfs 示例

root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
/sys/bus/iio/devices/
├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
│   ├── buffer
│   │   ├── enable
│   │   ├── length
│   │   └── watermark
...
│   ├── in_accel_hysteresis
│   ├── in_accel_offset
│   ├── in_accel_sampling_frequency
│   ├── in_accel_scale
│   ├── in_accel_x_raw
│   ├── in_accel_y_raw
│   ├── in_accel_z_raw
│   ├── name
│   ├── scan_elements
│   │   ├── in_accel_x_en
│   │   ├── in_accel_x_index
│   │   ├── in_accel_x_type
│   │   ├── in_accel_y_en
│   │   ├── in_accel_y_index
│   │   ├── in_accel_y_type
│   │   ├── in_accel_z_en
│   │   ├── in_accel_z_index
│   │   └── in_accel_z_type
...
│   │   ├── devices
│   │   │   │   ├── buffer
│   │   │   │   │   ├── enable
│   │   │   │   │   ├── length
│   │   │   │   │   └── watermark
│   │   │   │   ├── dev
│   │   │   │   ├── in_intensity_both_raw
│   │   │   │   ├── in_intensity_hysteresis
│   │   │   │   ├── in_intensity_offset
│   │   │   │   ├── in_intensity_sampling_frequency
│   │   │   │   ├── in_intensity_scale
│   │   │   │   ├── name
│   │   │   │   ├── scan_elements
│   │   │   │   │   ├── in_intensity_both_en
│   │   │   │   │   ├── in_intensity_both_index
│   │   │   │   │   └── in_intensity_both_type
│   │   │   │   ├── trigger
│   │   │   │   │   └── current_trigger
...
│   │   │   │   ├── buffer
│   │   │   │   │   ├── enable
│   │   │   │   │   ├── length
│   │   │   │   │   └── watermark
│   │   │   │   ├── dev
│   │   │   │   ├── in_magn_hysteresis
│   │   │   │   ├── in_magn_offset
│   │   │   │   ├── in_magn_sampling_frequency
│   │   │   │   ├── in_magn_scale
│   │   │   │   ├── in_magn_x_raw
│   │   │   │   ├── in_magn_y_raw
│   │   │   │   ├── in_magn_z_raw
│   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
│   │   │   │   ├── in_rot_hysteresis
│   │   │   │   ├── in_rot_offset
│   │   │   │   ├── in_rot_sampling_frequency
│   │   │   │   ├── in_rot_scale
│   │   │   │   ├── name
...
│   │   │   │   ├── scan_elements
│   │   │   │   │   ├── in_magn_x_en
│   │   │   │   │   ├── in_magn_x_index
│   │   │   │   │   ├── in_magn_x_type
│   │   │   │   │   ├── in_magn_y_en
│   │   │   │   │   ├── in_magn_y_index
│   │   │   │   │   ├── in_magn_y_type
│   │   │   │   │   ├── in_magn_z_en
│   │   │   │   │   ├── in_magn_z_index
│   │   │   │   │   ├── in_magn_z_type
│   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
│   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
│   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
│   │   │   │   ├── trigger
│   │   │   │   │   └── current_trigger
...
│   │   │   │   ├── buffer
│   │   │   │   │   ├── enable
│   │   │   │   │   ├── length
│   │   │   │   │   └── watermark
│   │   │   │   ├── dev
│   │   │   │   ├── in_anglvel_hysteresis
│   │   │   │   ├── in_anglvel_offset
│   │   │   │   ├── in_anglvel_sampling_frequency
│   │   │   │   ├── in_anglvel_scale
│   │   │   │   ├── in_anglvel_x_raw
│   │   │   │   ├── in_anglvel_y_raw
│   │   │   │   ├── in_anglvel_z_raw
│   │   │   │   ├── name
│   │   │   │   ├── scan_elements
│   │   │   │   │   ├── in_anglvel_x_en
│   │   │   │   │   ├── in_anglvel_x_index
│   │   │   │   │   ├── in_anglvel_x_type
│   │   │   │   │   ├── in_anglvel_y_en
│   │   │   │   │   ├── in_anglvel_y_index
│   │   │   │   │   ├── in_anglvel_y_type
│   │   │   │   │   ├── in_anglvel_z_en
│   │   │   │   │   ├── in_anglvel_z_index
│   │   │   │   │   └── in_anglvel_z_type
│   │   │   │   ├── trigger
│   │   │   │   │   └── current_trigger
...
│   │   │   │   ├── buffer
│   │   │   │   │   ├── enable
│   │   │   │   │   ├── length
│   │   │   │   │   └── watermark
│   │   │   │   ├── dev
│   │   │   │   ├── in_anglvel_hysteresis
│   │   │   │   ├── in_anglvel_offset
│   │   │   │   ├── in_anglvel_sampling_frequency
│   │   │   │   ├── in_anglvel_scale
│   │   │   │   ├── in_anglvel_x_raw
│   │   │   │   ├── in_anglvel_y_raw
│   │   │   │   ├── in_anglvel_z_raw
│   │   │   │   ├── name
│   │   │   │   ├── scan_elements
│   │   │   │   │   ├── in_anglvel_x_en
│   │   │   │   │   ├── in_anglvel_x_index
│   │   │   │   │   ├── in_anglvel_x_type
│   │   │   │   │   ├── in_anglvel_y_en
│   │   │   │   │   ├── in_anglvel_y_index
│   │   │   │   │   ├── in_anglvel_y_type
│   │   │   │   │   ├── in_anglvel_z_en
│   │   │   │   │   ├── in_anglvel_z_index
│   │   │   │   │   └── in_anglvel_z_type
│   │   │   │   ├── trigger
│   │   │   │   │   └── current_trigger
...