更新时间:2024-11-20 08:51:13下载pdf
本文以 SDK 内的智能单插 Demo 为例,介绍如何使用涂鸦标准模组 Wi-Fi SDK 开发,开发一款智能单插产品。
在 涂鸦开发者平台,在 硬件开发 阶段选择 涂鸦标准模组 SDK 开发 下载的SDK 开发资料包内,有丰富的应用 Demo 可以用于参考开发应用代码。智能单插 Demo 就众多 Demo 中的其中之一。
解压下载到的 SDK 开发资料包后,您可以在 apps
文件夹下找到众多 Demo 例程。其中,插座 Demo 的目录结构如下:
Demo 中包含的文件及相关说明如下所示:
文件名 | 文件类型 | 说明 |
---|---|---|
tuya_device.h | 头文件 | 包含设备相关初始化,功能代码,产测等函数接口 |
tuya_dp_upload.h | 头文件 | 包含 DP 数据上报相关的函数接口 |
tuya_hard_table.h | 头文件 | 包含硬件外设配置相关的函数 |
tuya_device.c | 源文件 | 硬件控制接口等 |
tuya_dp_upload.c | 源文件 | 其中包含关键固件 Key 参数 |
tuya_hard_table.c | 源文件 | 硬件控制接口等 |
本章节介绍 Demo 代码是如何实现插座的功能,以及您可以怎么参考 Demo,并进行应用代码的开发。
设备与涂鸦云端交互的逻辑主要概括如下:
数据交互方式。
涂鸦设备与云端使用 JSON 数据格式进行交互,数据的标识和定义是在平台第一步选择功能点处配置的,Demo 代码在 tuya_device_config
函数中写入 DP 信息。
设备唯一识别。
在涂鸦开发者平台创建产品会产生 PID 信息,PID 是设备的唯一标识,产品的配置都是和 PID 绑定的,比如 App UI面板、云端配置、语音功能等,因此需要将 PID 信息写入到代码中,demo 代码在 tuya_device.h
中通过宏定义写入 PID 信息。
连接云端前授权。
设备要连接到涂鸦云端,需要进行授权,授权码的获取和授权的流程请参考 通用 Wi-Fi SDK 烧录、授权和产测。
Demo 实现的功能概括如下:
功能名称 | 实现方式 |
---|---|
本地控制 | 检测按键IO口状态,控制继电器IO口输出信号对继电器进行控制,如果设备联网,将状态上报到云端 |
进入配网状态 | 检测按键IO口状态,如果检测到长按按键超过一定时间后(5S),调用重置函数,使设备进入到配网状态 |
状态指示 | 判断设备当前的状态,并通过LED灯处于亮、灭、快闪、慢闪对不同状态进行指示 |
App配网 | 此部分代码涂鸦SDK已经封装完成,设备进入到配网状态后,使用App选择对应的配网方式进行配网即可,无需编写代码 |
App控制 | 解析App下发数据对硬件进行控制,并将状态上报到云端 |
App移除 | 调用移除接口,控制设备进入到配网状态 |
语音控制 | 此部分代码与App对设备进行控制原理相同 |
定时开关 | 启动软件定时器,间隔固定时间,更新倒计时,判断时间结束时,控制设备响应相应的动作 |
断电记忆 | 控制设备到一个状态时,启用一个定时器,设置时间,时间到后,将设备当前的状态写到Flash内,当重新上电时,去Flash中读取设备状态参数,对设备进行控制,保证设备处于断电前的状态 |
OTA升级 | 接收云端推送升级固件,并更新运行 |
产测 | 扫描产测SSID并判断信号强度是否满足要求,进行对应的指示 |
在了解 Demo 代码是如何实现设备管控功能前,您需要了解 SDK 的初始化流程:
本章节主要介绍功能相关的代码介绍,部分函数对应多个功能实现,所以在对应功能内展示相关部分代码,其他部分代码使用 *****
替代。
整个流程中,应用相关功能的实现,您需要重点关注 4 个函数:
user_main() // 入口函数,通过调用下边三个函数完成 SDK 初始化
pre_device_init() // 查看 SDK 版本,设置日志输出等级
app_init() // 硬件相关初始化、设置 Wi-Fi 模组工作模式,注册产测回调函数、设置配网超时时间
device_init() // 注册功能回调函数,完成初始化,运行 SDK主流程
查看 SDK 版本:
//打印SDK相关信息、固件名称和版本、设置日志打印等级
VOID pre_device_init(VOID)
{
PR_DEBUG("%s",tuya_iot_get_sdk_info());
PR_DEBUG("%s:%s",APP_BIN_NAME,DEV_SW_VERSION);
PR_NOTICE("firmware compiled at %s %s",__DATE__,__TIME__);
PR_NOTICE("system reset reason:[%s]",tuya_hal_system_get_rst_info());
SetLogManageAttr(TY_LOG_LEVEL_DEBUG); //打印等级设置
}
硬件功能及配网设置:
//初始化硬件外设、设置Wi-Fi工作模式及产测、设置配网超时时间
VOID app_init(VOID)
{
tuya_device_config();
app_cfg_set(GWCM_LOW_POWER,prod_test);
tuya_iot_wf_timeout_set(180);
}
完成硬件相关的初始化,注册功能回调函数:
// 完成硬件相关的初始化,注册功能回调函数,进入主循环
OPERATE_RET device_init(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
tuya_hard_prod_flag(FALSE); // 设置产测标识
// 功能代码相关的回调函数
TY_IOT_CBS_S wf_cbs = {
gw_status_cb,\
gw_ug_cb,\
gw_reset_cb,\
dev_obj_dp_cb,\
dev_raw_dp_cb,\
dev_dp_query_cb,\
NULL,
};
// IoT框架的初始化
op_ret = tuya_iot_wf_soc_dev_init_param(func_select.gwcm_mode_user, WF_START_SMART_FIRST, &wf_cbs, FIRMWAIRE_KEY, PRODUCT_KEY, DEV_SW_VERSION);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_wf_soc_dev_init err:%d",op_ret);
return op_ret;
}
// 软件定时器的初始化
op_ret = tuya_hard_soft_timer_init();
if(OPRT_OK != op_ret)
{
PR_ERR("tuya_hard_soft_timer_init fail,fail_num:%d",op_ret);
return op_ret;
}
// 查询 Wi-Fi 模组的状态回调函数
op_ret = tuya_iot_reg_get_wf_nw_stat_cb(__get_wf_status);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_reg_get_wf_nw_stat_cb err:%d",op_ret);
return op_ret;
}
PR_NOTICE("system free heap:%d",tuya_hal_system_getheapsize());
return OPRT_OK;
}
//初始化相关硬件,并注册本地控制处理函数
VOID tuya_device_config(VOID)
{
DEVICE_PARAM_S dev_param;
/*开发者根据硬件信息的IO口进行设置*/
dev_param.wifi_mode = GWCM_LOW_POWER;
dev_param.wifi_led.io_pin = TY_GPIOA_9;
dev_param.wifi_led.io_level = IO_LOW_LEVEL;
dev_param.key_control.io_config.io_pin = TY_GPIOA_7;
dev_param.key_control.io_config.io_level = IO_LOW_LEVEL;
dev_param.key_control.press_time = 3000;
dev_param.key_control.key_call_back = key_process;
dev_param.relay.io_pin = TY_GPIOA_6;
dev_param.relay.io_level = IO_HIGH_LEVEL;
// 产品功能相关的 DP 配置
dev_param.dev_dp.switch_dp.is_exist = TRUE;
dev_param.dev_dp.switch_dp.dpid_num = 1;
dev_param.dev_dp.switch_cd_dp.is_exist = TRUE;
dev_param.dev_dp.switch_cd_dp.dpid_num = 9;
dev_param.dev_dp.app_relay_stat.is_exist = TRUE;
dev_param.dev_dp.app_relay_stat.dpid_num = 38;
dev_param.relay_led.io_pin = TY_GPIOA_8;
dev_param.relay_led.io_level = IO_LOW_LEVEL;
tuya_hard_init(&dev_param);
}
VOID key_process(IN TY_GPIO_PORT_E port, IN PUSH_KEY_TYPE_E type, IN INT_T cnt)
{
PR_DEBUG("port:%d,type:%d,cnt:%d",port,type,cnt);
OPERATE_RET op_ret = OPRT_OK;
if(tuya_hard_judge_key_pin(port))
{
if(LONG_KEY == type)//长按事件,进入配网状态
{
tuya_iot_wf_gw_unactive();//重置配网函数
}
else if(NORMAL_KEY == type) //短按事件,执行短按功能
{
tuya_hard_key_control();//短按按键操作控制
op_ret = tuya_hard_channel_upload(DOUBLE_TYPE);//更新继电器状态
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] tuya_hard_channel_upload fail,fail_num:%d",__FUNCTION__,op_ret);
}
tuya_hard_channel_save();//保存继电器当前状态
}
else
{
PR_NOTICE("key type is no deal");
}
}
return;
}
// 短按按键操作控制
VOID tuya_hard_key_control(VOID)
{
g_dev_stat.relay_stat = !g_dev_stat.relay_stat;
PR_DEBUG("key control channel status,channel_stat:%d",g_dev_stat.relay_stat);
g_dev_stat.relay_cd_sec = 0;
tuya_hard_set_channel_stat(g_dev_stat.relay_stat);
tuya_hard_channel_upload(DOUBLE_TYPE);
}
涂鸦模组 SDK 支持实现 Wi-Fi 快连配网和热点配网两种配网方式,对应涂鸦智能 App 中的 EZ模式 和 AP模式。
智能单插 Demo 通过控制按键长按控制设备进入到不同的配网状态。
tuya_device_config
中注册按键处理函数 key_process
,判断按键长按。
调用 tuya_iot_wf_gw_unactive
控制设备进入配网状态。
配网状态的切换形式是循环机制:
tuya_iot_wf_gw_unactive
会进入到 Wi-Fi 快连配网状态。tuya_iot_wf_gw_unactive
会进入到热点配网状态。VOID tuya_device_config(VOID)
{
DEVICE_PARAM_S dev_param;
/*开发者根据硬件信息的IO口进行设置*/
dev_param.wifi_mode = GWCM_LOW_POWER; //设置 Wi-Fi 工作模式
dev_param.wifi_led.io_pin = TY_GPIOA_9;
dev_param.wifi_led.io_level = IO_LOW_LEVEL;
dev_param.key_control.io_config.io_pin = TY_GPIOA_7; //设置按键引脚
dev_param.key_control.io_config.io_level = IO_LOW_LEVEL;//设置按键触发状态
dev_param.key_control.press_time = 3000; //设置长按按键时间判断阈值
dev_param.key_control.key_call_back = key_process;//注册按键回调函数
..... //与配网无关信息,此处省略掉
tuya_hard_init(&dev_param);
}
VOID key_process(IN TY_GPIO_PORT_E port, IN PUSH_KEY_TYPE_E type, IN INT_T cnt)
{
...... //与配网无关代码,此处不做展示
if(tuya_hard_judge_key_pin(port))
{
if(LONG_KEY == type)//长按按键事件,控制设备进入配网状态
{
tuya_iot_wf_gw_unactive();//配网重置函数
}
else if(NORMAL_KEY == type)
...... //与配网无关代码,此处不做展示
}
当网络状态变化时,device_init
函数中的 tuya_iot_reg_get_wf_nw_stat_cb
回调函数调用 nw_stat_cb
,通过hw_set_wifi_led_stat
对查询设备的当前状态。
OPERATE_RET device_init(VOID)
{
..... //与网络查询无关代码,此处不做展示
op_ret = tuya_iot_reg_get_wf_nw_stat_cb(nw_stat_cb);
if(OPRT_OK != op_ret) {
PR_ERR("tuya_iot_reg_get_wf_nw_stat_cb fail,fail_num:%d",op_ret);
return op_ret;
}
..... //与网络查询无关代码,此处不做展示
}
VOID nw_stat_cb(IN CONST GW_WIFI_NW_STAT_E stat)
{
PR_NOTICE("cur_wifi_stat:%d",stat);
OPERATE_RET op_ret = OPRT_OK;
tuya_hard_wifi_status(stat); //Wi-Fi 状态对应指示灯显示
if (STAT_CLOUD_CONN == stat || STAT_AP_CLOUD_CONN == stat)
{
op_ret = tuya_hard_upload_all_data();//初次连接到云端,将设备所有功能DP信息同步,用于面板展示
if (OPRT_OK != op_ret)
{
PR_ERR("tuya_hard_upload_all_data fail,fail_num:%d",op_ret);
}
}
return;
}
根据设备当前的网络状态指示,App 选择对应的配网方式进行配网,此部分代码 SDK 内已实现,无需您再开发。当设备连接到云端时,需要将设备当前所有的DP信息同步到云端,用于App面板的显示。
// 设备连接到云端时,将设备当前所有 DP 的状态进行上报,用于 App 面板显示
VOID nw_stat_cb(IN CONST GW_WIFI_NW_STAT_E stat)
{
..... //与连接到云端
if (STAT_CLOUD_CONN == stat || STAT_AP_CLOUD_CONN == stat)
{
**op_ret = tuya_hard_upload_all_data();//初次连接到云端,将设备所有功能DP信息同步,用于面板展示**
if (OPRT_OK != op_ret)
{
PR_ERR("tuya_hard_upload_all_data fail,fail_num:%d",op_ret);
}
}
return;
}
OPERATE_RET tuya_hard_upload_all_data(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
DP_UPLOAD_S *upload_dp = NULL;
UINT_T dp_cnt = DEV_DP_NUM;
upload_dp = tuya_upload_alloc_space(dp_cnt);
if (NULL == upload_dp)
{
PR_ERR("tuya_upload_alloc_space fail");
return OPRT_COM_ERROR;
}
if (g_dev_info.dev_dp.switch_dp.is_exist)
{
tuya_upload_dp_bool_frame(upload_dp,g_dev_info.dev_dp.switch_dp.dpid_num,g_dev_stat.relay_stat);
}
if (g_dev_info.dev_dp.switch_cd_dp.is_exist)
{
tuya_upload_dp_value_frame(upload_dp,g_dev_info.dev_dp.switch_cd_dp.dpid_num,g_dev_stat.relay_cd_sec);
}
if (g_dev_info.dev_dp.app_relay_stat.is_exist)
{
tuya_upload_dp_enum_frame(upload_dp,g_dev_info.dev_dp.app_relay_stat.dpid_num,g_dev_stat.relay_power_stat);
}
// dev_report_dp_json_async(get_gw_cntl()->gw_if.id, upload_dp->dp_buf, upload_dp->cur_idx)
op_ret = dev_report_dp_json_async(get_gw_cntl()->gw_if.id,upload_dp->dp_buf,upload_dp->cur_index);
tuya_upload_delete_space(upload_dp);
if (OPRT_OK != op_ret)
{
PR_ERR("dev_report_dp_json_async all_data is fail,fail_num:%d",op_ret);
return op_ret;
}
PR_DEBUG("upload all dp data sucess");
return OPRT_OK;
}
在 device_init
函数中,注册了 DP 数据的处理回调函数 dev_obj_dp_cb
。当设备接收到App发送的数据时,系统自动调用 dev_obj_dp_cb
函数对接收到的 DP 数据处理,并控制相关硬件实现功能,然后调用 tuya_hard_upload_all_data
将状态返回给 App。
OPERATE_RET device_init(VOID)
{
...... //与控制无关代码,此处不做展示
TY_IOT_CBS_S wf_cbs = {
status_changed_cb,\
gw_ug_inform_cb,\
gw_reset_cb,\
dev_obj_dp_cb,\
dev_raw_dp_cb,\
dev_dp_query_cb,\
NULL,
};
...... //与控制无关代码,此处不做展示
}
VOID dev_obj_dp_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
PR_NOTICE("app_send dp_cnt:%d",dp->dps_cnt);
OPERATE_RET op_ret = OPRT_OK;
UINT_T dp_index = 0;
UINT_T app_send_dp_num = dp->dps_cnt;
DEV_DP_TYPE_E dpid_type = DP_NOT_EXIST;
for (dp_index = 0;dp_index < app_send_dp_num;dp_index++)
{
dpid_type = tuya_hard_dpid_type(dp->dps[dp_index].dpid);
PR_DEBUG("dpid_type:%d",dpid_type);
switch (dpid_type)
{
case SW_TYPE:
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_bool);
tuya_hard_channel_control(dp->dps[dp_index].value.dp_bool);
break;
case SW_CD_TYPE:
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_value);
tuya_hard_channel_cd_control(dp->dps[dp_index].value.dp_value);
break;
case RELAY_ST_TYPE:
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_enum);
tuya_hard_relay_power_stat(dp->dps[dp_index].value.dp_enum);
break;
default:
break;
}
}
op_ret = tuya_hard_upload_all_data();//上报所有功能DP状态,用于面板展示
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] tuya_hard_upload_all_data fail,fail_num:%d",op_ret);
}
return;
}
//App 查询设备状态
VOID dev_dp_query_cb(IN CONST TY_DP_QUERY_S *dp_qry)
{
PR_DEBUG("Recv DP Query Cmd");
OPERATE_RET op_ret = OPRT_OK;
op_ret = tuya_hard_upload_all_data();//上报所有功能DP状态,用于面板展示
if (OPRT_OK != op_ret)
{
PR_ERR("tuya_hard_upload_all_data fail,fail_num: %d",op_ret);
}
return;
}
在 App 移除设备时,设备接收到移除命令后,调用 gw_reset_cb
重置设备并进入配网状态。
VOID gw_reset_cb(GW_RESET_TYPE_E type)
{
if (GW_REMOTE_RESET_FACTORY != type)
{
return;
}
/*clear falsh data*/
tuya_hard_clear_flash_data();//清除 Flash 存储的所有设备相关的信息
return;
}
//清除 Flash 存储的所有设备相关的信息。
VOID tuya_hard_clear_flash_data(VOID)
{
OPERATE_RET op_ret = OPRT_OK;
op_ret = iot_wd_common_delete(POWER_STAT_STORAGE);
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] delete power_stat fail",__FUNCTION__);
}
op_ret = iot_wd_common_delete(CHANNEL_STAT_STORAGE);
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] delete channel_stat fail",__FUNCTION__);
}
return;
}
语音控制与 App 控制实现原理一样,详细请参考 App 配网、App 控制、App 移除。
您需要在平台增值服务开通语音功能后,才能使用音响对设备进行控制,具体参考 第三方音响接入服务。
在 dev_obj_dp_cb
中接收到倒计时信息后,进入 tuya_hard_channel_cd_control
启动软件定时器注册 count_down_timer
回调函数,每隔 1 秒更新一次倒计时,并将更新后的倒计时信息上报到云端。
VOID dev_obj_dp_cb(IN CONST TY_RECV_OBJ_DP_S *dp)
{
..... //与倒计时无关代码,此处不做展示
switch (dpid_type)
{
..... //与倒计时无关代码,此处不做展示
case SW_CD_TYPE:
PR_DEBUG("value:%d",dp->dps[dp_index].value.dp_value);
tuya_hard_channel_cd_control(dp->dps[dp_index].value.dp_value);
break;
..... //与倒计时无关代码,此处不做展示
default:
break;
}
..... //与倒计时无关代码,此处不做展示
}
VOID tuya_hard_channel_cd_control(UINT_T app_send_cd_sec)
{
g_dev_stat.relay_cd_sec = app_send_cd_sec;
if (app_send_cd_sec == 0)
{
g_dev_stat.relay_cd_sec = 0;
tuya_hard_stop_soft_timer(g_dev_timer.count_down_timer);
}
else
{
tuya_hard_start_soft_timer(g_dev_timer.count_down_timer,1000,TIMER_CYCLE);
tuya_hard_channel_upload(SINGLE_TYPE);
}
}
每次设备状态改变时,都会调用tuya_hard_channel_save
保存设备当前的状态,当设备断电重新上电时,读取 Flash 保存的设备状态,实现断电记忆功能。
STATIC VOID key_process(tuya_pin_name_t port,PUSH_KEY_TYPE_E type,INT_T cnt)
{
..... //与断电记忆无关代码,此处不做展示
if(tuya_hard_judge_key_pin(port))
{
if(LONG_KEY == type)//press long enter linking network
{
tuya_iot_wf_gw_unactive();
}
else if(NORMAL_KEY == type)
{
tuya_hard_key_control();
op_ret = tuya_hard_channel_upload(DOUBLE_TYPE);
if (OPRT_OK != op_ret)
{
PR_ERR("[%s] tuya_hard_channel_upload fail,fail_num:%d",__FUNCTION__,op_ret);
}
tuya_hard_channel_save(); //保持本地控制后的设备状态
}
..... //与断电记忆无关代码,此处不做展示
}
}
VOID tuya_hard_channel_save(VOID)
{
if (g_dev_stat.relay_power_stat == RELAY_MEM)
{
tuya_hard_start_soft_timer(g_dev_timer.channel_save_timer,5000,TIMER_ONCE); //启动软件定时器,每隔5秒钟保存一次设备当前的状态
}
PR_DEBUG("relay_power_stat is not need save,stat:%d",g_dev_stat.relay_power_stat);
return;
}
在涂鸦开发者平台配置并对设备发起固件升级,设备收到推送的升级固件后调用 gw_ug_cb
回调函数进行固件更新,更新完成后跳转到升级后的固件运行
int gw_ug_cb(IN CONST FW_UG_S *fw)
{
PR_DEBUG("Rev GW Upgrade Info");
PR_DEBUG("fw->fw_url:%s", fw->fw_url);
PR_DEBUG("fw->sw_ver:%s", fw->sw_ver);
PR_DEBUG("fw->file_size:%d", fw->file_size);
return tuya_iot_upgrade_gw(fw, get_file_data_cb, upgrade_notify_cb, NULL);
}
//下载升级固件回调函数
OPERATE_RET get_file_data_cb(IN CONST FW_UG_S *fw, IN CONST UINT_T total_len, IN CONST UINT_T offset,
IN CONST BYTE_T *data, IN CONST UINT_T len, OUT UINT_T *remain_len, IN PVOID_T pri_data)
{
PR_DEBUG("Rev File Data");
PR_DEBUG("Total_len:%d ", total_len);
PR_DEBUG("Offset:%d Len:%d", offset, len);
return OPRT_OK;
}
//升级状态回调函数
VOID upgrade_notify_cb(IN CONST FW_UG_S *fw, IN CONST INT_T download_result, IN PVOID_T pri_data)
{
PR_DEBUG("download Finish");
PR_DEBUG("download_result:%d", download_result);
}
在 app_init
中通过 app_cfg_set
注册产测函数,扫描在 tuya_main.c
中定义的 TEST_SSID,判断信号强度。
如果信号强度大于 -60dB,认为设备信号正常,启动软件定时器,调用 protest_switch_timer_cb
回调函数,进行功能测试。
如果信号强度小于 -60dB,认为设备信号异常,做出相应指示,引导用户进行问题排查。
#define TEST_SSID "tuya_mdev_test1"
VOID app_init(VOID)
{
.....
app_cfg_set(tuya_hard_get_wifi_mode(),prod_test);
.....
}
VOID prod_test(BOOL_T flag,CHAR_T rssi)
{
PR_NOTICE("rssi:%d,flag:%d",rssi,flag);
if (flag == FALSE || rssi < -60)
{
tuya_hard_set_led_state(PROD_TEST_FAIL);
}
tuya_hard_set_led_state(ENTER_PROD_TEST);
tuya_hard_prod_flag(TRUE);
}
SDK 内提供编译脚本,您可以通过如下命令调用脚本可实现代码编译。
编译指令:进入到编译脚本所在目录,执行 ./build_app.sh apps/<项目名称> <项目名称> <版本号>
。
命令示例:
./build_app.sh apps/one_plug_demo one_plug_demo 1.0.0
编译成功后会在 apps/项目名称/output/版本号/xxx.bin
目录下生成烧录用的二进制(bin)文件,如下图片所示:
编译出的 bin 文件,名称中尾缀为 QIO 的是生产固件,生产时使用,名称中尾缀为 UA 的是用户区固件,调试阶段使用,名称中尾缀为 UG 的是升级固件,OTA 时使用。
文件名 | 说明 |
---|---|
tuya_demo_elp_1plug_QIO_1.0.0.bin | 生产固件,用于模组Flash工作方式为QIO的模组 |
tuya_demo_elp_1plug_UA_1.0.0(2)_1.0.0.bin | 用户区固件,用于芯片烧录工具使用 |
tuya_demo_elp_1plug_UG_1.0.0.bin | 升级固件,用于上传涂鸦开发者平台用户区固件和 OTA 固件 |
将固件上传至涂鸦开发者平台,申请激活码,通过涂鸦 云模组烧录授权平台 写入授权信息,详情参考 通用 Wi-Fi 烧录、授权和产测 。
在调试过程中可以通过添加打印信息,监控设备的运行状态,调试代码。
涂鸦通用 SDK 的日志等级有以下几种分类:
您可以通过设置日志的等级来决定哪些日志信息输出,例如设置日志输出等级为TY_LOG_LEVEL_INFO
,则ERR
、WARN
、NOTICE
、INFO
相关信息会显示,DEBUG
、TRACE
则不会显示。
VOID pre_device_init(VOID)
{
.... //与日志无关代码,此处不做展示
PR_DEBUG("%s",tuya_iot_get_sdk_info());
PR_DEBUG("%s:%s",APP_BIN_NAME,DEV_SW_VERSION);
PR_NOTICE("firmware compiled at %s %s",__DATE__,__TIME__);
PR_NOTICE("system reset reason:[%s]",tuya_hal_system_get_rst_info());
SetLogManageAttr(TY_LOG_LEVEL_DEBUG); //打印等级设置
}
/* tuya sdk definition of log level */
typedef INT_T LOG_LEVEL;
#define TY_LOG_LEVEL_ERR 0 // 错误信息,程序正常运行不应发生的信息
#define TY_LOG_LEVEL_WARN 1 // 警告信息
#define TY_LOG_LEVEL_NOTICE 2 // 需要注意的信息
#define TY_LOG_LEVEL_INFO 3 // 通知信息
#define TY_LOG_LEVEL_DEBUG 4 // 程序运行调试信息,RELEASE版本中删除
#define TY_LOG_LEVEL_TRACE 5 // 程序运行路径信息,RELEASE版本中删除
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈