TuyaOS Sensor Hub组件介绍

news2024/10/1 7:36:02

文章目录

    • Sensor Hub 设计思想
      • 分层设计
        • Sensor Hub 层(tdl)
        • Sensor Driver 层(tdd)
      • 传感数据元素类型抽象
      • 传感器采集策略
    • Sensor Hub 对上数据与接口
      • 数据结构
        • 1. 数据读取的触发模式
        • 2. 元素型数据订阅规则
        • 3. 数据就绪通知回调
        • 4. 传感设备信息
      • 应用接口
        • 1. 创建传感器实例
        • 2. 启动传感器
        • 3. 停止传感器
        • 4. 配置传感器参数
        • 5. 读取传感器实时数据
    • Sensor Hub 对下数据与接口
      • 数据结构
      • 驱动接口抽象
      • 驱动注册接口
    • 驱动开发流程
    • Sensor Hub使用流程

Sensor Hub 是 TuyaOS 传感器管理组件,可以实现对传感器设备的硬件抽象,设备管理和数据处理。基于 sensor_hub 开发传感器应用时,开发者无需关注传感器的传输协议,只需要对传感器挂载硬件接口、工作方式、采集间隔等进行配置,然后在事件回调中读取传感器处理即可。

通过 Sensor Hub 管理传感器,可快速新增、切换新的传感器,而无需修改上层应用程序。

开发者可使用 tuyaos_sensor_hub_demo_quickstart 体验 Sensor Hub 组件,将多种传感器设备加入到智能设备中,实现更多设备智能化。

在这里插入图片描述

Sensor Hub 设计思想

分层设计

Sensor Hub 组件采用软硬件分层设计,分为 sensor hub 逻辑实现层、sensor driver 驱动层,可在驱动层添加新驱动实现新传感器快速接入。

Sensor Hub 层(tdl)

主要功能:

  1. 对应用提供统一的传感交互接口
  2. 对传感驱动提供统一的适配接口
  3. 给应用提供多种比较通用的采集策略

Sensor Driver 层(tdd)

主要功能:

  1. 传感器实例化
  2. 对应用提供挂载到 Sensor Hub 上的注册接口

传感数据元素类型抽象

传感上报的数据类型由 Sensor Driver 层配置,即由传感器实例决定。

  1. 元素型

传感器采集的某一类数据可以根据其物理含义抽象为一种元素 (element),复合型传感则包含多种元素,如温湿度传感器就包含了 2 种元素:温度、湿度。一组数据中包含了 几种元素、各元素名称 (ID)、各元素值的数据类型 均由 Sensor Driver 层配置。

元素值的数据类型可分为整型、浮点型。

  1. 透传型
    传感数据存储的具体格式由 Sensor Driver 层配置,以二进制形式存储。

传感器采集策略

目前 Sensor Hub 支持以下采集策略配置:

  1. 数据读取的触发模式
  • 软定时轮询
  • 硬件定时轮询
  • IO中断
  1. 传感数据组缓存 fifo 深度

  2. 数据订阅模式

  • 元素组(每次返回都是所有元素数据)
  • 单元素(每次返回仅一种元素数据)
  1. 数据订阅规则设定
  • 数据组数
  • 过滤规则(最大值/最小值/步进值)

Sensor Hub 对上数据与接口

数据结构

1. 数据读取的触发模式

/**
 * @brief 采集触发模式
 */
typedef BYTE_T SR_TRIG_MODE_E;
#define SR_MODE_POLL_SOFT_TM	0		// 轮询(软件定时)
#define SR_MODE_POLL_HARD_TM    1   	// 轮询(硬件定时)
#define SR_MODE_EXTI            2   	// 外部中断(GPIO)

/**
 * @brief 工作模式配置
 */
typedef struct {
    SR_TRIG_MODE_E	trig_mode;			// 采集触发方式
    UINT_T    		poll_intv_ms;   	// 轮询方式:采集间隔(ms)
    TUYA_GPIO_NUM_E	irq_pin;        	// 中断方式:中断引脚
    TUYA_GPIO_IRQ_E irq_mode;       	// 中断方式:中断模式
} SR_WORK_MODE_T;

2. 元素型数据订阅规则

/**
 * @brief 元素型数据订阅类型
 */
typedef BYTE_T SR_ELE_SUB_TP_E;
#define SR_ELE_SUB_TP_GROUP		0		// 以组的形式上报应用订阅的所有元素的数据
#define SR_ELE_SUB_TP_SINGLE   	1   	// 一一上报应用订阅的每个元素的数据

/**
 * @brief 过滤规则
 */
typedef union {
    struct {
        INT_T	max;					// 最大值
        INT_T	min;					// 最小值
        UINT_T	step;   				// 步进值(非0:前后变化低于该值的会被过滤)
    } i;	// 整型

    struct {
        FLOAT_T	max;					// 最大值
        FLOAT_T min;					// 最小值
        FLOAT_T	step;					// 步进值(非0:前后变化低于该值的会被过滤)
    } f;	// 浮点型
} SR_FILTETR_U;

/**
 * @brief 元素型数据订阅规则
 * @note val_num仅在订阅类型为SR_ELE_SUB_TP_SINGLE时有效,且其值不能超过fifo_size
 */
typedef struct {
    UCHAR_T			id;					// 元素ID
    UCHAR_T   		val_num;			// 每次订阅的元素值个数
    SR_FILTETR_U    filter;     		// 过滤规则
} SR_ELE_SUB_RULE_T;

/**
 * @brief 元素型数据订阅配置
 *        拓展功能 (可选)
 */
typedef struct {
    SR_ELE_SUB_TP_E     tp;				// 元素型数据订阅方式
    UCHAR_T             num;    		// 元素订阅数量,也是元素型数据订阅规则数量
    SR_ELE_SUB_RULE_T  *rule;   		// 元素型数据订阅规则
} SR_ELE_SUB_CFG_T;

3. 数据就绪通知回调

/**
 * @brief 元素型数据缓存结构
 */
typedef struct {
    UCHAR_T			id;					// 元素ID
    SR_VAL_TP_E   	val_tp;     		// 元素值类型
    UCHAR_T   		val_num;			// 元素值个数
    SR_VAL_U       *val;				// 元素值(存储地址)
} SR_ELE_BUFF_T;

/**
 * @brief 数据就绪通知回调
 */
typedef VOID_T (*SR_ELE_INFORM_CB)(CHAR_T* name, UCHAR_T buf_num, SR_ELE_BUFF_T *ele_data);
typedef VOID_T (*SR_RAW_INFORM_CB)(CHAR_T* name, UINT_T raw_num, SR_RAW_DATA_T *raw_data);
typedef union {
    SR_ELE_INFORM_CB    ele;			// 用于元素型数据
    SR_RAW_INFORM_CB    raw;    		// 用于透传型数据
} SR_INFORM_CB_T;

4. 传感设备信息

/**
 * @brief 传感设备注册信息
 */
typedef struct {
    SR_WORK_MODE_T		mode;			// 数据采集模式
    SR_INFORM_CB_T      inform_cb;  	// 数据就绪通知回调
    UCHAR_T             fifo_size;  	// 存放返回给app数据的缓存大小
    SR_ELE_SUB_CFG_T   *ele_sub;    	// 元素型数据订阅模型配置(不使用则写NULL)
} SR_DEV_CFG_T;

/**
 * @brief 传感设备句柄
 */
typedef VOID_T* SENSOR_HANDLE_T;

应用接口

1. 创建传感器实例

/**
 * @brief 查找传感设备
 * @param[in] dev_name: 传感设备名称
 * @param[out] handle: 传感设备句柄
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_dev_find(CHAR_T *dev_name, SENSOR_HANDLE_T* handle);

2. 启动传感器

/**
 * @brief 启动传感设备
 * @param[in] handle: 传感设备句柄
 * @param[in] config: 设备配置参数
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_dev_open(SENSOR_HANDLE_T handle, SR_DEV_CFG_T* config);

3. 停止传感器

/**
 * @brief 启动传感设备
 * @param[in] handle: 传感设备句柄
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_dev_close(SENSOR_HANDLE_T handle);

4. 配置传感器参数

/**
 * @brief 配置传感设备
 * @param[in] handle: 传感设备句柄
 * @param[in] cmd: 配置命令
 * @param[in] param: 配置命令参数
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_dev_config(SENSOR_HANDLE_T handle, UCHAR_T cmd, VOID_T *param);

5. 读取传感器实时数据

/**
 * @brief 读取传感实时数据
 * @param[in] handle: 设备句柄
 * @param[in] ele_num: 元素个数,0表示透传型
 * @param[inout] ele_data: 元素型数据,不使用时写NULL
 * @param[out] raw_data: 透传型数据,不使用时写NULL
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_dev_read(IN SENSOR_HANDLE_T handle, IN UCHAR_T ele_num,
                                INOUT SR_ELE_DATA_T *ele_data, OUT SR_RAW_DATA_T *raw_data);

Sensor Hub 对下数据与接口

数据结构

  1. 元素数据类型配置
/**
 * @brief 元素数据类型配置
 */
typedef struct {
    UCHAR_T		id;						// 元素ID
    SR_VAL_TP_E	val_tp;					// 元素值类型
} SR_ELE_CFG_T;
  1. 驱动依赖资源信息
/**
 * @brief 资源信息
 */
typedef struct {
    UCHAR_T		type;					// 资源类型(I2C/SPI/...)
    UCHAR_T     port;					// 资源端口
    VOID_T*     handle;   				// 资源句柄(暂时没有用到)
    UCHAR_T     info[SR_RSRC_INFO_LEN];	// 其他资源信息
} SR_RSRC_T;

驱动接口抽象

/**
 * @brief 驱动接口抽象
 */
typedef struct {
    OPERATE_RET (*open)(SR_RSRC_T* dev);
    OPERATE_RET (*close)(SR_RSRC_T* dev);
    OPERATE_RET (*control)(SR_RSRC_T* dev, UCHAR_T cmd, VOID_T *param);
    OPERATE_RET (*read_ele)(SR_RSRC_T* dev, SR_ELE_DATA_T *ele_data, UCHAR_T ele_num); 
    OPERATE_RET (*read_raw)(SR_RSRC_T* dev, SR_RAW_DATA_T *raw_data); 
} SR_INTFS_T;

驱动注册接口

/**
 * @brief 注册传感设备
 * @param[in] dev_name: 传感设备名称
 * @param[in] intfs: 传感设备操作接口(内存由具体的传感器分配)
 * @param[in] ele_num: 传感数据元素个数,0表示采用透传型(内存由具体的传感器分配)
 * @param[in] ele_cfg: 每个元素的数据类型配置
 * @param[in] resource: 传感设备依赖的资源信息
 * @return 操作结果
 */
OPERATE_RET tdl_sensor_register(CHAR_T *dev_name, SR_INTFS_T *intfs, UCHAR_T ele_num, \
                                SR_ELE_CFG_T *ele_cfg, SR_RSRC_T *resource);

驱动开发流程

  1. 确定传感数据存储方式,如果选择元素型,则需确定有哪些 元素 及每个元素值的 数据类型
  2. 确定传感驱动的 外设 类型和需要配置的内容,比如 I2C、SPI …;
  3. 确定注册设备时需要做哪些处理,有哪些 资源信息 需要暂存至 SensorHub,实现 tdd_sensor_xxx_register 接口;(传感的通用初始化可以在注册时进行,或者使用控制命令进行,即由用户决定何时初始化)
  4. 确定传感是否有启动测量和停止测量命令,实现 openclose 接口;
  5. 确定传感读数据的过程,实现 read_eleread_raw 接口;
  6. 确定除读数据外是否需要增加其他的配置命令,实现 control 接口。

Sensor Hub使用流程

  1. 调用 tdd_sensor_xxx_register 注册 xxx 设备。
  2. 调用 tdl_sensor_dev_find 查找 xxx 设备,获得设备句柄(确认 xxx 设备是否注册成功)。
  3. 调用 tdl_sensor_dev_config 配置 xxx 设备(启动前的一些必要配置;启动后也可通过调用该接口控制设备)。
  4. 调用 tdl_sensor_dev_open 启动 xxx 设备(在需要启动时调用),同时需要编写数据通知回调函数。
  5. 调用 tdl_sensor_dev_read 读取 xxx 设备的实时数据(有需要时)。
  6. 调用 tdl_sensor_dev_close 停止 xxx 设备(在需要停止时调用)。

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

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

相关文章

vue3路由跳转params传参接收不到

import { useRouter } from "vue-router";const router useRouter(); // 提现记录 const withdrawalClick (item) > {router.push({ name: "Devwithdrawal", params: { name: 123 } }); };//跳转页面接收参数 import { useRoute } from "vue-rou…

指针和字符数组笔试题及其解析(第二组)

个人主页:Lei宝啊 愿所有美好如期而遇 前言: 数组名在寻常情况下表示首元素地址,但有两种情况例外: 1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小 2.&数组名,这里的…

OLED透明屏模块:引领未来显示技术的突破

OLED透明屏模块作为一项引领未来显示技术的突破,以其独特的特点和卓越的画质在市场上引起了广泛关注。 根据行业报告,预计到2025年,OLED透明屏模块将占据智能手机市场的20%份额,并在汽车导航系统市场中占据30%以上份额。 那么&am…

TD3算法

TD3算法 全称Twin Delayed DDPG,是对DDPG算法的继承、发展和改进,论文 改进如下: T w i n \mathcal{T}win Twin:使用了两个critic来评估actor的动作价值,对应两个critic target,一个actor target&#xff0…

[漏洞复现] metinfo_6.0.0_file-read(任意文件读取)

文章目录 漏洞描述漏洞等级影响版本漏洞复现基础环境漏洞点第一次测试第二次测试第三次测试第四次测试深度利用EXP编写EXP使用案例漏洞挖掘指纹信息修复建议 本次漏洞复现仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责&#xf…

Solidity 小白教程:10. 控制流,用 solidity 实现插入排序

Solidity 小白教程:10. 控制流,用 solidity 实现插入排序 这一讲,我们将介绍solidity中的控制流,然后讲如何用solidity实现插入排序(InsertionSort),一个看起来简单,但实际上很容易…

系统架构设计师(第二版)学习笔记----计算机系统基础

【原文链接】系统架构设计师(第二版)学习笔记----计算机系统基础 文章目录 一、计算机硬件1.1 计算机硬件的组成1.2 处理器指令集1.3 处理器层次1.4 总线分类1.5 接口的种类 二、计算机操作系统2.1 计算机软件分类2.2 操作系统的作用2.3 操作系统的特征2…

【FusionInsight 迁移】HBase从C50迁移到6.5.1(01)迁移概述

【FusionInsight 迁移】HBase从C50迁移到6.5.1(01)迁移概述 HBase从C50迁移到6.5.1(01)迁移概述迁移范围迁移前的准备HDFS文件检查确认HBase迁移目录确保数据落盘停止老集群HBase服务停止新集群HBase服务 HBase从C50迁移到6.5.1&a…

L1-063 吃鱼还是吃肉(Python实现) 测试点全过

前言: {\color{Blue}前言:} 前言: 本系列题使用的是,“PTA中的团体程序设计天梯赛——练习集”的题库,难度有L1、L2、L3三个等级,分别对应团体程序设计天梯赛的三个难度。更新取决于题目的难度,…

如何在opensuse build service (obs)打包deb包用于分发各个发行版

1.打开网页 https://build.opensuse.org/ 注册账号 创建home project 创建项目 需要配置需要打包的镜像如debian12 ubuntu等 先配置整体home仓库的全部 ​由于是home的,可能不同的项目有些不需要,可以在项目中禁用一些,再配置某个项目需要…

c语言 4.0

💂 个人主页: 程序员爱摸鱼🤟 版权: 本文由【程序员爱摸鱼】原创、在CSDN首发、需要转载请联系博主💬 如果文章对你有帮助、欢迎关注点赞收藏(一键三连)哦💅 想寻找共同成长的小伙伴,可以互粉哦 💬文章目录…

如何用Python机器学习、深度学习提升气象、海洋、水文领域实践能力!!!

Python是功能强大、免费、开源,实现面向对象的编程语言,能够在不同操作系统和平台使用,简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库,还有丰富的第三方库,Python在数据处理、科学计算、数学建模、数据挖…

测试用例设计方法真的很重要啊

记得我刚入职到部门的第一个星期,除了去熟悉公司部门的一些业务流程,就是去看我将要去测的系统的系统说明书,然后去熟悉各种业务流程,自己还是有点放不开,虽然之前也在一家公司实习过,主要是功能测试&#…

Apache HTTPD 多后缀解析漏洞复现

Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令。比如,如下配置文件: AddType text/html .html AddLanguage zh-CN .cn 其给.html后缀增加了media-type,值为text/html;给.cn后缀增加了语言&…

vue 弹框中包含avue-curd /el-table第一次点击样式正常 再次点击表格序号列和其他列错位

1.首先这里点击时获取接口数据需要等数据返回之后再打开弹框 2.给表格使用v-if 参数就是和弹框的参数一样 弹框显示再重新渲染表格就OK了

超低保证金!揭秘期权卖方的保证金是多少?

很多期权老手交易一段时间后,开始对期权卖方有了兴趣。“对于期权卖方的保证金是一笔不低的费用,如果是在分仓平台注册的账户,保证金是固定在大概在3000-4000元一张了。下文介绍超低保证金!揭秘期权卖方的保证金是多少&#xff1f…

LeetCode刷题笔记【23】:贪心算法专题-1(分发饼干、摆动序列、最大子序和)

文章目录 前置知识贪心算法的本质什么时候用贪心算法?什么时候不能用贪心?贪心算法的解题步骤 455.分发饼干题目描述解题思路代码 376. 摆动序列题目描述解题思路代码 53. 最大子序和题目描述暴力解法动态规划贪心算法 总结 前置知识 贪心算法的本质 贪心的本质是选择每一阶…

Android文字识别-阿里云OCR调用

0,阿里云OCR有在线识别接口,直接用httpPOST调用就能实现,开发起来很快捷。识别率还蛮好,摄像头斜着拍也能识别出来。实测识别时间单次在2s左右,普通使用使能满足需求的。 1,在阿里云页面先注册申请免费试用…

工作失误合集,这个月的工资被扣没咯!

俗话说“马有失蹄,人有失足”,不管是程序员还是其他行业,在工作的的时候即便是职场老手也有失手的时候。 工作中出现纰漏不可避免,但是总有那么些人秀的即使是工作出错,也错的惊为天人。今天就带大家来看看那些在工作…

C语言嵌入式系统编程注意事项之内存操作

C语言嵌入式系统编程注意事项之内存操作 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C以外的其它编程语言基本没有直接访问绝对地址的能力 数据指针 在嵌入式系统的编程中,常常要求在特…