Linux IIO研究(二)

大家好!我是大聪明-PLUS

设备树

这里我要特别强调一下为节点设置标签的功能,如果您有许多类似的设备,此功能尤其适用。您可以随时在每个 iio:device 的 of_node 目录中查看节点中设置的当前值 - /sys/bus/iio/devices/iio\:device0/of_node/。

测量通道类型

许多以前作为独立实体存在的传感器已迁移到 IIO 基础架构,因此几乎任何测量类型都可以在 iio_chan_type 枚举中找到。详情可在此处找到: iio_event_monitor。

数据格式

IIO 可以向我们报告数据传输的格式iio-buffer-sysfs-interface。

复制代码
`[be|le]:[s|u]bits/storagebitsXrepeat[>>shift]`

icm20608 的实例:

复制代码
`# cat /sys/bus/iio/devices/iio\:device0/scan_elements/*_type
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
le:s64/64>>0`

到这里,一切都或多或少清楚了:

  • 首先是字节顺序 le 或 be,我们必须确保顺序与我们的体系结构或我们选择的字节顺序相匹配
  • 然后是类型 - 有符号或无符号,分别为 s 或 u
  • 然后是值的长度(以位为单位),/ 之后是包含该值的字段的长度,同样以位为单位,是字节位数的倍数
  • 最后要改变的是

也就是说,如果我们将两个四位值打包到同一个字段中,我们将看到以下内容:

复制代码
`be:u4/8>>0
be:u4/8>>4`

倒数第二个字段(在实际示例中未显示)是重复的 - 如果它大于 1,则会立即传输一个维度数组。

缩放和偏移

正如我之前所说,读取的原始数据必须转化为一般形式:

复制代码
`/sys/bus/iio/devices/iio:deviceX/in_*_raw
/sys/bus/iio/devices/iio:deviceX/in_*_offset
/sys/bus/iio/devices/iio:deviceX/in_*_scale`

一般来说,转换的形式为 (raw + offset)*scale;对于某些传感器类型,可能没有偏移。

如何使用sysfs接口进行简单的ADC转换

iio_simple_dummy

对于研究和测试,iio_simple_dummy可能很有用------它是一个内核模块,可以为以下通道模拟抽象的 IIO 设备:

  • IIO_电压
  • IIO_加速
  • IIO_ACTIVITY

iio_simple_dummy 结构

iio_simple_dummy

自由主义

如果您觉得上述内容很复杂, Analog Devices 的libiio可以为您提供帮助。

除了处理诸如整理频道格式或打开/关闭频道等日常事务之外。

它具有一个有趣的特性,即能够作为服务器/客户端工作,在这种情况下,带有传感器的设备充当数据服务器,而客户端可以位于 Linux、Windows 或 Mac 机器上,并通过 USB、以太网或串行连接。

连接到远程 iiod 节点:

在远程:

复制代码
`host # iiod`

在本地:

复制代码
`local $ iio_info -n [host_address]
local $ iio_attr -u ip:[host_address] -d
local $ iio_readdev -u ip:[host_address] -b 256 -s 0 icm20608`

不使用 libiio 进行工作

我不会涉及 sysfs 的平凡工作,因此一般来说,阅读时您需要执行以下操作:

  • 搜索设备,这里我们关注的是/sys/bus/iio/iio:deviceN/name,分别/sys/bus/iio/iio:deviceN会匹配/dev/iio:deviceN
  • 初始化 /sys/bus/iio/iio:deviceN/scan_elements/ 中的通道,我们将仅接收在 *_en 中订购的通道的测量值
  • 初始化缓冲区 /sys/bus/iio/iio:deviceN/enable

该示例显示了工作所需的最低限度。

结论

如果我们不想使用 libiio,就必须自己做。

计算每个通道偏移量的简单代码:

复制代码
`
    if (bytes % length == 0)
        offset = bytes;
    else
        offset = bytes - bytes % length + length;

    bytes = offset + length;`

在没有 libiio 的情况下以及相反的情况下,测量都必须达到其最终形式:

  • 使字节顺序与正在使用的字节顺序一致
  • 移至所需值
  • 切掉多余的
  • 如果是签名的,则执行符号扩展(Sign extension)
  • 如果有偏移,则在应用比例之前添加它
  • 如果有尺度,则应用尺度
复制代码
`    input = is_be ? betoh(input) : letoh(input);
    input >>= shift;
    input &= BIT_MASK(bits);
    value = is_signed ? (float)sext(input, bits) : (float)input;
    if(with_offset) value += offset;
    if(with_scale) value *= scale;`

注意:示例中显示的 Sign 扩展是最简单的、不可移植的版本。

使用 libiio

关于读取数据的替代机制的几句话

作为数据访问的替代方案,提出了一个原型,允许将数据从设备缓冲区直接移动到用户缓冲区,即所谓的零拷贝机制。

所有这些都与处理高速数据流的方法有关。

方法比较(演示文稿摘要):

解决方案一------区块

  • 将多个维度组合成一个块
  • 每个块生成一个中断
  • 降低管理成本
  • 块大小必须是可配置的
  • 允许用户应用程序在延迟和开销之间进行选择

解决方案二:DMA + mmap()

  • 使用 DMA 将数据从设备移动到专用内存块。
  • 使用 mmap() 从用户空间访问内存
  • 避免复制数据
  • 用户空间中的"免费"解复用

在我看来,这是 SDR 的一个绝佳解决方案。

从我与作者的通信中,我了解到此功能将包含在官方核心中,尽管不是当前的形式并且何时发布尚不清楚。

相关推荐
用户9718356334665 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪6 小时前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩1 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
古城小栈1 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
国产化创客1 天前
ESP32 CameraWebServer 原生摄像头项目全解析
物联网·开源·嵌入式·实时音视频·智能硬件
凡人叶枫1 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
2601_961875241 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant