最佳入门教程!嵌入式必会的Linux驱动开发之IIO子系统

嵌入式ARM 2020-07-31 00:00


前阵子工作上做了一些关于 ADC 的支持,由于现在 ADC 相关的支持都被移动到了 IIO (Industrial I/O) 子系统下,我查阅了一些关于 IIO 资料,包括书籍、文章、内核文档和代码。个人感觉最好的入门文章应该是 ST WiKi 网站上 的 IIO Overview(2019) 和 Analog Device Wiki 网站上的 Linux Industrial I/O Subsystem(2017),为了方便爱偷懒或者英文不好的小伙伴,我提炼了多篇文章的精华内容并在其基础上进行完善,尽量控制篇幅,希望能给大家提供一点小小的帮助。

Linux 驱动开发 / IIO子系统入门1

正文目录:
    
1. 什么是 IIO 子系统?
  1.1 IIO 概述
  1.2 IIO 相关的组件
2. IIO 功能特性
3. IIO 相关配置  
  3.1 配置内核
  3.2 配置设备树
    3.2.1 IIO providers
    3.2.2 IIO consumers
4. IIO API
  4.1 用户空间 API
    4.1.1 4种接口
    4.1.2 操作实例
5. 更多值得学习的知识点
6. 相关参考
写作目的:
  • 整理一些 IIO 子系统的入门知识。

1. 什么是 IIO 子系统?

1.1 IIO 概述

Industrial I/O 子系统旨在为某种意义上是模数或数模转换器 (ADC,DAC) 的设备提供支持,于2009年由 Huawei 的 Jonathan Cameront 添加。
简单框图:
支持的设备包括:
    
ADC / DAC
加速度计
磁力计
陀螺仪
压力传感器
湿度传感器
温度传感器
...
很久以前,对于上述硬件的支持散落在 Linux 源码中的各种地方。
IIO 的出现,提供了一个统一的框架用于访问和控制上述各种类型的传感器,并且为用户态应用访问传感器提供了标准的接口:sysfs/devfs,并且填补了 Hwmon 和 Input 子系统之间的空白
另外,IIO 不仅可以支持低速的 SoC ADC,还可支持高速、高数据速率的工业设备,例如 100M samples/sec 工业 ADC。

1.2 IIO 相关的组件

IIO-overview
上图基于 STM32 MPU,来源见文末。
1) 客户端应用程序(用户空间):

该组件会使用 libiio 库来配置 IIO 设备,然后从 IIO 设备读数据或者写数据到 IIO 设备中。客户端程序可以细分为 local client 和 remote client。
2) libiio 库(用户空间):

libiio 是 Analog Device 公司发起的一个用于访问 IIO 设备的开源库。
它封装了对 /sys/bus/iio/devices(配置 iio) 和 /dev/iio/deviceX(读写iio) 的访问,并且提供了便于测试的 iio 命令行工具 (iio_info / iio_readdev) 和 iiod server
iiod server 内含 local backend 和 remote backend 以支持 local client 和 remote client 的访问。
libiio 的源码位于:github libiio
3) 访问接口(用户空间):
iio 支持多种标准的 Linux 设备访问接口:
char device, sysfs, configfs, debugfs。
4) 内核空间的 iio 消费者(即 IIO consumers):

除了用户空间的应用程序能访问 iio 设备之外,在内核里也有其他设备驱动需要使用 iio 子系统的 API 来编写符合自身框架的设备驱动
例如在 iio 子系统里支持了某款 Soc ADC 后,可能会有不同的硬件设备接到该 ADC 通道上,典型的例子是触摸芯片,开发人员需要在 input 子系统的框架下编写 touch driver,在 touch driver的 irq handler 中 调用 iio in-kern API 来读取触摸屏的 X、Y 值。
iio in-kernl API的定义位于头文件:
include/linux/iio/consumer.h
5) IIO framework(内核空间):
IIO 子系统的核心实现。
6) IIO device driver(或称 IIO providers):
7) Linux 内核自带的 IIO 调试工具:

2. IIO 的功能特性

相关参考:
  • Linux-4.14/drivers/staging/iio/Documentation/overview.txt
1) 基础的设备注册和访问
  • 类似于 hwmon 子系统,它们都可以通过 sysfs 以轮循的方式访问设备;
2) 可读取事件的字符设备(Event chrdevs)
  • 类似于 input 子系统,iio 子系统也可以向应用层上报事件(hardware triggered events),例如阈值检测事件,自由落体检测事件、更复杂的动作检测事件;

  • 目前 event 的格式为:event code + 时间戳;

3) 支持硬件 buffer
4) 支持 Trigger 和软件 buffer

3. IIO 相关配置

3.1 配置内核

Linux-4.14:
    
$ make menuconfig
Device Drivers  --->
  <*> Industrial I/O support  --->
    [*]   Enable buffer support within IIO
     < >     IIO callback buffer used  for push in-kernel interfaces
     <*>     Industrial I/O HW buffering
     <*>     Industrial I/O buffering based on kfifo
     < >   Enable IIO configuration via configfs                        
     [*]    Enable triggered sampling support
     (2)     Maximum number of consumers per trigger                    
     < >   Enable software triggers support                             
           Accelerometers  --->                                         
           Analog to digital converters  --->                          
           Amplifiers  --->                                             
           Chemical Sensors  --->                                       
           Hid Sensor IIO Common  ----                                  
           SSP Sensor Common  --->                                      
           Digital to analog converters  --->                           
           IIO dummy driver  --->                                       
           Frequency Synthesizers DDS/PLL  --->                         
           Digital gyroscope sensors  --->                              
           Health Sensors  --->                                         
           Humidity sensors  --->                                       
           Inertial measurement units  --->                             
           Light sensors  --->                                          
           Magnetometer sensors  --->                                   
           Inclinometer sensors  ----                                   
           Triggers - standalone  --->                                  
           Digital potentiometers  --->                                 
           Pressure sensors  --->                                       
           Lightning sensors  --->                                      
           Proximity sensors  --->                                      
           Temperature sensors  --->
从配置项的数目来看,IIO 的用途真的很广泛。

3.2 配置设备树

相关参考:
  • Linux-4.14/Documentation/devicetree/bindings/iio/iio-bindings.txt

3.2.1 IIO providers

1) 相关要点:
  • IIO channels 源在设备树中用 IIO providers 来指定;
2) 必要属性:
  • io-channel-cells,0 表示只有 1 路 IIO output,1 表示有多路 IIO output;

  • io-channel-ranges: 一个 empty 属性(即不用赋值),会在 driver/iio/inkern.c/iio_channel_get() 中被引用,它表明继承了当前节点的子节点可以引用当前节点的 IIO channel;

3) 例子1 (no trigger)
    
adc: voltage-sensor@ 35 {
  compatible =  "maxim,max1139";
  reg = < 0x35>;
   #io-channel-cells = <1>;
};
4) 例子2 (with trigger)
    
adc@ 35 {
  compatible =  "some-vendor,some-adc";
  reg = < 0x35>;

  adc1: iio-device@ 0 {
     #io-channel-cells = <1>;
     /* other properties */
  };
  adc2: iio-device@ 1 {
     #io-channel-cells = <1>;
     /* other properties */
  };
};

3.2.2 IIO consumers

1) 相关要点:
  • IIO consumer 节点的形式是 <phandle iio_specifier>;

  • 它的作用是连接 IIO provider 的 input 端到 IIO consumer 的 output 端;

  • 其中,phandle 是 IIO provider 的句柄,specifier 用于选择第几路 channel;

  • 类似 gpio specifier, IIO specifier 是有 1 个或者多个 cells 的数组,用于确定 IIO device的 output 端,即 1 个 cell 对应一个 IIO channel output;

  • IIO specifier 数组的长度由 IIO provider 节点的 #io-channel-cells 属性决定;

2) 必要属性:
  • io-channels: <phandle iio_specifier> 列表, 一个 <phandle iio_specifier> 代表该设备连接着的一路 IIO input。如果 IIO provider 的 io-channel-cells=0 (即只有1路 IIO output), 则省略 iio_specifier。
3) 可选属性:
  • io-channel-names: IIO input 的名称列表,顺序要和 io-channels 属性保持一致,Consumers drivers 会将该名称和 iio_specifier 指定的 IIO input match 到一起。
4) 例子1
    
some_consumer {
  io-channels = <&adc  1>, <&ref  0>;
  io-channel-names =  "vcc""vdd";
 };
上述例子的引用了provider &adc 的第1路 channel,和proiver &ref 的第0路 channel。

4. IIO API

4.1 用户空间 API

相关参考:
  • IIO user space interface
  • How to use the IIO user space interface

4.1.1 4种接口

1). sysfs interface
  • /sys/bus/iio/devices/iio:deviceX;

  • 可用于配置 /dev/iio:deviceX 接口的 events / data

  • 可用于轮循的方式低速地直接读/写 IIO 设备;

  • Documentation/ABI/testing/sysfs-bus-iio;

2). character device
  • /dev/iio:deviceX,该接口在 IIO 子系统里是可选非必要的;

  • 标准的文件 IO API: open(), read(), write(), close().

  • 用于读取 events 和 data;

3). configfs
  • 用于配置额外的 IIO 特性,例如:软件 triggers 或者 hrtimer triggers;

  • 详细说明:

    • Documentation/ABI/testing/configfs-iio;
    • Documentation/iio/iio_configfs.txt;
4). debugfs
  • 一些调试功能,例如 direct_reg_access 节点可用于读写寄存器;

4.1.2 操作实例

IIO direct mode: 通过 sysfs 以轮循的方式读 ADC 或者写 DAC:
1) 直接读 ADC
确定 sysfs 节点(方式1,不依赖工具)
    
$ grep -H  "" /sys/bus/iio/devices /*/name | grep adc
/sys/bus/iio/devices/iio:device0/name:48003000.adc:adc@0
/sys/bus/iio/devices/iio:device1/name:48003000.adc:adc@1
sysfs 中的 iio:device0 sysfs 对应 ADC1;
    
$ cd /sys/bus/iio/devices/iio:device0/
$ cat in_voltage6_raw      # Convert ADC1 channel  0 (analog-to-digital): get raw value
40603
$ cat in_voltage_scale     # Read scale
0.044250488
$ cat in_voltage_offset    # Read offset
0
$ awk  "BEGIN{printf (\"%d\n\", (40603 + 0) * 0.044250488)}"
1796  
计算公式: Scaled value = (raw + offset) * scale = 1796 mV;
2) 直接写 DAC
确定 sysfs 节点(方式2)
    
$ lsiio | grep dac
Device  00340017000.dac:dac@ 1
Device  00440017000.dac:dac@ 2
sysfs 中的 iio:device3 sysfs 对应 DAC1,lsiio 来源于Linux 内核源码(tools/iio/)。
    
$ cd /sys/bus/iio/devices/iio:device3/
$ cat out_voltage1_scale              # Read scale
0.708007812
$ awk  "BEGIN{printf (\"%d\n\", 2000 / 0.708007812)}"  # 假设要输出  2000 mV
2824
$ echo  2824 > out_voltage1_raw        # Write raw value to DAC1
$ echo  0 > out_voltage1_powerdown     #  Enable DAC1 (out of power-down mode)

5. 更多值得学习的知识点

  • 以 timer triggers 和 buffers 的方式读 ADC 或者写 DAC;
  • IIO 内核空间 API;
  • 编写 IIO device driver
  • 编写 IIO consumer driver
  • ...
鉴于大多数人的注意力无法在一篇文章里上集中太久,更多的内容请大家先自行去阅读吧,不是自己理解到的东西是消化不了的。有机会的话我会把更多的读书心得放在后面的文章。

6. 相关参考

  • IIO Overview
  • Linux Industrial I/O Subsystem
  • 《Linux Device Drivers Development》
本文只是一篇入门的文章,仍然有许多细节的知识点没有被描述到。如果本文能让你对 IIO 子系统有个大概的认识,那么本文的目的也就算达成了,以后还会继续写更多 IIO 子系统的文章。知识的学习应该是螺旋上升的,找到一条平缓的学习路线很重要,先有一个整体的概念,然后再不断地去丰富细节会比较好一点。就好像爬山一样,相对于几千米的高山,人类看起来总是显得多么的渺小,但是只要每天平稳地走几百个阶梯,再高的山也能在不知不觉中走完。

本文授权转载自公众号“嵌入式Hacker”,作者吴伟东Jack


-END-




推荐阅读



【01】数学对于编程来说重要吗?编程大佬现身说“线性代数”
【02】学不好后悔一辈子:刨根问底之链表数据结构
【03】精彩!由FPGA触发的芯片战争!
【04】12条CPU硬核干货!最全解释!
【05】史上最经典的“史密斯圆图”讲解

免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • 故障现象 一辆2024款路虎发现运动版车,搭载2.0 L发动机,累计行驶里程约为5 000 km。车主反映,使用遥控器无法解锁车门,随后使用机械钥匙打开车门,踩下制动踏板,按压起动按钮,仪表盘提示“将智能钥匙放在图示位置,然后按下起动按钮”(图1)。 图1 故障车的仪表盘提示采用上述应急起动方法,发动机能够起动着机。上述故障现象已出现过多次,过一段时间又会恢复正常,这次故障出现要求将车辆拖入店内进行彻底检修。 故障诊断 车辆进店后进行试车,车辆一切功能又恢复正常。经过反复测试
    虹科Pico汽车示波器 2025-03-20 10:17 29浏览
  •         在当今电子设备高度集成的时代,电路保护显得尤为重要。TVS管(瞬态电压抑制二极管)和压敏电阻作为一种高效的电路保护器件,被广泛应用于各种电子设备中,用以吸收突波,抑制瞬态过电压,从而保护后续电路免受损坏。而箝位电压,作为TVS管和压敏电阻的核心参数之一,直接关系到其保护性能的优劣。箝位电压的定义        箝位电压指瞬态保护器件(如TVS二极管、压敏电阻)在遭遇过压时,将电路电压限制在安全范围内的
    广电计量 2025-03-20 14:05 34浏览
  • 在电子制造领域,PCB(印刷电路板)的使用寿命直接决定了产品的长期稳定性和可靠性。捷多邦作为全球领先的PCB制造商,始终将质量放在首位,致力于为客户提供高可靠性、高性能的PCB解决方案。以下是捷多邦如何确保PCB使用寿命超过20年的核心技术与优势。 1. ​高品质原材料:从源头保障耐用性捷多邦采用国际认证的优质基材,如FR4、高频材料和高TG板材,确保PCB在高温、高湿等极端环境下的稳定性。通过严格的原材料筛选和入库检验,捷多邦从源头控制质量,避免因材料缺陷导致的失效问题。 
    捷多邦 2025-03-20 11:22 70浏览
  • 如同任何对我们工作方式的改变,新的工作方式必然会遇到许多必须面对的挑战。如果不解决组织在实施精益六西格玛过程中面临的障碍以及如何克服它们的问题,那么关于精益六西格玛的讨论就不算完整。以下列举了组织在成功实施精益六西格玛时常见的几个障碍,以及克服它们的方法:1)对精益六西格玛方法论缺乏理解。抵触情绪通常源于对精益六西格玛方法论的不了解,以及不相信它能真正发挥作用。这种情况在所有层级的人员中都会出现,包括管理层。虽然教育培训可以帮助改善这一问题,但成功的项目往往是打消疑虑的最佳方式。归根结底,这是一
    优思学院 2025-03-20 12:35 38浏览
  • 家电“以旧换新”政策的覆盖范围已从传统的八大类家电(冰箱、洗衣机、电视、空调、电脑、热水器、家用灶具、吸油烟机)扩展至各地根据本地特色和需求定制的“8+N”新品类。这一政策的补贴再叠加各大电商平台的优惠,家电销售规模显著增长,消费潜力得到进一步释放。晶尊微方案为升级换代的智能家电提供了高效且稳定的触摸感应和水位检测功能,使得操作更加便捷和可靠!主要体现在:水位检测1健康家电:养生壶、温奶器、加湿器的缺水保护安全2清洁电器:洗地机、扫地机器人的低液位和溢液提醒3宠物家电:宠物饮水机的缺水提醒/满水
    ICMAN 2025-03-20 15:23 48浏览
  • 本文内容来自微信公众号【工程师进阶笔记】,以工程师的第一视角分析了飞凌嵌入式OK3506J-S开发板的产品优势,感谢原作者温老师的专业分享。前两周,有一位老朋友联系我,他想找人开发一款数据采集器,用来采集工业现场的设备数据,并且可以根据不同的业务场景,通过不同的接口把这些数据分发出去。我把他提的需求总结了一下,这款产品方案大概有以下功能接口,妥妥地一款工业网关,在网上也能找到很多类似的产品方案,为啥他不直接买来用?再跟朋友深入地聊了一下,他之所以联系我,是因为看到我在公众号介绍过一款由飞凌嵌入式
    飞凌嵌入式 2025-03-20 11:51 46浏览
  • 在人工智能与物联网技术深度融合的今天,离线语音识别技术凭借其隐私安全、即时响应等优势,正在智能家居、工业控制等领域快速普及。广州唯创电子推出的WTK6900系列语音识别芯片,凭借其创新的离线命令词自学习功能,为用户提供了灵活高效的语音交互解决方案。本文将深入解析这一核心技术的工作原理及操作流程。一、智能自学习功能概述WTK6900系列芯片支持多模态学习方式,用户可通过物理按键、串口指令、语音命令或专用APP启动学习流程。其核心技术突破在于:全离线运行:所有学习过程均在本地完成,无需网络传输动态模
    广州唯创电子 2025-03-20 08:54 98浏览
  • 为有效降低人为疏失导致交通事故发生的发生率,各大汽车制造厂及系统厂近年来持续开发「先进驾驶辅助系统」ADAS, Advanced Driver Assistance Systems。在众多车辆安全辅助系统之中,「紧急刹车辅助系统」功能(AEB, Autonomous Emergency Braking)对于行车安全性的提升便有着相当大的帮助。AEB透过镜头影像模块与毫米波雷达感测前方目标,可在发生碰撞前警示或自动刹车以降低车辆损伤以及乘员伤害。面临的挑战以本次分享的客户个案为例,该车厂客户预计在
    百佳泰测试实验室 2025-03-20 15:07 45浏览
  • 流感季急诊室外彻夜排起的长队,手机屏幕里不断闪烁的重症数据,深夜此起彼伏的剧烈咳嗽声——当病毒以更狡猾的姿态席卷全球,守护健康的战争早已从医院前移到每个人的身上。在医学界公认的「72小时黄金预警期」里,可穿戴设备闪烁的光芒正穿透皮肤组织,持续捕捉血氧浓度、心率变异性和体温波动数据。这不是科幻电影的末日警报,而是光电传感器发出的生命预警,当体温监测精度精确到±0.0℃,当动态血氧检测突破运动伪影干扰……科技正在重新定义健康监护的时空边界。从智能手表到耳机,再到智能戒指和智能衣物,这些小巧的设备通过
    艾迈斯欧司朗 2025-03-20 15:45 49浏览
  • 近日,保定飞凌嵌入式技术有限公司(以下简称“飞凌嵌入式”)携手瑞芯微电子股份有限公司(以下简称“瑞芯微”)正式加入2025年全国大学生嵌入式芯片与系统设计竞赛(以下简称“嵌入式大赛”),并在应用赛道中设立专属赛题。本次嵌入式大赛,双方选用基于瑞芯微RK3588芯片设计的ELF 2开发板作为参赛平台,旨在通过此次合作,促进产教融合,共同推动嵌入式系统创新人才的培养。全国大学生嵌入式芯片与系统设计竞赛是一项A类电子设计竞赛,同时也是被教育部列入白名单的赛事,由中国电子学会主办,是学生保研、求职的公认
    飞凌嵌入式 2025-03-20 11:53 35浏览
  • PCIe 5.0应用环境逐步成形,潜在风险却蠢蠢欲动?随着人工智能、云端运算蓬勃发展,系统对于高速数据传输的需求不断上升,PCI Express(PCIe)成为服务器应用最广的传输技术,尤其在高效能运算HPC(High Performance Computing)及AI服务器几乎皆导入了最新的PCIe 5.0规格,使得数据传输的双向吞吐量达到了128GB/s,让这两类的服务器能够发挥最大的效能。不过随着PCIe 5.0的频率达到16GHz,PCB板因为高频而导致讯号衰减加剧的特性,使得厂商面临很
    百佳泰测试实验室 2025-03-20 13:47 32浏览
  • 全球领先的光学解决方案供应商艾迈斯欧司朗(SIX:AMS)近日宣布,凭借AS1163独立智能驱动器(SAID)成为中国领先的智能集成系统产品汽车制造商宁波福尔达智能科技股份有限公司(“福尔达”)环境动态照明应用的关键供应商。此次合作标志着汽车技术发展的一个重要时刻,充分展现了AS1163在优化动态照明应用系统成本方面的多功能性和先进性能。该产品支持传感器集成,拥有专为车顶照明设计的超薄外形,并能提升车内照明系统的性能。AS1163是一款先进的智能LED驱动器,能够与开放系统协议(OSP)网络无缝
    艾迈斯欧司朗 2025-03-20 14:26 33浏览
  • 4月8-11日,第91届中国国际医疗器械博览会(CMEF)将在国家会展中心(上海)举办。这场全球瞩目的医疗科技盛宴以“创新科技,智领未来”为主题,旨在全方位展示医疗科技的最新成果,与来自全球的行业同仁一道,为全球医疗健康领域带来一场科技与商贸交融的产业“盛宴”。飞凌嵌入式作为专业的嵌入式技术解决方案提供商,一直致力于为医疗器械行业提供丰富的、高可靠性的嵌入式硬件主控解决方案。届时,飞凌嵌入式将为来自全球的观众带来适用于IVD、医疗影像、生命体征监测等医疗设备的嵌入式板卡、显控一体屏产品以及多款动
    飞凌嵌入式 2025-03-20 11:46 24浏览
  • 贞光科技代理的品牌-光颉科技高精密薄膜电阻凭借0.01%的超高精度,在AI服务器电源模块中实现了精确电压分配、优化功率因数和减少热损耗,显著提升系统能效和可靠性。在当今的数字时代,人工智能(AI)服务器已成为数据中心的核心。随着AI应用的激增,服务器的性能和能效需求也在不断提高。电源模块作为服务器的关键组件,其性能直接影响整个系统的效率和可靠性。本文将探讨光颉科技高精密薄膜电阻,特别是其0.01%的精度,如何在AI服务器电源模块中提升能效。电源模块在AI服务器中的重要性电源模块负责将输入电源转换
    贞光科技 2025-03-20 16:55 40浏览
  • 随着自动驾驶技术的快速发展,仿真软件在开发过程中扮演着越来越重要的角色。仿真传感器与环境不仅能够加速算法验证,还能在安全可控的条件下进行复杂场景的重复测试。本文将分享如何利用自动驾驶仿真软件配置仿真传感器与搭建仿真环境,并对脚本进行修改,优化和验证4个鱼眼相机生成AVM(Around View Monitor)合成数据的流程。通过这一过程,一同深入体验仿真软件的应用潜力!一、流程概述AVM是一种通过多相机实现车辆周围环境的实时监控和显示的系统,广泛应用于自动驾驶和高级驾驶辅助系统(ADAS)的环
    康谋 2025-03-20 09:57 24浏览
我要评论
0
6
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦