定义
libiio 是一个跨平台的用户态软件库,用途是访问工业输入输出(Industrial I/O,IIO)设备[2]。IIO 最初是 Linux 内核中用来支持模数转换器(ADC)与数模转换器(DAC)一类器件的子系统,后来又扩展到加速度计、陀螺仪、惯性测量单元、电容数字转换器、压力与温度传感器、磁力计、直接数字合成器、锁相环、可变增益放大器以及射频收发器等多种器件[1]。
libiio 以 C 语言编写,对外提供一套高层应用编程接口,并配有 Python、C# 等语言的绑定[4][5]。库本身不直接操作寄存器,而是把设备抽象成上下文、设备、通道、属性等对象,由应用程序按名字枚举和读写,从而避免自行解析内核暴露的文本格式[2]。
原理
libiio 的模型是一棵由对象组成的树:根是一个上下文(context),上下文之下是设备,每个设备带有若干通道,通道又带有若干属性[6]。属性以名值对的形式表示采样率、中心频率、射频带宽、增益等可调设置,应用可以枚举设备实际提供了什么,而不必在代码里写死[2]。下面用 Mermaid 示意其对象层次。
graph TD
A[iio_context 上下文] --> B[iio_device 设备]
B --> C[iio_channel 通道]
C --> D[属性 名值对]
B --> E[iio_buffer 缓冲区]
A --> F[local 后端]
A --> G[remote 后端]
F --> H[内核 IIO 子系统]
G --> I[iiod 守护进程]
库由一个高层接口和若干后端组成:本地后端通过 sysfs 虚拟文件系统与 Linux 内核通信,远程后端则经由网络、USB 或串口链路与 iiod 服务器对话[7]。采样数据的传输通过缓冲区完成,程序先启用所需通道,创建指定大小的缓冲区,再反复填充(接收方向)或推送(发送方向)数据;库还提供按通道遍历交错采样、以及格式转换的辅助函数[2]。
由于后端可替换,同一份应用代码在本地、USB、网络之间切换时不需要修改,这被称为远程过程调用风格的接口[8]。iio_context 是库中唯一保存状态的对象,库本身没有全局状态,因此可以同时创建多个上下文[4]。
发展历程
IIO 框架本身先于 libiio 出现:它由 Jonathan Cameron 开发,自 2009 年进入内核,2012 年从暂存区移出,到 4.6 版内核时已有约 220 个 IIO 设备驱动[4]。libiio 的开发始于 2014 年初,同年 8 月发布首个稳定版本,此后大致保持每年两个稳定版本,主要维护者和首席开发者是 Paul Cercueil[4][9]。
自创建起,libiio 长期保持应用二进制接口(ABI)的稳定,这意味着围绕 0.1 版编写的程序在多年后的 0.3x 版上仍可运行[9]。2023 年 8 月 22 日起,项目主线分支转入面向 1.0 版的新接口,与 0.25 及更早版本不兼容;旧的 0.x 接口保留在单独分支上,仅接受重要缺陷修复,同时 1.0 版提供兼容层,使针对 0.x 编译的旧程序仍能运行[10]。1.0 版的改动包括后端模块化,除本地后端外均可动态加载,并新增了更底层的块式数据流接口[9]。
应用
在软件定义无线电领域,libiio 是访问模拟器件公司 SDR 系列器件的原生途径,最典型的是低成本 PlutoSDR 以及基于同一收发器的 FMComms 系列和 ADALM 开发板[6]。主机程序借助它设置中心频率、增益和采样率,并以 IQ 缓冲区的形式收发数据[6]。开源混合信号分析与生成工具包 Scopy 也用 libiio 连接 ADALM-2000,既可用 USB 也可用以太网建立连接[3]。
GNU Radio 通过 gr-iio 模块接入这些器件,该模块自 2021 年起进入 GNU Radio 官方代码库,并随 3.10 及之后的版本直接提供[11][12]。配套的命令行工具如 iio_info 可列出设备与其属性,iio_readdev 与 iio_writedev 用于缓冲区读写,iio_attr 用于属性读写[13]。
在嵌入式方向,本地后端与随库附带的 iiod 守护进程可运行于各类嵌入式 Linux 系统,从 PlutoSDR、ADALM2000 到 Raspberry Pi、BeagleBoard 与 Jetson[2]。针对资源受限且无操作系统的平台,另有独立的 tiny-iiod 实现,可在裸机、Zephyr、FreeRTOS 等环境提供与 libiio 兼容的接口,经网络或串口与客户端通信[13][8]。
局限
libiio 的接口虽然灵活,但使用起来较为繁琐,需要编写大量样板代码[2]。当应用通过内核 IIO 框架访问设备时,很多问题实际出在驱动一侧,而 libiio 本身并不解决这一层的问题[2]。
不同后端在部分行为上并不完全一致。例如在读取某一属性时若提供的缓冲区过小,本地后端会截断内容并返回成功,而 USB、以太网等经 iiod 的远程后端会返回输入输出错误[14]。远程访问还受限于 iiod 所在的网络环境,跨网段的级联设备需要额外配置才能被发现[15]。
0.x 与 1.0 之间的 API 不兼容,是既有项目升级时必须面对的问题:新版本引入了全新的接口,旧接口转入维护状态[10]。此外,库的功能边界止于设备访问与数据传输,信号本身的处理需要由 GNU Radio 等上层框架完成[3]。
参见
参考资料
- README [引用日期2026-10-14]
- Welcome to the libIIO [引用日期2026-10-14]
- Background [引用日期2026-10-14]
- Introduction to IIO [引用日期2026-10-14]
- Libiio [引用日期2026-10-14]
- libiio [引用日期2026-10-14]
- What is libiio? — System Level Documentation documentation [引用日期2026-10-14]
- libiio Documentation [引用日期2026-10-14]
- GNU Radio Conference 2022 [引用日期2026-10-14]
- README [引用日期2026-10-14]
- GNU Radio Conference 2021 [引用日期2026-10-14]
- GNU Radio and IIO Devices: gr-iio [引用日期2026-10-14]
- LinuxIIO-OSS-NA25(PDF) [引用日期2026-10-14]
- github.com 上的网页 [引用日期2026-10-14]
- analog.com 上的网页 [引用日期2026-10-14]