全部产品
弹性计算 会员服务 网络 安全 移动云 数加·大数据分析及展现 数加·大数据应用 管理与监控 云通信 阿里云办公 培训与认证 智能硬件
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 更多
阿里云物联网套件

OTA固件升级

更新时间:2017-10-27 18:51:31

概述

  • 本文档描述进行MQTT设备OTA升级的一般流程,旨在让您快速构建一个OTA功能。device_upgrade_flow

  • 本文档将围绕“将设备上的固件从当前固件A(版本号为: version1.0)升级到目标固件B(版本号为: version2.0)”这一目标进行,其中,OTA推送通道采用MQTT,OTA固件下载通道采用HTTPS,其它通道的流程与此类似。

前提条件

  • OTA依赖于IoT套件,所以需要IoT套件相关能力,诸如IoT控制台的账户
  • OTA是IoT套件上的服务,所以需要您开启OTA服务
  • OTA必须关联某个设备,所以需要您提前创建好产品、设备

OTA基本流程

该篇实践的基本流程如下:

  • 1) 编译好固件A、固件B
  • 2) 固件A烧录到设备中,并运行设备,上报版本号
  • 3) 在IoT控制台上添加目标固件B,固件版本号填为version2.0,并推送升级
  • 4) 设备端将收到云端推送的URL,并从该URL拉取固件,同时上报状态,并写入设备Flash中
  • 5) 设备重启,此时设备运行新固件(即固件B),启动后向云端上报版本号 “version2.0”
  • 6) 云端收到版本号 “version2.0”后,方认为OTA完成

OTA具体流程与操作

编译好固件

  • 请根据不同的平台编译固件A、固件B
  • 注意:固件A与固件B至少有一个区别:上报的版本号不一样,固件A上报的版本号为 “version1.0”,固件B上报的版本号为 “version2.0”,在代码中体现为:
  1. //固件A中:
  2. IOT_OTA_ReportVersion(h_ota, "version1.0");
  1. //固件B中:
  2. IOT_OTA_ReportVersion(h_ota, "version2.0");

烧录&运行固件A

  • 请将固件烧录到设备中,并启动运行设备,OTA相应的初始代码如下:
  1. h_ota = IOT_OTA_Init(PRODUCT_KEY, DEVICE_NAME, pclient);
  2. if (NULL == h_ota) {
  3. rc = -1;
  4. printf("initialize OTA failed\n");
  5. }

注意: OTA模块的初始化依赖于MQTT连接,即代码中先获得的MQTT客户端句柄:pclient

IoT控制台操作

  • 步骤1 添加固件

添加固件

  • 步骤2 填写固件信息

填写固件信息请务必注意版本号填写正确

  • 步骤3 验证固件(即触发固件推送)

a) 验证固件-1

验证固件-1

b) 验证固件-2

验证固件-2

验证固件之后方可对固件进行批量升级

设备端处理升级推送

  • 步骤1 设备端收到URL等固件信息,以下是日志样例:OTA信息

  • 步骤2 设备端收到URL之后,通过下载通道下载固件

IOT_OTA_IsFetching()接口用以判断是否有固件可下载,IOT_OTA_FetchYield()接口用以下载一个固件块,IOT_OTA_IsFetchFinish()接口用以判断是否已下载完成,具体参考代码如下:

  1. //判断是否有固件可下载
  2. if (IOT_OTA_IsFetching(h_ota)) {
  3. unsigned char buf_ota[OTA_BUF_LEN];
  4. uint32_t len, size_downloaded, size_file;
  5. do {
  6. //循环下载固件
  7. len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
  8. if (len > 0) {
  9. //写入到Flash等存储器中
  10. }
  11. } while (!IOT_OTA_IsFetchFinish(h_ota)); //判断固件是否下载完毕
  12. }

注:一般情况下,由于RAM不足,在下载的同时需要写入到系统OTA区

  • 步骤3 下载固件的同时上报下载状态

通过IOT_OTA_ReportProgress()接口上报下载状态,参考代码如下:

  1. if (percent - last_percent > 0) {
  2. IOT_OTA_ReportProgress(h_ota, percent, NULL);
  3. }
  4. IOT_MQTT_Yield(pclient, 100); //注:为了让消息能够到达云端,必须调用该接口

升级进度可以上传升级进度百分比(1%~100%),对应的进度会实时显示在控制台正在升级列表的进度列。

升级进度也可以上传失败码,目前失败码有以下四种,对应消息:

  • -1:升级失败(fail to upgrade)
  • -2:下载失败(fail to download)
  • -3:校验失败(fail to verify)
  • -4:烧写失败(fail to flash)
  • 步骤4 检查固件合法性,并最终令硬件系统下次启动时运行新固件

通过IOT_OTA_Ioctl()接口,获取固件是否合法,参考代码如下:

  1. int32_t firmware_valid;
  2. IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
  3. if (0 == firmware_valid) {
  4. printf("The firmware is invalid\n");
  5. } else {
  6. printf("The firmware is valid\n");
  7. }

如果固件合法,则需要通过修改系统启动参数等方式(不同系统的修改方式可能不一样)以使得硬件系统下一次启动时运行新固件(即固件B)

设备重启运行新固件,并向云端上报新版本号

  • 设备重启,此时设备运行新固件(即固件B)
  • 在OTA模块初始化之后,调用IOT_OTA_ReportVersion()上报当前固件(即固件B)的版本号,具体代码如下:
  1. if (0 != IOT_OTA_ReportVersion(h_ota, "version2.0")) {
  2. rc = -1;
  3. printf("report OTA version failed\n");
  4. }

完成

  • 云端收到版本号:”version2.0”,至此,认为OTA完成

其它

  • 具体代码请查看文件:$(IOTX-SDK)/sample/ota/ota_mqtt-example.c
本文导读目录