一、前提条件
接入前需完成以下准备工作:
1. 按照 登录与注册 文档跑通 tc_iot_login 登录功能。
2. 按照 OTA 升级包 文档在后台为需要升级的模块创建并发布固件版本,确保模块名称与 OTA 初始化配置中的 module_name 完全一致。
3. 确认下载目录可写且有足够空间;设备没有文件系统时,可联系技术支持。
二、步骤 1:配置当前固件信息并初始化 OTA
SDK 登录成功后,填写各模块当前运行的固件版本,注册回调,并调用 tc_iot_ota_init。SDK 上报各模块当前版本,并在有可用升级时通过回调通知升级任务。
| 字段 | 说明 |
| module_name | 固件模块名称,以 \\0 结尾;须与后台固件模块名称一致。 |
| module_version | 当前运行的固件版本,以 \\0 结尾。 |
| firmware_info | 各模块当前固件信息数组。 |
| firmware_info_count | firmware_info 数组中的模块数量。 |
#include <stdio.h>#include <string.h>#include "tc_iot.h"#include "tc_iot_ota.h"static void on_receive_firmware_upgrade_notify( const tc_iot_ota_firmware_info_t *firmware_info, void *user_data);static void on_download_firmware_progress( const tc_iot_ota_firmware_info_t *firmware_info, uint32_t current_size, uint32_t total_size, void *user_data);static void on_download_firmware_result( const tc_iot_ota_firmware_info_t *firmware_info, tc_iot_error_e error_code, const char *error_message, const char *file_path, void *user_data);tc_iot_ota_firmware_info_t firmware_info[] = { { .module_name = "mcu", .module_version = "1.0.0", }, { .module_name = "wifi", .module_version = "1.1.0", }}; // 示例版本;实际接入时填写当前运行的固件版本。tc_iot_ota_config_t ota_config = { .firmware_info = firmware_info, .firmware_info_count = sizeof(firmware_info) / sizeof(firmware_info[0]),};tc_iot_ota_observer_t ota_observer;memset(&ota_observer, 0, sizeof(ota_observer));ota_observer.on_receive_firmware_upgrade_notify = on_receive_firmware_upgrade_notify;ota_observer.on_download_firmware_progress = on_download_firmware_progress;ota_observer.on_download_firmware_result = on_download_firmware_result;tc_iot_error_e error = tc_iot_ota_init(&ota_config, &ota_observer, NULL);if (error != TC_IOT_ERR_SUCCESS) { printf("tc_iot_ota_init failed: %d\\n", error);}
on_receive_firmware_upgrade_notify 和 on_download_firmware_result 必须注册;不需要处理下载进度时,on_download_firmware_progress 可设为 NULL。
三、步骤 2:处理升级通知,检查更新条件并发起下载
有可用升级时,SDK 调用 on_receive_firmware_upgrade_notify,通知目标模块和目标版本。设备检查本地状态,确认满足更新条件后,调用 tc_iot_ota_download_firmware 发起下载。
以下示例假设本地更新条件已满足,在回调中发起下载:
#define OTA_DOWNLOAD_DIRECTORY "./ota_firmware"static void on_receive_firmware_upgrade_notify( const tc_iot_ota_firmware_info_t *firmware_info, void *user_data) { (void)user_data; printf("[ota] receive upgrade: module=%s, target_version=%s\\n", firmware_info->module_name, firmware_info->module_version); tc_iot_error_e error = tc_iot_ota_download_firmware(firmware_info, OTA_DOWNLOAD_DIRECTORY); if (error != TC_IOT_ERR_SUCCESS) { printf("[ota] submit download failed: %d\\n", error); }}
download_directory 指定固件保存目录。下载成功后,使用结果回调提供的 file_path 读取固件。
四、步骤 3:处理固件下载进度(可选)
下载期间,SDK 通过 on_download_firmware_progress 通知已下载字节数和固件总字节数。示例按字节数计算下载百分比:
static void on_download_firmware_progress( const tc_iot_ota_firmware_info_t *firmware_info, uint32_t current_size, uint32_t total_size, void *user_data) { (void)user_data; uint32_t progress = total_size == 0 ? 0 : (uint32_t)(((uint64_t)current_size * 100u) / total_size); printf("[ota] downloading: module=%s, version=%s, progress=%u%% (%u/%u)\\n", firmware_info->module_name, firmware_info->module_version, progress, current_size, total_size);}
tc_iot_ota_report_upgrade_progress 用于上报固件刷写进度。
五、步骤 4:处理下载结果并执行固件刷写
SDK 通过 on_download_firmware_result 通知下载结果。仅在 error_code 为 TC_IOT_ERR_SUCCESS 时执行固件刷写:
| 场景 | error_code | error_message | file_path |
| 下载并校验成功 | TC_IOT_ERR_SUCCESS | NULL | 固件文件路径 |
| 下载或校验失败 | 非 TC_IOT_ERR_SUCCESS | 失败原因 | NULL |
static void on_download_firmware_result( const tc_iot_ota_firmware_info_t *firmware_info, tc_iot_error_e error_code, const char *error_message, const char *file_path, void *user_data) { ota_demo_context_t *context = (ota_demo_context_t *)user_data; if (error_code != TC_IOT_ERR_SUCCESS) { printf("[ota] download failed: module=%s, version=%s, error=%d, message=%s\\n", firmware_info->module_name, firmware_info->module_version, error_code, error_message ? error_message : ""); return; } printf("[ota] firmware ready: module=%s, version=%s, path=%s\\n", firmware_info->module_name, firmware_info->module_version, file_path); /* 复制回调参数并通知升级线程执行固件刷写,不能长期持有回调中的指针。 */ schedule_firmware_install(context, firmware_info, file_path);}
示例中的 schedule_firmware_install 由接入方实现,用于复制固件信息和文件路径,并通知独立升级线程执行固件刷写。
注意:firmware_info、error_message 和 file_path 仅在回调期间有效,延后使用时必须复制内容。
六、步骤 5:上报固件刷写进度和结果
设备在固件刷写过程中,按实际进度调用 tc_iot_ota_report_upgrade_progress。固件刷写失败,或成功后无需重启时,调用 tc_iot_ota_report_upgrade_result 上报结果。
如果固件刷写成功后需要重启,设备在新固件启动并登录后,将实际运行的新版本填入 tc_iot_ota_init 配置。SDK 会上报新版本,后台据此确认升级完成。
以下示例演示固件刷写函数返回后主动上报结果的用法:
static void install_firmware(const tc_iot_ota_firmware_info_t *firmware_info, const char *file_path) { tc_iot_error_e error = tc_iot_ota_report_upgrade_progress(firmware_info, 0); if (error != TC_IOT_ERR_SUCCESS) { printf("[ota] report upgrade progress failed: %d\\n", error); } /* 平台固件刷写过程中,应继续按实际固件刷写进度调用进度上报接口。 */ bool install_success = platform_install_firmware(file_path); if (install_success) { error = tc_iot_ota_report_upgrade_progress(firmware_info, 100); if (error != TC_IOT_ERR_SUCCESS) { printf("[ota] report upgrade progress failed: %d\\n", error); } } int32_t result_code = install_success ? 0 : -1; const char *description = install_success ? "upgrade_success" : "upgrade_failed"; error = tc_iot_ota_report_upgrade_result( firmware_info, result_code, description); if (error != TC_IOT_ERR_SUCCESS) { printf("[ota] report upgrade result failed: %d\\n", error); }}
| 接口 | 说明 |
| tc_iot_ota_report_upgrade_progress(firmware_info, progress) | 上报固件刷写进度,progress 取值范围为 0~100。 |
| tc_iot_ota_report_upgrade_result(firmware_info, 0, description) | 上报升级成功。 |
| tc_iot_ota_report_upgrade_result(firmware_info, -1, description) | 上报升级失败。 |
七、步骤 6:反初始化 OTA
设备退出登录或释放 SDK 前,调用 tc_iot_ota_deinit 停止下载并释放 OTA 资源:
tc_iot_error_e error = tc_iot_ota_deinit();if (error != TC_IOT_ERR_SUCCESS) { printf("tc_iot_ota_deinit failed: %d\\n", error);}tc_iot_logout();tc_iot_deinit();
八、常见问题
| 现象 | 排查建议 |
| tc_iot_ota_init 返回 TC_IOT_ERR_NOT_INITIALIZED | 先调用 tc_iot_init 初始化 SDK,并调用 tc_iot_login 登录。 |
| tc_iot_ota_init 返回 TC_IOT_ERR_NOT_CONNECTED | 等待 tc_iot_login 回调通知登录成功后,再初始化 OTA。 |
| tc_iot_ota_init 返回 TC_IOT_ERR_OTA_INIT_PARAM_INVALID | 检查 firmware_info 和 firmware_info_count 是否正确;模块名称不可重复,名称和版本字符串以 \\0 结尾。 |
| tc_iot_ota_init 返回 TC_IOT_ERR_OTA_INIT_OBSERVER_NULL | 需要传入合法的 observer,至少包含必填的 on_receive_firmware_upgrade_notify 和 on_download_firmware_result。 |
| on_download_firmware_result 回调中的 error_code 为 TC_IOT_ERR_OTA_START_FAILED | 检查模块名称和目标版本是否与本次升级通知一致,以及是否重复调用下载接口。 |
| 烧录完成重启后仍收到相同升级通知 | 确认新固件已生效,并在 tc_iot_ota_init 中使用实际运行的新版本初始化 |
九、联系我们
接入或使用过程中遇到问题,或有相关建议,可通过 联系我们 提交反馈。