最佳入门教程!嵌入式必会的Linux驱动开发之IIO子系统
扫描二维码
随时随地手机看文章
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 概述
ADC / DAC
加速度计
磁力计
陀螺仪
压力传感器
湿度传感器
温度传感器
...
1.2 IIO 相关的组件
char device, sysfs, configfs, debugfs。
include/linux/iio/consumer.h
IIO 子系统的核心实现。
2. IIO 的功能特性
-
Linux-4.14/drivers/staging/iio/Documentation/overview.txt
-
类似于 hwmon 子系统,它们都可以通过 sysfs 以轮循的方式访问设备;
-
类似于 input 子系统,iio 子系统也可以向应用层上报事件(hardware triggered events),例如阈值检测事件,自由落体检测事件、更复杂的动作检测事件;
-
目前 event 的格式为:event code + 时间戳;
3. IIO 相关配置
3.1 配置内核
$ 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 --->
3.2 配置设备树
-
Linux-4.14/Documentation/devicetree/bindings/iio/iio-bindings.txt
3.2.1 IIO providers
-
IIO channels 源在设备树中用 IIO providers 来指定;
-
io-channel-cells,0 表示只有 1 路 IIO output,1 表示有多路 IIO output;
-
io-channel-ranges: 一个 empty 属性(即不用赋值),会在 driver/iio/inkern.c/iio_channel_get() 中被引用,它表明继承了当前节点的子节点可以引用当前节点的 IIO channel;
adc: voltage-sensor@ 35 {
compatible = "maxim,max1139";
reg = < 0x35>;
#io-channel-cells = <1>;
};
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
-
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 属性决定;
-
io-channels: <phandle iio_specifier> 列表, 一个 <phandle iio_specifier> 代表该设备连接着的一路 IIO input。如果 IIO provider 的 io-channel-cells=0 (即只有1路 IIO output), 则省略 iio_specifier。
-
io-channel-names: IIO input 的名称列表,顺序要和 io-channels 属性保持一致,Consumers drivers 会将该名称和 iio_specifier 指定的 IIO input match 到一起。
some_consumer {
io-channels = <&adc 1>, <&ref 0>;
io-channel-names = "vcc", "vdd";
};
4. IIO API
4.1 用户空间 API
-
IIO user space interface -
How to use the IIO user space interface
4.1.1 4种接口
-
/sys/bus/iio/devices/iio:deviceX;
-
可用于配置 /dev/iio:deviceX 接口的 events / data
-
可用于轮循的方式低速地直接读/写 IIO 设备;
-
Documentation/ABI/testing/sysfs-bus-iio;
-
/dev/iio:deviceX,该接口在 IIO 子系统里是可选非必要的;
-
标准的文件 IO API: open(), read(), write(), close().
-
用于读取 events 和 data;
-
用于配置额外的 IIO 特性,例如:软件 triggers 或者 hrtimer triggers;
-
详细说明:
-
Documentation/ABI/testing/configfs-iio; -
Documentation/iio/iio_configfs.txt;
-
一些调试功能,例如 direct_reg_access 节点可用于读写寄存器;
4.1.2 操作实例
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
$ 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
确定 sysfs 节点(方式2)
$ lsiio | grep dac
Device 003: 40017000.dac:dac@ 1
Device 004: 40017000.dac:dac@ 2
$ 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》
本文授权转载自公众号“嵌入式Hacker”,作者吴伟东Jack
-END-
推荐阅读
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!