OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3086|回复: 1

【干货】RT-Thread传感器设备驱动框架介绍

[复制链接]

55

主题

134

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2018-8-7
在线时间
55 小时
发表于 2019-2-28 18:09:59 | 显示全部楼层 |阅读模式
本帖最后由 Fillmore 于 2019-2-28 18:13 编辑

Sensor 是物联网重要的一部分,“Sensor 之于物联网”相当于“眼睛之于人类”。人没有眼睛就看不到这大千的花花世界,物联网没有了 Sensor 更是不能感知这变化万千的世界。
现在,为物联网开发的 Sensor 已经很多了,有加速度计(Accelerometer),磁力计(Magnetometer),陀螺仪(Gyroscope),光感计(Ambient light sensor),接近光(Proximity),气压计(Barometer/pressure),湿度计(Humidometer)等等。这些传感器,世界上的各大半导体厂商都有出产,虽然增加了市场的可选择性,同时也加大了应用程序开发的难度。因为不同的传感器厂商、不同的传感器都需要配套自己独有的驱动才能运转起来,这样在开发应用程序的时候就需要针对不同的传感器做适配,自然加大了开发难度。为了降低应用开发的难度,增加传感器驱动的可复用性,我们设计了 Sensor 驱动框架。
Sensor 驱动框架的作用是:为上层提供统一的操作接口,提高上层代码的可重用性;简化底层驱动开发的难度,只要实现简单的 ops(operations: 操作命令) 就可以将传感器注册到系统上。

整体框架
Sensor 驱动框架的整体架构图如下:
1.png
它为上层提供的是标准 device 接口open/close/read/write/control ,为底层驱动提供的是简单的 ops 接口:fetch_data/control。并且框架支持 module(模块),为底层存在耦合的传感器设备提供服务。
工作原理
Sensor 设备其实是对标准设备 rt_device 的一个丰富,是在原有标准设备的基础上增加了 Sensor 自己独有的一部分 属性 和 控制命令 ,如下图所示:
传感器图片.png
sensor
整个 Sensor 设备包括两个部分:
  • 继承自标准设备的一些特性,包括:标准的控制接口 、回调函数、device_id 等。
  • Sensor 设备独有的部分,包括:Sensor 的类型、相关的信息、特有的控制命令、ops、以及一些 数据的结构。

sensor 的结构体
Sensor 设备的结构体如下所示:
1struct rt_sensor_device
2{

3    struct rt_device             parent;    /* The standard device */
4
5    struct rt_sensor_info        info;      /* The sensor info data */
6    struct rt_sensor_config      config;    /* The sensor config data */
7
8    void                        *data_buf;  /* The buf of the data received */
9    rt_size_t                    data_len;  /* The size of the data received */
10
11    const struct rt_sensor_ops  *ops;       /* The sensor ops */
12
13    struct rt_sensor_module     *module;    /* The sensor module */
14};
15typedef struct rt_sensor_device *rt_sensor_t;
Sensor 的信息
struct rt_sensor_info info 里存储的是一些与 Sensor 自身相关的信息,在 Sensor 设备注册的时候提供,在使用的过程中不应修改其内容。具体成员如下所示。
1struct rt_sensor_info
2{

3    rt_uint8_t     type;                    /* The sensor type */
4    rt_uint8_t     vendor;                  /* Vendor of sensors */
5    const char    *model;                   /* model name of sensor */
6    rt_uint8_t     unit;                    /* unit of measurement */
7    rt_uint8_t     intf_type;               /* Communication interface type */
8    rt_int32_t     range_max;               /* maximum range of this sensor's value. unit is 'unit' */
9    rt_int32_t     range_min;               /* minimum range of this sensor's value. unit is 'unit' */
10    rt_uint32_t    period_min;              /* Minimum measurement period,unit:ms. zero = not a constant rate */
11    rt_uint8_t     fifo_max;                /* Maximum depth of fifo  */
12};
Sensor 的类型暂时只有以下几种,如果有新的传感器类型,可以提 PR 添加上。
1#define RT_SENSOR_CLASS_ACCE           (1)  /* Accelerometer     */
2#define RT_SENSOR_CLASS_GYRO           (2)  /* Gyroscope         */
3#define RT_SENSOR_CLASS_MAG            (3)  /* Magnetometer      */
4#define RT_SENSOR_CLASS_TEMP           (4)  /* Temperature       */
5#define RT_SENSOR_CLASS_HUMI           (5)  /* Relative Humidity */
6#define RT_SENSOR_CLASS_BARO           (6)  /* Barometer         */
7#define RT_SENSOR_CLASS_LIGHT          (7)  /* Ambient light     */
8#define RT_SENSOR_CLASS_PROXIMITY      (8)  /* Proximity         */
9#define RT_SENSOR_CLASS_HR             (9)  /* Heart Rate        */
10#define RT_SENSOR_CLASS_TVOC           (10) /* TVOC Level        */
11#define RT_SENSOR_CLASS_NOISE          (11) /* Noise Loudness    */
12#define RT_SENSOR_CLASS_STEP           (12) /* Step sensor       */
其他的几个成员,分别是厂商、model(如:"mpu6050")、传感器数据的单位、通信接口类型、测量的最大范围、测量的最小范围、最小测量周期、硬件 FIFO 的最大深度。
Sensor 的配置
Sensor 驱动框架抽象出了一些公共的配置选项,这些可配置的选项置于 struct rt_sensor_config 里, 成员如下:
1struct rt_sensor_config
2{

3    struct rt_sensor_intf        intf;      /* sensor interface config */
4    struct rt_device_pin_mode    irq_pin;   /* Interrupt pin, The purpose of this pin is to notification read data */
5    rt_uint8_t                   mode;      /* sensor work mode */
6    rt_uint8_t                   power;     /* sensor power mode */
7    rt_uint16_t                  odr;       /* sensor out data rate */
8    rt_int32_t                   range;     /* sensor range of measurement */
9};
这些配置项中的 intf 和 irq_pin 是为了将传感器和硬件解耦而抽象出来的,通过在底层初始化的时候传入 struct rt_sensor_config 这个参数,完成了通信接口的解耦。
1struct rt_sensor_intf
2{

3    char                       *dev_name;   /* The name of the communication device */
4    rt_uint8_t                  type;       /* Communication interface type */
5    void                       *user_data;  /* Private data for the sensor. ex. i2c addr,spi cs,control I/O */
6};
其余的一些配置项是用 Sensor 特有控制命令控制的,如下所示:
1#define  RT_SENSOR_CTRL_GET_ID         (0)  /* 读设备ID */
2#define  RT_SENSOR_CTRL_GET_INFO       (1)  /* 获取设备信息 */
3#define  RT_SENSOR_CTRL_SET_RANGE      (2)  /* 设置传感器测量范围 */
4#define  RT_SENSOR_CTRL_SET_ODR        (3)  /* 设置传感器数据输出速率,unit is HZ */
5#define  RT_SENSOR_CTRL_SET_MODE       (4)  /* 设置工作模式 */
6#define  RT_SENSOR_CTRL_SET_POWER      (5)  /* 设置电源模式 */
7#define  RT_SENSOR_CTRL_SELF_TEST      (6)  /* 自检 */
结合 ops 中的 control 接口使用,就可以完成传感器的配置了。
Sensor 数据的存储
为了方便数据的解析,规定每一个类型的 Sensor 都有自己独有的数据结构,这些成员之间使用共用体以减少代码量。
1/* 3-axis Data Type */
2struct sensor_3_axis
3{

4    rt_int32_t x;
5    rt_int32_t y;
6    rt_int32_t z;
7};
8struct rt_sensor_data
9{

10    rt_uint32_t         timestamp;          /* The timestamp when the data was received */
11    rt_uint8_t          type;               /* The sensor type of the data */
12    union
13    {
14        struct sensor_3_axis acce;          /* Accelerometer.       unit: mG          */
15        struct sensor_3_axis gyro;          /* Gyroscope.           unit: mdps        */
16        struct sensor_3_axis mag;           /* Magnetometer.        unit: mGauss      */
17        rt_int32_t           temp;          /* Temperature.         unit: dCelsius    */
18        rt_int32_t           humi;          /* Relative humidity.   unit: permillage  */
19        rt_int32_t           baro;          /* Pressure.            unit: pascal (Pa) */
20        rt_int32_t           light;         /* Light.               unit: lux         */
21        rt_int32_t           proximity;     /* Distance.            unit: centimeters */
22        rt_int32_t           hr;            /* Heat rate.           unit: HZ          */
23        rt_int32_t           tvoc;          /* TVOC.                unit: permillage  */
24        rt_int32_t           noise;         /* Noise Loudness.      unit: HZ          */
25        rt_uint32_t          step;          /* Step sensor.         unit: 1           */
26    } data;
27};
特有的 ops
ops(操作函数)包含两个函数指针, 一个的作用是获取传感器数据(fetch_data),另一个的作用是通过控制命令控制传感器(control)。
1struct rt_sensor_ops
2{

3    rt_size_t (*fetch_data)(struct rt_sensor_device *sensor, void *buf, rt_size_t len);
4    rt_err_t (*control)(struct rt_sensor_device *sensor, int cmd, void *arg);
5};
注册方式
传感器驱动框架提供了一个 Sensor 注册函数,通过传入 Sensor 的控制块,名称,标志位和私有数据,就可以完成传感器设备的注册。
1int rt_hw_sensor_register(rt_sensor_t sensor,
2                          const char              *name,
3                          rt_uint32_t              flag,
4                          void                    *data);
这样看来 Sensor 驱动框架依托于标准的设备框架,只要将传感器驱动对接到 Sensor 的 ops 上,并通过调用 rt_hw_sensor_register 函数注册为 Sensor 设备就可以通过标准的设备接口控制传感器了。
module支持
module 的定义是解决底层有耦合的两个传感器而出现的,有些传感器既有加速度计的功能又有陀螺仪的功能,并且他们的FIFO是共用的,在 FIFO 模式下,只能将两个类型的传感器的数据同时读出,这就说明他们的数据是耦合的。
为了解决这个问题,我们定义了 module 的类型
1struct rt_sensor_module
2{

3    rt_mutex_t            lock;                      /* The module lock */
4
5    rt_sensor_t           sen[RT_SENSOR_MODULE_MAX]; /* The module contains a list of sensors */
6    rt_uint8_t            sen_num;                   /* Number of sensors contained in the module */
7};
里面包含有耦合的传感器的设备控制块指针,通过这个功能就可以在读取陀螺仪的数据的时候,同时更新加速度计的值,解决了底层耦合的问题。


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

160

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2019-3-4
在线时间
4 小时
发表于 2019-4-1 12:07:43 | 显示全部楼层
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表