OTA接口介绍及示例

更新时间:2023-01-29 07:31:53下载pdf

在使用模组自定义开发方式下,可以通过涂鸦的模组去 OTA 一些无法联网的芯片(也可以叫做模组的附属芯片,当模组与 MCU 协同工作的时候,MCU 就可以看做是模组的附属设备)。本文主要介绍的是如何通过可以联网的涂鸦模组去给其附属设备进行 OTA 升级。

在 Tuya IoT SDK 中有一个非常重要的回调结构体,当设备升级、网络状态发生改变、DP 的上报和下发等等功能都是通过这个结构体进行回调处理的。该结构体是通过 tuya_iot_wf_soc_dev_init_param() 函数将回调结构体注册进去的,这里要讲的附属设备的 OTA 升级也是和这个结构体有着密切的关系的。回调结构体原型如下:

typedef struct {
    GW_STATUS_CHANGED_CB gw_status_cb;
    GW_UG_INFORM_CB gw_ug_cb;
    GW_RESET_IFM_CB gw_reset_cb;
    DEV_OBJ_DP_CMD_CB dev_obj_dp_cb;
    DEV_RAW_DP_CMD_CB dev_raw_dp_cb;
    DEV_DP_QUERY_CB dev_dp_query_cb;
    DEV_UG_INFORM_CB dev_ug_cb;
    DEV_RESET_IFM_CB dev_reset_cb;
#if defined(TUYA_GW_OPERATOR) && (TUYA_GW_OPERATOR==1)
    OPE_HTTPC_GET_CHCODE_CB ope_get_chcode_cb;
#endif
#if defined(ENABLE_ALARM) && (ENABLE_ALARM==1)
    GW_OFFLINE_DP_SAVE gw_offline_dp_save_cb;
#endif
#if defined(QRCODE_ACTIVE_MODE) && (QRCODE_ACTIVE_MODE==1)
    ACTIVE_SHORTURL_CB active_shorturl;
#endif
    GW_UG_INFORM_CB pre_gw_ug_cb;
    DEV_UG_INFORM_CB pre_dev_ug_cb;
}TY_IOT_CBS_S;

当附属设备进行 OTA 升级的时候就是通过 GW_UG_INFORM_CB gw_ug_cb; 这个结构体成员进行回调处理的。通过阅读提供的 demo 代码可以发现在该注册回调函数中调用了 tuya_iot_upgrade_gw() 函数注册了 get_file_data_cb()upgrade_notify_cb() 这两个回调函数。

/**
* @brief ota inform callback
*
* @param[in] fw: firmware info
* @return 
*/
INT_T gw_ug_inform_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);
}

1. 获取文件数据回调函数

通过该函数可以获取到联网模组的附属设备的升级固件。


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);

Parameters:

  • fw: 固件信息结构体。
  • total_len: 固件总长度。
  • offset: 当前下载包偏移量。
  • data: 当前下载包的数据。
  • len: 当前下载包长度。
  • remain_len: 剩余长度。
  • pri_data: 私有数据。

Return:

  • OPRT_OK: 函数执行成功。
  • other: 函数执行失败。

在该函数的参数中值得一提的是固件信息结构体,其函数原型如下:

typedef struct {
    DEV_TYPE_T tp;      // firmware type
    UPGRADE_TYPE_T type;
    CHAR_T fw_url[FW_URL_LEN+1];  // firmware download url
    CHAR_T sw_ver[SW_VER_LEN+1];  // firmware version
    UINT_T file_size;             // firmware size in BYTE
    CHAR_T fw_hmac[FW_HMAC_LEN+1];  // firmware hmac
#if defined(ENABLE_IPC) && (ENABLE_IPC != 0)
    CHAR_T fw_md5[FW_MD5_LEN+1];  // firmware md5
#endif
    BOOL_T diff_ota;
}FW_UG_S;

该结构体中值得一提的是 tp 这个结构体成员,它表示的是固件的通道号。根据固件类型的不同,分别赋予它不同类型的通道号。通道 0-9 涂鸦定义使用,10-19 通道给用户自定义使用。

2. 下载完成回调函数

在固件下载完成后会调用该函数。


VOID upgrade_notify_cb(IN CONST FW_UG_S *fw, IN CONST INT_T download_result, IN PVOID_T pri_data);

Parameters:

  • fw: 固件信息结构体。
  • download_result: 0:下载成功。其他:下载失败
  • pri_data: 私有数据。

Return:

  • None

3. OTA 在平台上的操作

在 IoT 平台上进行自定义固件升级,需要先将固件上传到 IoT 平台,才可以进行升级。

点击查看固件上传详细流程介绍

点击查看固件升级详细流程介绍

4. 应用示例

这里将从 IoT 平台接收到的固件数据通过串口打印出来。可以看到通道数为 9 说明这是 MCU 的通道。这里需要说明的是在涂鸦方案中,根据芯片类型的不同为其分配了不同的通道号。这样的做目的是在一些产品中一个联网模组可能会有多个附属设备,例如一个多模无线网关,就有可能会在 WiFi 模组下挂载一个蓝牙芯片和一个 ZigBee 芯片。这里的演示为了简单,模拟的是一个 WiFi 模组下挂载了一个 MCU 芯片,通过 WiFi 模组给 MCU 芯片进行 OTA 升级。涂鸦的 IOT 平台对固件仅提供透传功能,加密、校验等功能需要开发者自己进行处理。

点击到 GitHub 查看完整工程代码

OTA接口介绍及示例