当前位置:首页 > 公众号精选 > 嵌入式微处理器
[导读]前阵子工作上做了一些关于 ADC 的支持,由于现在 ADC 相关的支持都被移动到了 IIO (Industrial I/O) 子系统下,我查阅了一些关于 IIO 资料,包括书籍、文章、内核文档和代码。个人感觉最好的入门文章应该是 ST WiKi 网站上 的 IIO Overview(2019) 和 Analog



前阵子工作上做了一些关于 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】史上最经典的“史密斯圆图”讲解

免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭