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不可在此处配置,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(&params);   //返回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开发框架>能力地图>设备初始化

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

70、Spring Data JPA 的 自定义查询(全手动,自己写完整 SQL 语句)

1、方法名关键字查询(全自动,既不需要提供sql语句,也不需要提供方法体) 2、Query查询(半自动:提供 SQL 或 JPQL 查询) 3、自定义查询(全手动) ★ 自定义查询&#xff08…

范文展示,如何三步写出一篇满意的论文

第一步:输入文章关键信息 文章标题,写论文的话即为拟定的论文标题,例如这篇范文中的题目为“阳明心学研究” 关键词,可以写出多个论文主题相关的关键词,用逗号分开,例如这篇范文中只写了一个关键词“王阳…

9.12 C++作业

实现一个图形类(Shape),包含受保护成员属性:周长、面积, 公共成员函数:特殊成员函数书写 定义一个圆形类(Circle),继承自图形类,包含私有属性:半…

长城网络靶场第三题

关卡描述:1.oa服务器的内网ip是多少? 先进行ip统计,开始逐渐查看前面几个ip 基本上都是b/s,所以大概率是http,过滤一下ip 第一个ip好像和oa没啥关系 第二个ip一点开就是 oa,应该就是他了。 关卡描述&a…

指针-子串逆置

任务描述 从标准输入上读入以空格分隔的字符串 s 和 t,将 s 中与 t 匹配的所有子串逆置后再输出 s,当 s 中无与 t 匹配的子串时直接输出字符串 s。已经匹配的字符不会再重复匹配。 相关知识 参考之前的关卡。 编程要求 根据提示,在右侧编…

Golang编写自定义IP限流中间件

目录 基于令牌桶的限流算法实现高并发限流(使用golang官方限流器)Go代码测试记录ab -t 1 -c 1 http://127.0.0.1:8080/api/resource结果预测:1秒内最多生成10个令牌,而总共有20个串行的请求,结果应该是1个成功&#xf…

CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0

https://downloads.mysql.com/archives/community/是社区版的官网,可以选择版本下载。 cat /etc/redhat-release可以看到系统版本是CentOS Linux release 7.6.1810 (Core),uname -r可以看到版本是3.10.0-957.el7.x86_64。 yum remove -y mysql-libs把…

来看看Python MetaClass元类详解

MetaClass元类,本质也是一个类,但和普通类的用法不同,它可以对类内部的定义(包括类属性和类方法)进行动态的修改。可以这么说,使用元类的主要目的就是为了实现在创建类时,能够动态地改变类中定义…

Python3.10 IDLE更换主题

前言 自定义主题网上有很多,3.10IDLE的UI有一些新的东西,直接扣过来会有些地方覆盖不到,需要自己测试着添几行配置,以下做个记录。 配置文件路径 Python安装目录下的Lib\idlelib\config-highlight.def。如果是默认安装&#xf…

轻松鲨-AI文案写作 人工智能聊天

轻松鲨AI助手使用地址:http://www.qingsongsha.com?utm_sourcenavigation_website 或前往苹果App Store下载“轻松鲨APP” 支持AI连续对话聊天,帮你解答各种疑问... 让AI帮你画思维导图写文案,提升工作效率... 内置多场景专业模板&#xff0…

解决 tesserocr报错 Failed to init API, possibly an invalid tessdata path : ./

问题描述 我们在初次使用tesserocr库的时候,可能会报以下错误: RuntimeError: Failed to init API, possibly an invalid tessdata path: ./ 这是因为我们在使用 conda 创建的环境中找不到"tessdata"这个文件夹。 解决办法 这时候把Tessera…

品牌是什么?品牌加分秘笈曝光

作为一个多年的品牌人,这几年,历经迷惘和探索,迷惘在于: 1.品牌部是花钱部门,不直接创造营收,不受老板重视、钱少。 2.品牌作业难以衡量,一般以曝光、阅读、声量指数等指标来衡量,…

026-从零搭建微服务-文件服务(二)

写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):https://gitee.com/csps/mingyue 源码地址(前端):https://gitee.com/csps…

鼠标拖拽拖动盒子时,与盒子内某些点击事件冲突问题解决

目录 问题解决思路解决代码(标注【主要代码】的为重点) 问题 拖动该悬浮球时,鼠标弹起可能会触发悬浮球内事件 解决思路 鼠标拖动盒子时,将 isMove 设为 true 意为正在拖动盒子,此时将 class"btns_move" 遮…

利用 SOAR 加快事件响应并加强网络安全

随着攻击面的扩大和攻击变得越来越复杂,与网络攻击者的斗争重担落在了安全运营中心 (SOC) 身上。SOC 可以通过利用安全编排、自动化和响应 (SOAR) 平台来加强组织的安全态势。这一系列兼容的以安全为中心的软件可加快事…

单元格法近似求解多边形最大内接矩形问题【思路讲解+java实现】

文章目录 问题描述问题解决方案多边形网格化区分每个单元格是在多边形内部还是外部根据已标记单元格寻找最大内接矩形剪枝优化多角度旋转 案例测试代码实现说明 问题描述 给定一个多边形的点集,希望找出多边形内部面积最大的矩形。该问题可能出现在,从一…

聊聊Spring事务同步器TransactionSynchronization

在一些业务场景中可能我们需要去对某一个spring事务的生命周期进行监控,比如在这个事务提交,回滚,被挂起的时候,我们想要去执行一些自定义的操作,这怎么去做呢?其实spring作为一个高扩展性的框架&#xff0…

关系型三大范式与BCNF有什么用呢

学的时候就知道是一堆公式。 实际中在设计表的时候可能会用到。 前提是关系型数据库,比如mysql。 (实际中oracle比mysql更好用。但是他收费啊。) 第一范式:每个属性都是原子的(需要做到每个属性都是不可分割的。&…

02 java ---- Android 基础app开发

目录 相对布局 显示一个美女 显示两个美女 安卓APP启动过程 安卓布局控件 常用布局之相对布局 常用布局之相对布局 padding和margin 按键美化 常用布局之线性布局 安卓按键响应的几种方式 直接设置按键的onClick绑定的函数 自定义类实现按键监听事件的接口 匿名内…

[NLP] LLM---<训练中文LLama2(一)>训练一个中文LLama2的步骤

一 数据集 【Awesome-Chinese-LLM中文数据集】 【awesome-instruction-dataset】【awesome-instruction-datasets】【LLaMA-Efficient-Tuning-数据集】Wiki中文百科(25w词条)wikipedia-cn-20230720-filteredBaiduBaiKe(563w词条) …