NXP i.MX8系列平台开发讲解 - 3.4 Linux 之IIO子系统(sensor opt3001)

 专栏文章目录传送门返回专栏目录


目录

1. Linux IIO子系统介绍

2. Linux IIO子系统框架

3. IIO 子系统的实现


本文实操是基于Android11 系统下i.MX8MQ环境下:

  • cpu: i.mx8mq

  • OS:Android 11

  • Kernel version:kernel 5.10

Linux IIO(Industrial I/O)子系统是Linux内核中的一个子系统,用于处理与工业领域相关的数据输入和输出设备。它支持各种传感器和数据采集设备,如加速度计、陀螺仪、温度传感器等。IIO子系统提供了统一的接口和框架,允许用户空间应用程序通过sysfs和设备文件来访问和配置这些传感器数据。这使得开发者可以方便地采集和处理来自各种传感器的数据,并实现更复杂的应用和算法。

1. Linux IIO子系统介绍

Linux IIO子系统是为了工业输入输出所涉及的子系统,主要用于ADC或者DAC或者两者都有的设备提供的一种设备驱动的支持。主要很好规范各种不同设备具有统一接口提供给开发人员使用的。在目前使用各种传感器大多都是ADC的,有通过IIC,SPI等接口进行获取数据或者配置,种类非常繁多,有IIO子系统就很好对这些传感器进行使用起来。

目前IIO常见的管理的设备:

  • 加速度计:用于测量加速度和倾斜,广泛应用于工业自动化、移动设备和汽车领域等。

  • 陀螺仪:用于测量角速度和转动,常见于飞行器、导航系统和姿态控制应用。

  • 温度传感器:用于测量环境温度,广泛应用于气象、环境监测和智能家居等。

  • 压力传感器:用于测量气体或液体压力,常见于气象观测、工业自动化和医疗设备。

  • 光传感器:用于测量环境光照强度,广泛应用于显示器自动调光和照明控制等。

  • 湿度传感器:用于测量空气湿度,常见于气象、农业和温室应用。

  • ....

以上这些常用的传感器设备一般通过IIC/SPI总线接入到Linux中,在Linux可以看到IIO设备,然后在应用上进行操作。

2. Linux IIO子系统框架

图片

从IIO系统框架来看,从底部网上查看

Bus Drivers: 这是一种特殊类型驱动程序,负责管理和处理与传感器相关的总线通信,主要是作为与传感器进行数据交互,包括数据的配置与数据传输。IIO 支持多种不同总线类型,比如SPI/I2C/UART等等;

Device Driver: 这里指的是特定的传感器或者数据采集设备的驱动程序,每个设备都需要响应的Device Driver与IIO进行交互,实现数据采集控制;

IIO Subsystem:包含iio_ring/iio_core/iio_trigger等这些属于IIO Framwrok部分,iio_ring相当于连续采集的数据缓存buffer,iio_ring将提供字符设备文件的注册,所以在应用上可以通过字符设备读取该设备的数据;iio_core主要实现iio device的创建,iio_trigger是一种触发,当收到该触发后将数据放入buffer。

3. IIO 子系统的实现

iio 目录结构

.
├── accel
├── adc
├── afe
├── amplifiers
├── buffer
├── built-in.a
├── chemical
├── common
├── dac
├── dummy
├── frequency
├── gyro
├── health
├── humidity
├── iio_core.h
├── iio_core_trigger.h
├── imu
├── industrialio-buffer.c
├── industrialio-buffer.o
├── industrialio-configfs.c
├── industrialio-core.c
├── industrialio-core.o
├── industrialio-event.c
├── industrialio-event.o
├── industrialio-sw-device.c
├── industrialio-sw-trigger.c
├── industrialio-trigger.c
├── industrialio-triggered-event.c
├── industrialio-trigger.o
├── inkern.c
├── inkern.o
├── Kconfig
├── light
├── magnetometer
├── Makefile
├── modules.order
├── multiplexer
├── orientation
├── position
├── potentiometer
├── potentiostat
├── pressure
├── proximity
├── resolver
├── temperature
├── TODO
└── trigger

从目录结构来看,可以明显看到具体相关类的传感器,加速度传感器accel, 模数转换器adc, 温度传感器addac,还有其他就不再一一讲述。

主要实现函数

ls ./drivers/iio/industrialio-*.c
./drivers/iio/industrialio-buffer.c
./drivers/iio/industrialio-core.c  
./drivers/iio/industrialio-sw-device.c  
./drivers/iio/industrialio-trigger.c
./drivers/iio/industrialio-configfs.c 
./drivers/iio/industrialio-event.c 
./drivers/iio/industrialio-sw-trigger.c  
./drivers/iio/industrialio-triggered-event.c

这几个函数文件都是围绕iio_dev/ iio_info/ 还有iio_buffer, iio_trigger的功能实现,具体的调用可以看到下图相关的关系。

所有的可以通过IIO子系统实现的传感器都是在./drivers/iio/,如果是没有该驱动可以根据相近的驱动进行修改添加。

这里以光强传感器opt3001来说明;

opt3001的驱动文件,从probe入手:

static int opt3001_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
{
        struct device *dev = &client->dev;
​
        struct iio_dev *iio;
        struct opt3001 *opt;
        int irq = client->irq;
        int ret;
​
        iio = devm_iio_device_alloc(dev, sizeof(*opt));
        if (!iio)
                return -ENOMEM;
​
        opt = iio_priv(iio);
        opt->client = client;
        opt->dev = dev;
​
        mutex_init(&opt->lock);
        init_waitqueue_head(&opt->result_ready_queue);
        i2c_set_clientdata(client, iio);
        //通过I2C读取设备ID是存在
        ret = opt3001_read_id(opt);
        if (ret)
                return ret;
        //写寄存器配置opt3001
        ret = opt3001_configure(opt);
        if (ret)
                return ret;
        //填充iio_dev 结构体,将opt->info 具体操作实现,
        iio->name = client->name;
        iio->channels = opt3001_channels;
        iio->num_channels = ARRAY_SIZE(opt3001_channels);
        iio->modes = INDIO_DIRECT_MODE;
        iio->info = &opt3001_info;
        //注册一个iio设备        
        ret = devm_iio_device_register(dev, iio);
        if (ret) {
                dev_err(dev, "failed to register IIO device\n");
                return ret;
        }
​
        /* Make use of INT pin only if valid IRQ no. is given */
        if (irq > 0) {
                //配置中断
                ret = request_threaded_irq(irq, NULL, opt3001_irq,
                                IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                "opt3001", iio);
                if (ret) {
                        dev_err(dev, "failed to request IRQ #%d\n", irq);
                        return ret;
                }
                opt->use_irq = true;
        } else {
                dev_dbg(opt->dev, "enabling interrupt-less operation\n");
        }
​
        return 0;
}

从OPT3001probe来看主要是设置了通信接口I2C,初始化设备,并注册iio_dev设备,这样就和iio联系起来。

通道的设置:iio->channels

static const struct iio_chan_spec opt3001_channels[] = {
        {
                .type = IIO_LIGHT,
                .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
                                BIT(IIO_CHAN_INFO_INT_TIME),
                .event_spec = opt3001_event_spec,
                .num_event_specs = ARRAY_SIZE(opt3001_event_spec),
        },
        IIO_CHAN_SOFT_TIMESTAMP(1),
};
​

每个传感器可以有一个或多个通道,每个通道用于描述传感器输出的一种类型的数据。在这里对于光照传感器来说,只有一个通道去描述光照强度数据就狗了。但是对于其他一些比如加速度计就存在多个通道。这个描述通道作用是在IIO框架交互能够以标准化交互。

iio_info部分

static const struct iio_info opt3001_info = {
        .attrs = &opt3001_attribute_group, //提供个sysfs使用
        .read_raw = opt3001_read_raw, //读取传感器数据
        .write_raw = opt3001_write_raw, //配置
        .read_event_value = opt3001_read_event_value, //读取一个事件,比如对opt3001设定了一个阈值,如果超过 就会产生一个事件
        .write_event_value = opt3001_write_event_value,//设置一个事件,比如阈值
        .read_event_config = opt3001_read_event_config,//读取事件配置
        .write_event_config = opt3001_write_event_config,//设置事件配置
};

从结构体来说基本就已经定义了该传感器的功能与接口,这样使得在IIO层就可以去实现数据的采集配置和时间的处理等功能。

实际效果查看

图片

cat in_illuminance_input就可以看到当前的光强强度。

  • 55
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 全志Linux IIO(Industrial I/O)是全志科技公司为其系统-on-chip(SoC)芯片设计的一个功能丰富的子系统。它提供了一套用于处理从各种传感器设备读取和控制数据的框架和驱动程序。 IIO子系统的主要目的是使Linux系统能够与各种传感器进行交互。这些传感器可以是温度传感器、光传感器、加速度计、罗盘、湿度传感器等。IIO框架为传感器的数据读取、数据转换(如ADC和DAC)、数据传输和保存等提供了一致性接口和库。 全志的Linux IIO提供了一套强大和丰富的驱动程序集合,以支持其在不同SoC芯片上集成的各种传感器和输入/输出设备。这些驱动程序集合可以用于从这些传感器读取数据,控制设备参数和提供高性能数据流。 尽管全志的Linux IIO是为全志公司的特定芯片设计的,但它也兼容其他Linux平台,并且可以在其他SoC芯片上使用。这使得开发人员能够简化传感器驱动开发和移植,从而更快地将其应用于不同的嵌入式系统项目。 总之,全志Linux IIO是一个重要的子系统,使得开发人员能够轻松地与各种传感器设备进行通信和控制。它为传感器数据读取和设备参数控制提供了一个统一且可靠的接口,同时也为传感器驱动程序的开发和移植提供了便利。 ### 回答2: 全志Linux IIO是处理器芯片制造商全志科技公司发布的一套用于Linux系统的传感器支持框架。IIO全称为Industrial Input/Output子系统,是Linux内核的一个功能子系统,用于处理与外部硬件设备的数据输入和输出。 全志Linux IIO主要用于支持嵌入式系统中的传感器设备,如加速度计、陀螺仪、光学传感器等,以及一些特殊的外设设备,如电压电流传感器等。通过全志Linux IIO开发者可以很方便地将各种传感器设备连接到嵌入式系统中,并实现数据的输入和输出。 使用全志Linux IIO开发者可以通过一系列的API函数来配置和控制传感器设备。这些API函数包括设备的初始化、传感器数据的采集、设备的校准、数据的处理和传输等。全志Linux IIO提供了一套统一的接口,使得开发者可以方便地操作各种不同类型的传感器设备。 全志Linux IIO的优势在于其兼容性和灵活性。它可以运行在多种不同的处理器架构上,并且支持多种不同的传感器设备。开发者可以根据具体需求选择合适的传感器设备,并根据自己的需求调整和配置设备参数。 总之,全志Linux IIO是一套用于Linux系统的传感器支持框架,它使得开发者可以方便地接入和控制各种传感器设备,实现数据的采集和处理。它的灵活性和兼容性使得开发者可以根据具体需求选择合适的传感器设备,并进行相应的配置和控制。 ### 回答3: 全志Linux IIO是全志科技开发的一种用于嵌入式系统的开源软件平台IIO代表了"Industry Input/Output",指的是从不同的物理量传感器(包括温度、压力、湿度等)获取数据,并将其传输到嵌入式系统中。 全志Linux IIO遵循Linux内核的架构,并提供一系列驱动程序和库,使得开发者能够轻松地与各种传感器进行通信。它提供了一个统一的接口,使得开发者可以使用相同的API来读取多个不同类型的传感器的数据。这种模块化的设计让开发者能够快速添加、更新或替换传感器,且不需要对底层软件进行太多修改。 通过使用全志Linux IIO,嵌入式系统可以方便地监测和控制各种物理量,并将其应用于各种领域,例如工业自动化、智能家居、物联网等。开发者可以通过编写简单的程序来获取传感器数据,并根据需要进行进一步处理和分析。 此外,全志Linux IIO还支持一些高级功能,例如采样率控制、数据滤波和事件触发等。这些功能可以帮助开发者优化系统性能,并提高传感器数据的准确性和可靠性。 总而言之,全志Linux IIO是一个强大的开源软件平台,为开发者提供了丰富的工具和接口,使他们能够轻松地与各种传感器进行集成和交互。它为嵌入式系统的开发和应用带来了便利和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值