阿里云物联网平台为设备提供OTA升级与管理服务。本文介绍设备如何通过物联网平台完成远程升级功能。
前提条件
使用流程
如下功能时序图,以设备的应用程序./demos/ota_basic_demo.c
为例,介绍设备升级过程。
步骤1: 设备初始化
创建设备句柄,完成设备建连。
static void* demo_device_init(char *product_key, char *device_name, char *device_secret, char *host, uint16_t port) { int32_t res = STATE_SUCCESS; /* 创建设备 */ void *device = aiot_device_create(product_key, device_name); if (device == NULL) { printf("device create failed\n"); return NULL; } /* 设置设备密钥 */ aiot_device_set_device_secret(device, device_secret); /* 连接配置参数初始化 */ aiot_linkconfig_t* config = aiot_linkconfig_init(protocol); /* 设置服务器的host、port */ aiot_linkconfig_host(config, host, port); /* 设置设备连接参数 */ aiot_device_set_linkconfig(device, config); /* 设备建连 */ res = aiot_device_connect(device); if (res < STATE_SUCCESS) { /* 尝试建立连接失败, 销毁MQTT实例, 回收资源 */ aiot_linkconfig_deinit(&config); aiot_device_delete(&device); printf("aiot_device_connect failed: -0x%04X\n\r\n", -res); return NULL; } /* 建连成功返回设备对象 */ aiot_linkconfig_deinit(&config); return device; }
设置OTA消息回调。
memset(&ota_task, 0, sizeof(ota_task)); ota_task.device = device; ota_task.ota_process_flag = 0; ota_task.filename = "fireware.bin"; /* 设置OTA回调函数 */ aiot_device_ota_set_callback(device, demo_ota_msg_callback, &ota_task);
步骤2: 上报设备版本号
物联网平台可根据上报的设备版本号决定是否推送升级。
/* 上报设备版本号 */
aiot_device_ota_report_version(device, NULL, "4.0.0");
步骤3: 请求固件信息
物联网平台部署升级固件后,会推送升级消息。当有升级任务时,设备可以主动请求升级信息。
/* 设备主动请求升级包,如果有升级任务,会下发 */
aiot_device_ota_request_firmware(device, NULL);
步骤4: 处理固件信息
步骤1中已设置OTA消息回调,在接收到消息后,会执行该回调函数。回调函数不能长时间阻塞,新建线程用于处理固件下载及升级动作。
static void demo_ota_msg_callback(void *device, const aiot_ota_msg_t *ota_msg, void *userdata)
{
int32_t res = STATE_SUCCESS;
pthread_t ota_process_thread;
demo_ota_task_t *task = (demo_ota_task_t *)userdata;
if(ota_msg != NULL && ota_msg->http_url != NULL) {
/* 判断设备是否已经在执行升级,避免重复升级 */
if(task->ota_process_flag != 0) {
return;
}
/* 回调中不能长时间阻塞,拷贝消息用于异步处理, 拷贝的对象需要删除 */
task->ota_msg = aiot_ota_msg_clone(ota_msg);
res = pthread_create(&ota_process_thread, NULL, demo_ota_process_thread, task);
if (res < 0) {
aiot_ota_msg_free(task->ota_msg);
task->ota_msg = NULL;
printf("pthread_create demo_ota_process_thread failed: %d\n", res);
return;
} else {
/* 设置线程为detach状态,用于自动资源回收 */
pthread_detach(ota_process_thread);
}
} else {
printf("ota invalid message \r\n");
}
}
步骤5: 下载固件
下载固件会在下载完成时退出,也可设置接收固件的超时时间,超时也可退出。
/* 下载文件 */
res = core_http_download_request(task->ota_msg->http_url, params, task->filename, save_file, NULL);
步骤6: 固件校验
固件校验是为了确保固件是否完整,示例中采用的是MD5校验,如果校验出错,不再执行升级动作,上报校验失败的状态并退出升级。
res = file_md5_check(task->filename, task->ota_msg->expect_digest);
if(STATE_SUCCESS != res ) {
/* 校验固件失败,上报状态 */
aiot_device_ota_report_state(task->device, NULL, -3);
}
步骤7: 上报升级状态
上报升级状态可在升级过程表示升级的进度,如下示例在固件下载完成后上报进度100%,用户可自行定义升级进度。
/* 写文件系统或者flash成功,上报升级进度 */
aiot_device_ota_report_state(task->device, NULL, 100);
步骤8: 上报新的版本号
只有上报的版本号与新固件的版本号相同,物联网平台才会认为升级完成,建议设备重启后再上报。
/* 更新新版本号表示升级完成,建议是重启后再上报 */
/*
aiot_device_ota_report_version(task->device, NULL, ota_msg->version);
*/
步骤9:设备反初始化
/* 断开设备连接,并回收设备资源 */
demo_device_deinit(device_client);
文档内容是否对您有帮助?