Linux之IIO子系统简介

概述

IIO (Industrial I/O) 是一个用于模数转换器(ADCs)、数模转换器(DACs)和各种传感器的子系统。它可用于高速、高数据率的工业设备。直到最近,它主要关注用户空间抽象。它还包括内核中的API供其他驱动程序使用。

IIO子系统提供了一个统一的框架来与驱动程序通信(读取和写入),涵盖了许多不同类型的嵌入式传感器和少数执行器。它还提供了一个标准接口,通过sysfs和devfs来处理传感器的用户空间应用程序。

以下是一些在IIO中支持的传感器类型:

  • 模数转换器 / 数模转换器
  • 加速度计
  • 磁力计
  • 陀螺仪
  • 压力
  • 湿度
  • 温度
  • 光和接近传感器
  • 等等

iio.png

IIO子系统与hwmon和input子系统比较类似(某些情况下甚至存在相当大的重叠,比如通过SPI或I2C连接的外设),但IIO总体目标是为了填补其他2个子系统的一些不足和缺失。

  • hwmon子系统主要针对用于风扇速度控制和温度测量等应用中的低采样率传感器。
  • input子系统主要关注于人类互动(HID)的输入设备,比如键鼠、触摸屏、操纵杆等。

IIO系统框架

以下是从 ST MPU 官方wiki截取的一张 IIO系统 整体框架图,觉得挺完善的:
IIO-overview.png

说明:

  • 客户端应用程序(用户空间): 一个通过 libiio 配置、从IIO设备读取或写入数据的应用程序。
  • iiod 服务器(用户空间): 这是可选的。基于 libiio 的应用程序可以通过IIO守护进程服务器进行远程访问IIO“本地”后端(通过网络)。
  • libiio (用户空间): libiio 是一个用于开发IIO相关应用程序的完整API库。它由一套高级 API 和两个后端组成:
    1. “本地”后端,对接Linux内核 IIO API接口
    2. “network” 后端,通过网络链接对接 iiod 服务器接口。
  • 用户空间接口: 由标准字符设备、sysfs、configfs和debugfs(见API描述)组成。
  • 内核空间用户: 它可以是任何内核空间IIO消费者,例如其他音频驱动程序,IIOhwmon驱动程序等(参见如何使用IIO内核API)。
  • 内核空间接口: 它由一套标准的API组成。
  • IIO 框架 (内核空间): 它由一个核心core组成,负责管理数据缓冲区、用户空间事件、触发器。
  • IIO 驱动程序 (内核空间): 用于处理内部外设或外部设备。它们包括一个接口,向用户提供控制和数据 (如: ADC 驱动程序,DAC 驱动程序, 连接在 SPI 或 I2C 上的 IIO 设备驱动程序)。
  • 主控接口或内部外设 (硬件): 通过特定接口连接到外部设备(示例:ADC,DAC,SPI,或 I2C)
  • 外部设备 (硬件): 通过特定接口连接到STM32前端。这些可以是模拟设备(如加速度计、惯性测量单元…),ADC 调制器(用于音频记录、能量测量…),SPI 或 I2C接口的IIO外设…等

相关API接口

根据需求和使用位置(内核空间或用户空间),有多种API接口可以控制 IIO 设备。

用户空间接口

该IIO框架提供了几种用户空间接口:

  • iio 设备 sysfs 接口: 它用于配置哪些事件和数据应该从字符设备输出,例如/sys/bus/iio/devices/iio:deviceX
    在低速率下它可以用于读取(轮询)或直接写入数据。 IIO sysfs ABI文档在:Documentation/ABI/testing/sysfs-bus-iio。更多细节这里不再赘述,感兴趣的小伙伴可以去查看具体的官方文档。

  • 字符设备: 在IIO中是可选的。它用于输出事件和传感器数据,例如/dev/iio:deviceX
    从应用程序的角度来看,基本上是一个文件。标准文件API都可以访问它:open()、read()、write()、close()…等

  • configfs: 它允许配置额外的IIO功能,如软件和hrtimer触发器。
    IIO configfs 接口文档在:Documentation/ABI/testing/configfs-iioDocumentation/iio/iio_configfs.txt

  • Debugfs: 提供一些调试手段(例如 直接寄存器访问 入口来读写寄存器),具体取决于所使用的IIO 设备驱动程序。

libiio

Libiio 为客户端应用程序提供了一套用户空间的高级 API 。该库抽象了硬件的底层细节,封装在内核提供的用户空间接口(sysfs和字符设备)之上,向上提供了一套简单但完整的编程接口,由ADI开发维护。
官方主页: http://analogdevicesinc.github.io/libiio/

内核空间接口

IIO子系统也提供了相关内核空间接口,供其他子系统使用:

  • devm_iio_channel_get_all()iio_channel_get_all() / iio_channel_release_all():用于查找、获取并释放IIO通道。
  • iio_get_channel_type():获取通道的类型,例如 IIO_VOLTAGE, IIO_TEMP…
  • iio_read_channel_processed():读取通道处理值,例如电压以微伏计,温度以毫度计…
  • 。。。等等

更多可用的内核空间接口可以在内核头文件中找到:include/linux/iio/consumer.h

使用

使用的话细节比较多,这里篇幅有限,就不再继续细聊,有时间的话会单独另起一篇。

参考