Last Updated on : 2024-06-25 04:08:34download
This topic describes how to manage firmware versions and implement firmware updates over the air (OTA) for sub-devices.
The following sequence diagram shows how an OTA update for a sub-device works:
The firmware key is used to manage the firmware. One firmware key can be associated with multiple firmware versions. Steps to create a firmware key:
On the page of Product Development, find the target product.
Click Develop. The example uses a three-gang switch to show you how to create a firmware key.
Click the Hardware Development tab. Choose Add Custom Firmware.
Complete the required information and click Generate Firmware Key.
Field description
Firmware Type: Choose Extended Firmware. The protocol type less than 10 is reserved for SDK use. The protocol type greater than or equal to 10 is custom.
Update Channel: It matches the input parameter of the protocol type that is bound with the sub-device.
Update Timeout: If the sub-device fails to report the new version number, the app will prompt end-users with a message saying update timeout.
This section describes how to upload firmware updates to the platform.
Click New Firmware Version.
Enter the Firmware Version, upload the Production Firmware and Firmware Updates, and click Save & Enable.
In this example, the firmware update file only contains a Hello World
string for demonstration.
Click Save and Enable.
This section describes how to verify the updates by using the allowlist.
Click More > OTA Updates.
Select the firmware key and click New Update Deployment.
Select the firmware version we created. For Update Method, choose Update Notification. Complete the description and click OK.
Click Verify. Enter the virtual ID of the sub-device to add it to the allowlist.
To find the virtual ID, open the Smart Life app and enter the control panel of the sub-device. Tap … in the top right corner and tap Device Information.
tuya_subdev_user_sigle_type_reg
to register the device management callback and implement the callback for dev_upgrade
./**
* @brief sub-device management callback
*/
typedef struct __ty_gw_subdev_mgr_cbs_s {
GW_PERMIT_ADD_DEV_CB dev_add; // permit joining callback, see GW_PERMIT_ADD_DEV_CB
GW_DEV_DEL_CB dev_del; // remove callback, see GW_DEV_DEL_CB
DEV_RESET_IFM_CB dev_reset; // reset callback, see DEV_RESET_IFM_CB
GW_BIND_DEV_INFORM_CB dev_bind; // bind result callback, see GW_BIND_DEV_INFORM_CB
DEV_OBJ_DP_CMD_CB dp_cmd_obj; // obj DP command, see DEV_OBJ_DP_CMD_CB
DEV_RAW_DP_CMD_CB dp_cmd_raw; // raw DP command, see DEV_RAW_DP_CMD_CB
DEV_DP_QUERY_CB dp_query; // DP query, see DEV_DP_QUERY_CB
DEV_HEARTBEAT_SEND_CB dev_hb; // heartbeat query callback, see DEV_HEARTBEAT_SEND_CB
DEV_UG_INFORM_CB dev_upgrade; // upgrade callback, see DEV_UG_INFORM_CB
GW_DEV_WAKEUP_CB dev_wakeup; // low power device wakeup callback, see GW_DEV_WAKEUP_CB
GW_DEV_GRP_INFM_CB dev_grp_info; // group control callback, see GW_DEV_GRP_INFM_CB
GW_DEV_SCENE_INFM_CB dev_sce_info; // scene control callback, see GW_DEV_SCENE_INFM_CB
GW_DEV_SIGMESH_TOPO_UPDAET_CB bt_topo_update; // Bluetooth LE device added callback, see GW_DEV_SIGMESH_TOPO_UPDAET_CB
GW_DEV_SIGMESH_DEV_CACHE_DEL_CB bt_cache_del; // Bluetooth LE device removed callback, see GW_DEV_SIGMESH_DEV_CACHE_DEL_CB
GW_DEV_SIGMESH_CONN_CB bt_conn; // Bluetooth LE device event callback, see GW_DEV_SIGMESH_CONN_CB
DEV_ONLINE_STAT_SEND_CB dev_online; // online state changed callback, see DEV_ONLINE_STAT_SEND_CB
}TY_GW_SUBDEV_MGR_CBS_S;
/**
* @brief tuya sdk ota firmware info
*/
typedef struct {
/** firmware type */
DEV_TYPE_T tp;
/** upgrade type, see UPGRADE_TYPE_T */
UPGRADE_TYPE_T type;
/** firmware download URL */
CHAR_T fw_url[FW_URL_LEN + 1];
/** firmware version */
CHAR_T sw_ver[SW_VER_LEN + 1];
/** firmware size in BYTE */
UINT_T file_size;
/** firmware HMAC */
CHAR_T fw_hmac[FW_HMAC_LEN + 1];
/** firmware MD5 */
CHAR_T fw_md5[FW_MD5_LEN + 1];
/** is difference OTA or not */
BOOL_T diff_ota;
} FW_UG_S;
#define tuya_iot_dev_upgd_progress_rept(percent, devid, tp) \
tuya_iot_dev_upgd_progress_with_remain_time(percent, devid, tp, 0)
Call this function to report the progress of the firmware update.
#define TUS_RD 1 // ready
#define TUS_UPGRDING 2 // upgrading
#define TUS_UPGRD_FINI 3 // finish
#define TUS_UPGRD_EXEC 4 // error
OPERATE_RET tuya_iot_dev_upgd_result_report(IN CONST CHAR_T *dev_id, IN CONST DEV_TYPE_T type, IN CONST INT_T result);
The application calls this function to report the failure of a firmware update. By default, the change in version number indicates a successful update.
OPERATE_RET tuya_iot_upgrade_dev_notify(IN CONST CHAR_T *devid,
IN CONST FW_UG_S *fw, \
IN CONST GET_FILE_DATA_CB get_file_cb, \
IN CONST UPGRADE_NOTIFY_CB upgrd_nofity_cb, \
IN CONST PVOID_T pri_data, \
BOOL_T notify, UINT_T download_buf_size);
#define tuya_iot_upgrade_dev(devid, fw, get_file_cb, upgrd_nofity_cb, pri_data) \
tuya_iot_upgrade_dev_notify(devid, fw, get_file_cb, upgrd_nofity_cb, pri_data, TRUE, 0)
The application calls this function to get the sub-device firmware update after receiving the callback for dev_upgrade
.
get_file_cb
is invoked when the gateway downloads the firmware update.upgrd_nofity_cb
is invoked when the gateway notifies the sub-device of the update installation.STATIC CHAR_T upg_dev[DEV_ID_LEN] = {0};
/**
* @brief device OTA callback
* @param[in] fw : OTA firmware information
* @param[in] total_len : total length of OTA image
* @param[in] offset : OTA image offset
* @param[in] data : payload of OTA image
* @param[in] len : length of data
* @param[out] remain_len : tell SDK remain length
* @param[in] pri_data : pri_data is passed as the argument of tuya_iot_upgrade_dev()
*/
STATIC OPERATE_RET __dev_ota_data(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)
{
/**
* TODO:
* Receiving OTA image data callback. Maybe should write to file
*/
/**
* Here we have an example showing what should do in this callback
* a) print OTA image data (maybe you should write to file )
* b) report to the cloud.
*/
for (INT_T i = 0; i < len; i++) {
PR_DEBUG_RAW("%02x ", data[i]);
}
PR_DEBUG_RAW("\n");
UINT_T percent = 0;
percent = ((offset * 100) / (total_len+1));
if (percent >= 99) {
percent = 98;
}
tuya_iot_dev_upgd_progress_rept(percent, upg_dev, fw->tp);
return OPRT_OK;
}
/**
* @brief device OTA notify callback
* @param[in] fw : OTA firmware information
* @param[in] download_result : result of download OTA image
* @param[in] pri_data : pri_data is passed as the argument of tuya_iot_upgrade_dev()
*/
STATIC VOID __dev_ota_notify(IN CONST FW_UG_S *fw,
IN CONST INT_T download_result,
IN PVOID_T pri_data)
{
/**
* TODO:
* download_result == OPRT_OK , download success , send notify to sub-device and transform it
* download_result != OPRT_OK , download failed, report result
*/
/**
* Here we have an example :
* a) if download succeeded, report new software version
* b) if download failed, report result:
* #define TUS_RD 1 // ready
* #define TUS_UPGRDING 2 // upgrading
* #define TUS_UPGRD_FINI 3 // finish
* #define TUS_UPGRD_EXEC 4 // error
*/
if (download_result == OPRT_OK) {
tuya_iot_gw_subdevice_update(upg_dev, fw->sw_ver);
} else {
tuya_iot_dev_upgd_result_report(upg_dev, fw->tp, 4);
}
}
/**
* @brief SDK receives upgrade cmd callback
* @param[in] dev_id : device's ID
* @param[in] fw : OTA firmware information
*/
STATIC VOID __dev_upgrade_cb(CONST CHAR_T *dev_id, CONST FW_UG_S *fw)
{
/**
* TODO:
* call tuya_iot_upgrade_dev() to download sub-device's new image and do something
*/
strncpy(upg_dev, dev_id, SIZEOF(upg_dev));
tuya_iot_upgrade_dev(dev_id, fw, __dev_ota_data, __dev_ota_notify, NULL);
}
TY_GW_SUBDEV_MGR_CBS_S dev_mgr_cbs = {
.dev_upgrade = __dev_upgrade_cb,
};
tuya_subdev_user_sigle_type_reg( &dev_mgr_cbs , DEV_ATTACH_MOD_1 );
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback