TuyaOS开发学习笔记(2)——NB-IoT开发SDK架构、运行流程
一、SDK架构
1.1 架构框图
基于 TuyaOS 系统,可以裁剪得到的适用于 NB-IoT 协议产品接入的 SDK。SDK 将设备配网、上下行数据通信、产测授权、固件 OTA 升级等接口进行封装,并提供相关函数。
1.2 目录结构
1.2.1 TuyaOS目录说明
- adapter:TuyaOS kernel 适配层目录。包含了 TuyaOS kernel adapter layer 定义的标准接口头文件。
- apps:TuyaOS 应用程序目录。包含了开发框架自带的演示程序,开发者应用程序。
- tuyaos_demo_nb_sample:基础的数据上报与下发演示demo。
- tuyaos_demo_nb_3rdcloud_app:接入第三方云应用demo。
- build:编译配置文件目录
- docs:TuyaOS 文档目录。包含了 TuyaOS 的使用说明、接口文档、各个功能模块的介绍和使用说明。
- include:TuyaOS 外部头文件目录。包含了 TuyaOS 对外提供服务的功能组件的接口文件。
- adapter:平台驱动适配目录
- base:基础头文件。自动生成的通用头文件。
- components:组件头文件,对外提供服务的组件头文件。
- libs:TuyaOS 库文件目录。包含了组件的静态、动态库文件。库文件名一般为 libtuyaos.a,或者 libtuya_iot.so,也可以包含其他的名称的库,可以按需链接。
- vendor:原厂 SDK,
- CHANGELOG.md:修改记录。记录了各个版本的修改记录,包括修改的 bug,新增的特性支持。
- LICENSE:授权声明。介绍使用 TuyaOS 开发框架的方式和范围、知识产权等。
- README.md:介绍文档。包含了介绍、下载、编译、接口文档链接、应用对接文档链接等内容。
- build_app.sh:应用编译入口脚本文件。编译脚本,用户可以根据自己的需求进行修改、适配。可以按照需求对 build_app.sh 的内容进行定制,比如说有较大的、特殊的 TuyaOS 开发框架,可以存放在指定的位置,在 build_app.sh 里进行下载。支持 sh、bat、py 格式。
1.2.2 应用程序及Demo目录说明
此处展示的 Demo 是 TuyaOS NB-IoT 开发包最基本的 Demo,开发者可以通过该 Demo 体验开发包支持的几乎所有功能,当然也可以基于该 Demo 开发任何产品。
- tuyaos_demo_nb_sample:基础的数据上报与下发演示demo。
- tuyaos_demo_nb_3rdcloud_app:接入第三方云应用demo。
1.2.3 组件(含库)目录说明
组件是 TuyaOS NB-IoT 开发包的主体部分,TuyaOS 的目标就是实现代码的组件化,熟练地掌握常用组件的基本原理和实现方法对于产品开发可以达到事半功倍的效果。
1.2.4 原厂SDK目录说明
Vender 是开发环境所在目录,包含芯片原厂 SDK、各类适配层以及通用头文件,由涂鸦和芯片原厂共同维护。
- mt2625:MTK芯片原厂SDK。
- toolchain:编译工具链。
- tuyaos/tuya_os_adapter:TuyaOS 各类适配层。
- include:通用头文件。为保证 TKL(Tuya Kernel Layer)层以上能够达到一套代码适用于多个芯片平台的目标,Flash 地址、外设引脚、线程优先级等平台相关的因素都通过统一的宏定义设置。
- driver:涉及TKL(Tuya Kernel Layer)层 NB-IoT、外设驱动(ADC、Flash、GPIO、I2C、SPI、UART……)等适配。
- system:涉及TKL(Tuya Kernel Layer)层系统驱动(Memory、Network、OTA、Mutex、Semaphore、Thread……)等适配。
二、运行流程
2.1 涂鸦SDK初始化流程
2.1.1 tuya_app_main
static void app_init_thread(void* param)
{user_main();/* Kill init thread after all init tasks done */tal_thread_delete(app_init_task);app_init_task = NULL;
}void tuya_app_main(void)
{THREAD_CFG_T cfg = {.priority = TASK_PRIO_NORMAL,.stackDepth = 4096*2,.thrdname = "app_init_thread",};tal_thread_create_and_start(&app_init_task, NULL, NULL, app_init_thread, NULL, &cfg);
}
2.1.2 user_main()
void user_main(void)
{OPERATE_RET op_ret = OPRT_OK;//涂鸦Device OS 日志及kv初始化:不要修改tuya_nbiot_init_params();// 应用初始化前置准备工作,用户在此处可以进行一些设置,为后续继续标准化预留pre_init();//涂鸦Device OS SDK 初始化前准备:不要修改#ifdef TUYA_RELEASE__tuya_nbiot_pre_init(APP_BIN_NAME, USER_SW_VER, true);#else__tuya_nbiot_pre_init(APP_BIN_NAME, USER_SW_VER, false);#endif// 产测初始化, 注册函数需要应用实现,其中串口驱动不需要应用提供MF_IMPORT_INTF_S user_intf = {.user_test = tuya_user_prod_test,};mf_test_system_start(&user_intf,APP_BIN_NAME, USER_SW_VER);//涂鸦Device OS SDK 初始化:不要修改__tuya_nbiot_init();//应用初始化device_init();//标记涂鸦应用初始化完成:不要修改tuya_nbiot_set_initialized();
}
2.2 设备应用初始化流程
2.2.1 pre_init()
此阶段对应初始化 NBIOT SDK 之前需要做的一些工作,用户可以根据自己的需求在 tuya_device.c
文件中实现,也可以不实现,不实现便不会执行,该函数主要用于一些外设的基本配置与需要上电快速启动的一些功能,例如:唤醒引脚初始化
、ADC 初始化
、快速点亮 LED 灯
或者 使能外设
等操作。注意:请不要在此函数中使用较长时间延时。
例如在 tuyaos_demo_nb_sample 基础的数据上报与下发演示 Demo 中进行 按键初始化与中断配置
和 LED 灯 GPIO 配置
int pre_init(void)
{/*该位置仅可以添加系统启动时硬件相关的初始化操作例如GPIO、ADC、I2C等注:UART1不可在此处配置,请在device_init()内配置请不要在此处操作长时间延时*/tuya_key_init_test();tuya_gpio_init_test();return 0;
}
例如在 tuyaos_demo_nb_3rdcloud_app 接入第三方云应用 Demo 中进行 接入云参数配置
int pre_init(void)
{TAL_NBIOT_LWM2M_REGISTER_T params;int ret = 0;params.bootstrap_en = 0; // ctcc及直连:不开启bs;cmcc:drx专网不开启,psm网络开启params.srv_ip = "117.60.157.137"; //服务器地址,电信线上params.srv_port = 5684; //服务器端口号,5684(加密),5683(不加密),移动暂时支持不加密params.isp_type = NBIOT_ISP_OTHER; //NBIOT_ISP_TUYA:表示直连三方云;否则连运营商云中转params.lifetime = 7200; //lwm2m协议交互心跳间隔,单位:秒params.psk = "bFFFcDDDEB7aaBbc"; //16~32个字符lwm2m协议交互秘钥//params.imei = "862363050000149"; //15个字符的imei,可以由底层获取,可选!/*endpoint_name,pskid*///device attribute:params.attri.obj_id = 19;params.attri.ins_id_up = 0;params.attri.ins_id_down = 1;params.attri.res_id = 0;ret = tuya_user_api_3rd_cloud_config(¶ms); //返回0:成功return ret;
}
2.2.2 device_init()
此阶段用于初始化产品功能,用户根据自己的需求在 tuya_device.c
文件中实现。如果是连接涂鸦云,需要配置 PRODUCT_KEY
与一些必要的回调注册,下面以一种经典的场景举例介绍该函数的使用方法:
int device_init(void)
{int ret = OPRT_OK;// 配置产品 PIDtuya_user_api_set_product_key(PRODUCT_KEY);// 设置事件捕获回调函数tuya_user_api_event_loop_set_cb(tuya_event_process_cb, NULL);// 启动事件捕获任务tuya_user_api_event_loop_start();// 设置云端下发数据点回调函数tuya_user_api_dp_write_default_cb(tuya_dp_write_cb);// 设置记录型数据点上报结果回调函数tuya_user_api_dp_report_record_ack_register_cb(dp_report_notify_callback);// 设置心跳时间tuya_user_api_lifetime_set(600);// 设置记录型数据在弱网条件下的上报时间间隔tuya_user_api_record_dp_lifetime_set(600);/*此处可创建用户任务*/return ret;
}
2.3 系统事件捕获流程
svc_nb
NB-IoT服务组件
API 位于 TuyaOS/include/components/svc_nb/include/tuya_event_loop.h
首先在 device_init()
函数中进行 tuya_user_api_event_loop_set_cb()
设置事件捕获回调和 tuya_user_api_event_loop_start()
启动事件捕获任务。
int device_init(void)
{······// 设置事件捕获回调函数tuya_user_api_event_loop_set_cb(tuya_event_process_cb, NULL);// 启动事件捕获任务tuya_user_api_event_loop_start();······
}
2.3.1 系统事件捕获回调
在事件捕获回调 tuya_event_process_cb()
中进行判断和处理 SDK 返回的事件 ID
static OPERATE_RET tuya_event_process_cb(void* ctx, system_event_t* event)
{USER_API_LOGD("tuya user event:%d",(event->event_id));switch (event->event_id) {case SYSTEM_EVENT_NETWORK_DISCONNECT:if (STR_EQU(event->event_info.param, "TRUE")) {//网络断开,数据无法发送!USER_API_LOGD("SYSTEM_EVENT_NETWORK_DISCONNECT");}break;case SYSTEM_EVENT_NETWORK_READY:USER_API_LOGD("SYSTEM_EVENT_NETWORK_READY");break;case EVENT_LWM2M_CONNECTED:USER_API_LOGD("EVENT_LWM2M_CONNECTED");break;case EVENT_LWM2M_READY:USER_API_LOGD("EVENT_LWM2M_READY");data_send();break;case SYSTEM_EVENT_GOING_REBOOT://系统准备重启!USER_API_LOGD("SYSTEM_EVENT_GOING_REBOOT");break;case SYSTEM_EVENT_GOING_SLEEP://系统准备进入睡眠!USER_API_LOGD("SYSTEM_EVENT_GOING_SLEEP");break;default:break;}return OPRT_OK;
}
2.3.2 系统事件ID
位于 TuyaOS/include/components/svc_nb/include/tuya_comm.h 中,事件 ID 包含以下各种状态:
typedef enum {SYSTEM_EVENT_ID_CARD, //设备识别到SIM卡正常SYSTEM_EVENT_NO_ID_CARD, //设备未识别到SIM卡SYSTEM_EVENT_NETWORK_READY, //成功附着基站SYSTEM_EVENT_NETWORK_DISCONNECT,//网络断开SYSTEM_EVENT_REG_DENIED,SYSTEM_EVENT_BE_AWAKENED, //设备正准备睡眠时被打断醒来!SYSTEM_EVENT_DELAY_SLEEP, //进入睡眠倒计时阶段!SYSTEM_EVENT_GOING_SLEEP, //马上进入睡眠!SYSTEM_EVENT_DELAY_REBOOT, //进入重启倒计时阶段!SYSTEM_EVENT_GOING_REBOOT, //设备正在重启SYSTEM_EVENT_WAKE_FROM_NORMAL_RTC_TIMEOUT, //普通RTC超时唤醒SYSTEM_EVENT_WAKE_FROM_DISCRETE_RTC_TIMEOUT, //离散RTC超时唤醒EVENT_LWM2M_CONNECTED, //已连接LWM2M服务器EVENT_LWM2M_READY, //LWM2M网络服务已可用EVENT_LWM2M_UPDATE_SUCCESS, //数据上报成功EVENT_LWM2M_RESPONSE_SUCCESS, //数据响应成功 EVENT_LWM2M_SEND_FAIL, //LWM2M协议层发送失败EVENT_LWM2M_RESTART, //LWM2M网络重连EVENT_DEVICE_INFO_RESET, //设备信息重置EVENT_DEVICE_BIND_ON, //设备已绑定EVENT_DEVICE_UNBIND_ON, //设备未绑定EVENT_DEVICE_DEACTIVE, //设备重置 EVENT_POWERKEY_PRESS, //POWER按键被按下EVENT_SLP_UNLOCK, EVENT_FOTA_UPDATE_DELAY,EVENT_HEARTBEAT_SEND, //心跳发送EVENT_FACTORY_RESETING,EVENT_COMPOSITE_ACTIVE_SUCCESS, //复合产品NB为X模组激活成功EVENT_LWDP_PACKET_SEND, //LWDP数据包异步发送EVENT_SLEEP_TYPE, //睡眠事件类型EVENT_DISCRETE_ON, //离散开始EVENT_CFUN_ON,EVENT_HEARTBEAT_LIFETIME_UPDATE, //心跳周期更新SYSTEM_EVENT_MAX
} system_event_id_t;
主要事件包括:
- 当设备读到SIM卡后,响应
SYSTEM_EVENT_ID_CARD
此事件。 - 当网络注册上基站后,响应
SYSTEM_EVENT_NETWORK_READY
此事件。 - 当ISP模式(代理服务器模式)时,设备会先与代理服务器通讯,通讯正常,则设备响应
EVENT_LWM2M_READY
事件。 - 当设备登录上代理服务器,则响应
EVENT_LWM2M_CONNECTED
事件。 - 当设备网络断开,响应
SYSTEM_EVENT_NETWORK_DISCONNECT
事件。
• 由 Leung 写于 2023 年 9 月 9 日
• 参考:SDK 架构-TuyaOS-涂鸦开发者
TuyaOS>NB-IoT开发框架>能力地图>设备初始化
相关文章:

TuyaOS开发学习笔记(2)——NB-IoT开发SDK架构、运行流程
一、SDK架构 1.1 架构框图 基于 TuyaOS 系统,可以裁剪得到的适用于 NB-IoT 协议产品接入的 SDK。SDK 将设备配网、上下行数据通信、产测授权、固件 OTA 升级等接口进行封装,并提供相关函数。 1.2 目录结构 1.2.1 TuyaOS目录说明 adapter:T…...

Qt应用开发(基础篇)——普通按钮类 QPushButton QCommandLinkButton
一、前言 QPushButton类继承于QAbstractButton,是一个命令按钮的小部件。 按钮基类 QAbstractButton 按钮或者命令按钮是所有图形界面框架最常见的部件,当按下按钮的时候触发命令、执行某些操作或者回答一个问题,典型的按钮有OK,A…...
Data Structures Fan(cf)
考察异或运算以及前缀和 题意大概:给你一个长度为n的a数组,一个长度为n的01字符串,会询问q次 当x的值为1 给出 l r 将 l r 区间中的0 改变为1,1改变为0 。当x的值为2是 若随后的数为0 则输出当前字符串中 是0 的a数组中的数异或 …...

BIOS < UEFI
Basic Input Output System (BIOS) Unified Extensible Firmware Interface (UEFI)...

微信最新更新隐私策略(2023-08-15)
1、manifest.json 配置修改 在mp-weixin: 参数修改(没有就添加) "__usePrivacyCheck__": true, ***2、注意 微信开发者工具调整 不然一直报错 找不到 getPrivacySetting 废话不多说 上代码 3、 编辑首页 或者用户授权界面 <uni-popup…...
Java中xml转javaBean
Java中xml转javaBean maven坐标 <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.13.4</version></dependency>代码测试 import cn.hutool.js…...
Spring Boot集成JPA和ClickHouse数据库
简介 Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。它具有快速开发特性,可以大大减少开发人员的工作量。JPA(Java Persistence API)是Java中处理关系型数据库持久化的标准规范,而ClickHouse是一个高性能、分布…...

Hadoop生态圈中的Hive数据仓库技术
Hadoop生态圈中的Hive数据仓库技术 一、Hive数据仓库的基本概念二、Hive的架构组成三、Hive和数据库的区别四、Hive的安装部署五、Hive的基本使用六、Hive的元数据库的配置问题七、Hive的相关配置项八、Hive的基本使用方式1、Hive的命令行客户端的使用2、使用hiveserver2方法操…...

idea配置gitLab
前言:网上有很多类似的文章,但描述不够详细 步骤1:安装git 如果安装成功再次点击TEST按钮展示如下:git版本 步骤2:idea配置gitlab 查看当前项目管理的 远程仓库再git的地址,该地址可是gitLab的࿰…...

工程可以编译通过,但是Vscode依然有波浪线提示
前言 (1)我们在使用Vscode进行开发的时候,命名文件成功编译通过了,但是Vscode还是有波浪线的提示。 (2)其实成功编译通过就行,但是肯定还会存在一些强迫症患者,硬要消除这个报错。接…...

黑马JVM总结(二)
(1)栈 栈帧对应一次方法的调用,线程是要执行代码的,这些代码都是由一个个方法组成,线程运行的时候每个方法需要的内存叫做一个栈帧 (2)栈的演示 Frames:相当有栈 方法相当于栈帧…...
《Effective C++中文版,第三版》读书笔记7
条款41: 了解隐式接口和编译期多态 隐式接口: 仅仅由一组有效表达式构成,表达式自身可能看起来很复杂,但它们要求的约束条件一般而言相当直接而明确。 显式接口: 通常由函数的签名式(也就是函数名…...

脚本:python实现动态爱心
文章目录 效果代码Reference python实现dynamic heart 效果 代码 import turtle as tu import random as ratu.setup(0.5, 0.5) # 设置画板大小(小数表示比例,整数表示大小) tu.screensize(1.0, 1.0) # 设置屏幕大小 tu.bgcolor(black) #…...

【李宏毅】深度学习6:机器学习任务攻略
如果在测试集上的效果不佳,应该要做什么?Optimization 如何选择?解决 overfitting 的方法? 测试集上的效果不佳 看训练数据的loss,是不是模型本身就没训练好? 问题:model 太简单了,…...

如何使用SQL SERVER的OpenQuery
如何使用SQL SERVER的OpenQuery 一、OpenQuery使用说明二、 OpenQuery语法2.1 参数说明2.2注解 三、示例3.1 执行 SELECT 传递查询3.2 执行 UPDATE 传递查询3.3 执行 INSERT传递查询3.4 执行 DELETE 传递查询 一、OpenQuery使用说明 在指定的链接服务器上执行指定的传递查询。 …...
element-tree树结构-默认选中第一个节点高亮-根据id选中节点高亮
前言 tree树结构是在开发中经常使用的组件,比如区域树,楼层树,组织架构树,等等包含节点关系 实际开发可能需要我们一进到页面选中树形结构第一个节点,并且调用数据,来达到用户体验 在用户选择之后&#x…...

Python实操 PDF自动识别并提取Excel文件
最近几天,paddleOCR开发了新的功能,通过将图片中的表格提取出来,效果还不错,今天,作者按照步骤测试了一波。 首先,讲下这个工具是干什么用的:它的功能主要是针对一张完整的PDF图片,可…...
JVM监控和调优常用命令jps|jstat|jinfo|jmap|jhat|jstack实战
1.JVM监控和调优的主要目的 性能优化:通过JVM调优,可以提高Java应用程序的性能,减少响应时间,提高吞吐量,以更好地满足用户需求。性能优化可以加快应用程序的执行速度,减少延迟,提高用户体验。 内存管理:JVM负责管理Java应用程序的内存。正确的内存管理可以避免内存泄漏…...

chatglm2-6b在P40上做LORA微调 | 京东云技术团队
背景: 目前,大模型的技术应用已经遍地开花。最快的应用方式无非是利用自有垂直领域的数据进行模型微调。chatglm2-6b在国内开源的大模型上,效果比较突出。本文章分享的内容是用chatglm2-6b模型在集团EA的P40机器上进行垂直领域的LORA微调。 …...

WebGL 同时使用多幅纹理
目录 前言 编辑 示例代码 颜色矢量的分量乘法来计算两个纹素最终的片元颜色 注册事件响应函数:loadTexture(),最后一个参数是纹理单元编号。 请求浏览器加载图像: 配置纹理:loadTexture࿰…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...