一文带你深入了解Linux IIO 子系统

news2024/11/26 10:43:27

【推荐阅读】

一文剖析Linux内核中内存管理

分析linux启动内核源码

关于如何快速学好,学懂Linux内核。内含学习路线

工业场合里面也有大量的模拟量和数字量之间的转换,也就是我们常说的 ADC 和 DAC。而且随着手机、物联网、工业物联网和可穿戴设备的爆发,传感器的需求只持续增强。比如手机或者手环里面的加速度计、光传感器、陀螺仪、气压计、磁力计等,这些传感器本质上都是ADC,大家注意查看这些传感器的手册,会发现他们内部都会有个 ADC,传感器对外提供 IIC或者 SPI 接口,SOC 可以通过 IIC 或者 SPI 接口来获取到传感器内部的 ADC 数值,从而得到想要测量的结果。Linux 内核为了管理这些日益增多的 ADC 类传感器,特地推出了 IIO 子系统,我们学习如何使用 IIO 子系统来编写 ADC 类传感器驱动。

1、IIO 子系统简介

IIO 全称是 Industrial I/O,翻译过来就是工业 I/O大家不要看到“工业”两个字就觉得 IIO 是只用于工业领域的。大家一般在搜索 IIO 子系统的时候,会发现大多数讲的都是 ADC,这是因为 IIO 就是为 ADC 类传感器准备的,当然了 DAC 也是可以的。大家常用的陀螺仪、加速度计、电压/电流测量芯片、光照传感器、压力传感器等内部都是有个 ADC,内部 ADC 将原始的模拟数据转换为数字量,然后通过其他的通信接口,比如 IIC、SPI 等传输给 SOC。

因此,当你使用的传感器本质是 ADC 或 DAC 器件的时候,可以优先考虑使用 IIO 驱动框架。

1、iio_dev 结构体

IIO 子系统使用结构体 iio_dev 来描述一个具体 IIO 设备,此设备结构体定义在include/linux/iio/iio.h 文件中

2、iio_dev 申请与释放

在使用之前要先申请 iio_dev,申请函数为 iio_device_alloc,函数原型如下:

struct iio_dev *iio_device_alloc(int sizeof_priv)

sizeof_priv:私有数据内存空间大小,一般我们会将自己定义的设备结构体变量作为 iio_dev 的私有数据,这样可以直接通过 iio_device_alloc 函数同时完成 iio_dev 和设备结构体变量的内存申请。申请成功以后使用 iio_priv 函数来得到自定义的设备结构体变量首地址。

返回值:如果申请成功就返回 iio_dev 首地址,如果失败就返回 NULL。

3、iio_dev 注册与注销

前面分配好 iio_dev 以后就要初始化各种成员变量,初始化完成以后就需要将 iio_dev 注册 到内核中,需要用到 iio_device_register 函数

4、iio_info

iio_dev 有个成员变量:info,为 iio_info 结构体指针变量,这个是我们在编写 IIO 驱动的时候需要着重去实现的,因为用户空间对设备的具体操作最终都会反映到 iio_info 里面。iio_info结构体定义在 include/linux/iio/iio.h 中

5、iio_chan_spec

IIO 的核心就是通道,一个传感器可能有多路数据,比如一个 ADC 芯片支持 8 路采集,那么这个 ADC 就有 8 个通道。Linux 内核使用 iio_chan_spec 结构体来描述通道,定义在 include/linux/iio/iio.h 文件中。

2、IIO 驱动框架创建

分析 IIO 子系统的时候大家应该看出了,IIO 框架主要用于 ADC 类的传感器,比如陀螺仪、加速度计、磁力计、光强度计等,这些传感器基本都是 IIC 或者 SPI 接口的。因此 IIO 驱动的基础框架就是 IIC 或者 SPI,我们可以在 IIC 或 SPI 驱动里面在加上 regmap。当然了,有些 SOC 内部的 ADC 也会使用 IIO 框架,那么这个时候驱动的基础框架就是 platfrom。

IIO 设备的申请、初始化以及注册在 probe 函数中完成,在注销驱动的时候还需要在 remove 函数中注销掉 IIO 设备、释放掉申请的一些内存。

以 SPI 接口为例,demo 如下

/* 自定义设备结构体 */
struct xxx_dev { 
 struct spi_device *spi; /* spi 设备 */
 struct regmap *regmap; /* regmap */
 struct regmap_config regmap_config;
 struct mutex lock;
};

/*
* 通道数组
*/
static const struct iio_chan_spec xxx_channels[] = {

};

/*
* @description : 读函数,当读取 sysfs 中的文件的时候最终此函数会执行,
* :此函数里面会从传感器里面读取各种数据,然后上传给应用。
* @param - indio_dev : IIO 设备
* @param - chan : 通道
* @param - val : 读取的值,如果是小数值的话,val 是整数部分。
* @param - val2 : 读取的值,如果是小数值的话,val2 是小数部分。
* @param - mask : 掩码。
* @return : 0,成功;其他值,错误
*/
static int xxx_read_raw(struct iio_dev *indio_dev,
   struct iio_chan_spec const *chan,
   int *val, int *val2, long mask)
{
 return 0;
} 

/*
* @description : 写函数,当向 sysfs 中的文件写数据的时候最终此函数
* :会执行,一般在此函数里面设置传感器,比如量程等。
* @param - indio_dev : IIO 设备
* @param - chan : 通道
* @param - val : 应用程序写入值,如果是小数的话,val 是整数部分。
* @param - val2 : 应用程序写入值,如果是小数的话,val2 是小数部分。
* @return : 0,成功;其他值,错误
*/
static int xxx_write_raw(struct iio_dev *indio_dev,
   struct iio_chan_spec const *chan,
   int val, int val2, long mask)
{
 return 0;
}

/*
* @description : 用户空间写数据格式,比如我们在用户空间操作 sysfs 来设
* :置传感器的分辨率,如果分辨率带小数,那么这个小数传递到
* : 内核空间应该扩大多少倍,此函数就是用来设置这个的。
* @param - indio_dev : iio_dev
* @param - chan : 通道
* @param - mask : 掩码
* @return : 0,成功;其他值,错误
*/
static int xxx_write_raw_get_fmt(struct iio_dev *indio_dev,
   struct iio_chan_spec const *chan, long mask)
{
 return 0;
}

/*
* iio_info 结构体变量
*/
static const struct iio_info xxx_info = {
  .read_raw = xxx_read_raw,
  .write_raw = xxx_write_raw,
  .write_raw_get_fmt = &xxx_write_raw_get_fmt,
};

/*
* @description : spi 驱动的 probe 函数,当驱动与
* 设备匹配以后此函数就会执行
* @param - spi : spi 设备
* 
*/ 
static int xxx_probe(struct spi_device *spi)
{
  int ret;
  struct xxx_dev *data;
  struct iio_dev *indio_dev;

  /* 1、申请 iio_dev 内存 */
  indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
  if (!indio_dev)
  return -ENOMEM;

  /* 2、获取 xxx_dev 结构体地址 */
  data = iio_priv(indio_dev);
  data->spi = spi;
  spi_set_drvdata(spi, indio_dev);
  mutex_init(&data->lock);

  /* 3、初始化 iio_dev 成员变量 */
  indio_dev->dev.parent = &spi->dev;
  indio_dev->info = &xxx_info;
  indio_dev->name = "xxx";
  indio_dev->modes = INDIO_DIRECT_MODE; /* 直接模式 /
  indio_dev->channels = xxx_channels;
  indio_dev->num_channels = ARRAY_SIZE(xxx_channels);

  iio_device_register(indio_dev);

  /* 4、regmap 相关设置 */

  /* 5、SPI 相关设置*/

  /* 6、芯片初始化 */

  return 0;

}

/*
* @description : spi 驱动的 remove 函数,移除 spi 驱动的时候此函数会执行
* @param - spi : spi 设备
* @return : 0,成功;其他负值,失败
*/
static int xxx_remove(struct spi_device *spi)
{
  struct iio_dev *indio_dev = spi_get_drvdata(spi);
  struct xxx_dev *data;

  data = iio_priv(indio_dev); ;

  /* 1、其他资源的注销以及释放 */

  /* 2、注销 IIO */
  iio_device_unregister(indio_dev);

  return 0;
}

3、使能内核 IIO 相关配置

Linux 内核默认使能了 IIO 子系统,但是有一些 IIO 模块没有选择上,这样会导致我们编译 驱动的时候会提示某些 API 函数不存在,需要使能的项目如下:

-> Device Drivers 
   -> Industrial I/O support (IIO [=y])
       -> [*]Enable buffer support within IIO //选中
       -> <*>Industrial I/O buffering based on kfifo //选中

IIO 驱动框架提供了 sysfs 接口,因此加载成功以后我们可以在用户空间访问对应的 sysfs 目录项,进入目录“/sys/bus/iio/devices/”目录里面,此目录下都是 IIO 框架设备。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48262.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[第二十二篇]——Docker 安装 MongoDB

Docker 安装 MongoDB MongoDB 是一个免费的开源跨平台面向文档的 NoSQL 数据库程序。 1、查看可用的 MongoDB 版本 访问 MongoDB 镜像库地址&#xff1a; 。 可以通过 Sort by 查看其他版本的 MongoDB&#xff0c;默认是最新版本 mongo:latest。 你也可以在下拉列表中找到…

高校社团管理系统的设计与实现

摘要 随着互联网技术的高速发展&#xff0c;人们生活的各方面都受到互联网技术的影响。现在的社团成员可以通过互联网技术就能实现不在学校&#xff0c;在家也可以查看社团信息并能进行申请加入&#xff0c;简单、快捷的方便了社团成员的社交生活。同样的&#xff0c;在人们的工…

【Spring项目中的统一处理异常】

目录 1. 统一处理异常的机制 2. 关于统一处理异常的方法 3. 关于处理异常的方法的执行特点 1. 统一处理异常的机制 Spring MVC框架提供了统一处理异常的机制&#xff01;表现为每种类型的异常只需要写一段&#xff08;写一次&#xff09;处理此异常的代码即可&#xff0c;项…

需求:针对同一个表格多次导入是否要做判断(此项目是用得若依)

每次上传表时&#xff0c;将上传的表名与以往上传的表名做对比&#xff0c;如果相同&#xff0c;则提示表已经有记录&#xff0c;是否上传相同表并结束此方法。 实现思路&#xff1a; 首先&#xff0c;每次上传表都要把表明记录一下&#xff0c;可以新建一个表&#xff08;数…

天宇优配|离岸人民币狂拉逾千点!中概股暴涨!B站涨22%

当地时间周二&#xff0c;美股三大指数收盘涨跌纷歧。道指涨0.01%&#xff0c;标普500指数跌0.16%&#xff0c;纳指跌0.59%。 抢手中概股领涨&#xff0c;纳斯达克我国金龙指数大涨5.04%&#xff0c;哔哩哔哩&#xff08;B站&#xff09;涨超22%。大型科技股多数跌落&#xff0…

小程序中的confirm-type设置键盘的确认按钮

详情&#xff1a; confirm-type是很多小程序组件中的一种设置&#xff0c;用于改变输入键盘右下角的确认按钮。比如说&#xff0c;正常情况下&#xff0c;键盘上的默认提示可能是完成&#xff0c;但是你可以通过confirm-type将其设置为发送&#xff0c;搜索等&#xff0c;在特…

间隔不到一年开两店,温州鸿雁全屋智能经销商透露了他的生意经

作者 | 牧之 编辑 | 小沐 出品 | 智哪儿 zhinaer.cn编者按&#xff1a;间隔不到一年&#xff0c;连续开设了两家全屋智能体验店。这是发生在温州的渠道商故事。本期专访&#xff0c;「智哪儿」对话浙江林上智能科技有限公司总经理朱飞隆先生。他为何做智能家居&#xff1f;为何…

翻转单词序列、按之字形顺序打印二叉树、二叉搜索树的第k个节点

1、翻转单词序列 本题考点&#xff1a;子串划分&#xff0c;子串逆置 牛客链接 题目描述&#xff1a; 牛客最近来了一个新员工Fish&#xff0c;每天早晨总是会拿着一本英文杂志&#xff0c;写些句子在本子上。同事Cat对Fish写的内容颇感兴趣&#xff0c;有一天他向Fish借来翻…

Python数据库编程之关系数据库API规范

Python关系数据库API规范 对于关系数据库的访问&#xff0c;Python社区已经制定出一个标准&#xff0c;称为Python Database API Specification。Mysql&#xff0c;Oracal等特定数据库模块遵从这一规范&#xff0c;而且可以添加更多特性。 高级数据库API定义了一组用于连接数…

三十六、Java 泛型

Java 泛型 Java 泛型&#xff08;generics&#xff09;是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型&#xff0c;也就是说所操作的数据类型被指定为一个参数。 假定我们有这…

火山引擎 DataLeap 的 Data Catalog 系统公有云实践

Data Catalog 通过汇总技术和业务元数据&#xff0c;解决大数据生产者组织梳理数据、数据消费者找数和理解数的业务场景。本篇内容源自于火山引擎大数据研发治理套件 DataLeap 中的 Data Catalog 功能模块的实践&#xff0c;主要介绍 Data Catalog 在公有云部署和发布中遇到挑战…

5. LSTM的C++实现

[C 基于Eigen库实现CRN前向推理] 第三部分&#xff1a;TransposedConv2d实现 &#xff08;含dilation&#xff09; 前言&#xff1a;(Eigen库使用记录)第一部分&#xff1a;WavFile.class (实现读取wav/pcm,实现STFT)第二部分&#xff1a;Conv2d实现第三部分&#xff1a;Tran…

你知道不同U盘在ARM+Linux下的读写速率吗?

优秀的产品离不开完善的测试&#xff0c;即使一个简单的USB接口也要确保稳定性及兼容性。不同的U盘在ARMLinux板卡下的兼容性、速率怎么样呢&#xff1f;本文将为大家提供测试参考数据及详细测试步骤&#xff01; 1. 测试准备 主控选用最近发布的64位Cortex-A55核心板&#xff…

设计模式-day01

1&#xff0c;设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大&#xff08;Christopher Alexand…

深入理解SR-IOV和IO虚拟化

一、背景 SR-IOV&#xff08;Single Root I/O Virtualization&#xff09;是由PCI-SIG组织定义的PCIe规范的扩展规范《Single Root I/O Virtualization and Sharing Specification》&#xff0c;目的是通过提供一种标准规范&#xff0c;为VM&#xff08;虚拟机&#xff09;提供…

springboot+vue职称评审管理系统

开发语言&#xff1a;Java 框架&#xff1a;Springbootssm(SpringSpringMVCMyBatis) JDK版本&#xff1a;JDK1.8 前端框架&#xff1a;vue.js 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/idea都支持 Mave…

前端页面的性能测试

介绍 随着 Web 应用的空前发展&#xff0c;前端业务逐渐复杂&#xff0c;为了处理这些复杂业务&#xff0c;前后端分离&#xff0c;出现了专门应对这种分离架构的应用开发框架&#xff0c;比如 Angular&#xff0c;React&#xff0c;Vue 等&#xff0c;从而也导致 Web 应用的复…

高效率开发Web安全扫描器之路(一)

一、背景 经常看到一些SRC和CNVD上厉害的大佬提交了很多的漏洞&#xff0c;一直好奇它们怎么能挖到这么多漏洞&#xff0c;开始还以为它们不上班除了睡觉就挖漏洞&#xff0c;后来有机会认识了一些大佬&#xff0c;发现它们大部分漏洞其实是通过工具挖掘的&#xff0c;比如说下…

linux服务器监控性能测试

一、服务器实时内存监控 1、top&#xff1a;能够实时监控系统的运行状态&#xff0c;并且可以按照cpu以及内存等进行排序。 输入&#xff1a;top -help就可以出现下面的例子&#xff1a; 命令例子&#xff1a;top -hv | -bcHiOSs -d secs -n max -u|U user -p pid(s) -o fiel…

计算机网络——分层结构,协议接口,服务

分层结构 主机进行资源共享时需满足以下条件&#xff1a; &#xff08;1&#xff09;发起通信的计算机要将数据通路进行激活 &#xff08;2&#xff09;告诉网络如何识别主机 &#xff08;3&#xff09;发起通信的主机要查明目的主机是否开机等 &#xff08;4&#xff09;发起…