SOTA升级示例
场景描述
QuecThing的SOTA升级,一般来说指的是把新的固件写入外挂MCU中,代替原有的固件的过程。升级方式均为将固件包上传到开发者中心,设备从开发者中心获取固件包实现远程升级,最后 MCU 接收升级包并写入本地闪存,实现固件的升级。本章节指导用户通过QuecOpen方案进行SOTA固件升级。
涉及指令
函数 | 说明 |
---|---|
Ql_iotCmdOtaRequest() | 向平台请求OTA升级计划 |
Ql_iotCmdOtaAction() | 配置OTA升级行为 |
Ql_iotCmdOtaMcuFWDataRead() | 读取保存在模块中的固件数据 |
Ql_iotConfigSetMcuVersion() | 配置 MCU 编号及其对应的版本号 |
Ql_iotConfigGetMcuVersion() | 获取 MCU 编号及其对应的版本号 |
提示:OTA升级相关接口详情请参考这里,配置MCU版本相关接口详情请参考这里。
操作步骤
一、登录开发者中心
二、创建产品
创建产品是产品开发流程的第一步,产品是开发者中心定义一类设备的抽象描述,用于对同类设备进行管理。例如您有一台具备LTE联网能力的香薰机,需要接入开发者中心完成设备监控,则您可以定义它为一个产品:“智能香薰机”产品。
三、OTA升级操作流程
1、添加版本包
- 版本包名称 :为此升级包输入一个名称。
- 组件类型:支持模组固件升级与MCU固件升级。
- 模组固件(FOTA),一般来说指的是把新的固件写入移远模组芯片中 。
- MCU固件(SOTA),一般来说指的是把新的软件包通过移远模组烧入进外挂MCU内。
- 版本包类型:支持整包升级、差分包升级两种固件升级方式。
- 差分包针对指定源版本的升级,一般为进行小规模功能或修复BUG升级。
- 整包不指定源版本,所有设备均可升级。
- 源版本:源固件包的版本,若选择差分包类型则会显示此项,整包则无。(开发者中心根据设备连接平台时上报的设备信息中的版本号判断是否与此参数一致,若一致则下发升级信息)。
- 目标版本:固件包的新版本号。(设备升级完成后需要上报升级后的版本号,开发者中心检查设备上报的版本号是否与此参数一致,若一致则判断为升级成功)。
- 上传版本包:上传的固件文件支持格式: .bin,.zip,.rar,.pack,.mini_1,.mini_2,.py,.tar,.tar.gz,.s19,.bin_1,.bin_2等类型的文件,文件大小不能超过100MB,最多支持5个文件。
- 备注:对本次上传的固件版本进行描述和记录。
2、版本包固件验证(可选)
固件验证是为了确保将要大规模升级的固件是安全可用的,最大限度降低升级风险,防止意外损失的出现。在大批量升级设备之前,您可以选择单台设备进行固件验证并执行OTA升级流程。
i.选择需要验证的版本包,点击 固件验证。
ii.选择用来验证的设备,输入需要验证的组件标识,提交验证。
iii.点击固件包 详情,查看固件验证详情。
3、创建升级计划
在升级设备前,需创建或选择一个已有的升级计划;计划包含了需要升级的设备、升级时间、升级的组件配置等信息。
i. 基本信息填写
- 计划名称:为此升级计划输入一个名称。
- 升级产品 :选择对应需要升级设备的产品。
- 设置黑白名单:若不设置黑、白名单,则该产品下所有设备升级。若同时设置黑、白名单,则黑名单优先级大于白名单优先级
- 若只设置白名单:只允许在白名单中的设备被升级。
- 若只设置黑名单:在黑名单中的设备不允许被升级。
- 时区:此项必须配置。配置后平台只会在此时区+推送时段推送升级计划。
- 推送时段:配置平台主动推送升级计划的时间段,可选择性配置,只能配置整点到整点,至少间隔1个小时。
- 升级方式 :
- 静默升级: 是指无需用户确认,应用端将自动完成升级,再次开启后为升级过的版本。
- 用户确认升级: 是指用户需主动进入设备控制界面,在设备详情页检查并确认固件升级。
ii. 制定升级策略
在固件升级的过程中,难免会遇到因升级环境较差的情况导致升级失败,为了避免这种情况,从而需制定升级策略来减少升级失败概率。点击升级策略旁的 自定义 按钮即可在弹窗配置升级策略。
iii. 新增升级组件
升级组件是用户自主创建,由一个或多个组件构成的集合体。用于创建升级计划时对需要升级的产品组件进行选择和规划,组件名称、组件标识需唯一。
iv. 配置升级文案
用户确认升级计划需要录入升级文案,静默升级计划无需录入。其中中文和英文的文案必须输入,其他语言根据实际需求录入。
v. 激活升级任务
完成以上的 添加版本包 与 创建升级计划 操作步骤后,点击左下角的 激活计划 按钮即可激活此计划。开发者中心将会执行升级任务,下发所选的目标版本固件到升级范围内的目标设备中。
提示:升级任务激活后将不允许被删除。
4、设备初始化并连接平台
设备初始化并启动连接开发者中心,在开发者中心和设备间建立安全、稳定的通信并实现设备管理、OTA等操作。
/* 初始化QuecThing SDK */
Ql_iotInit();
/* 注册事件回调函数 */
Ql_iotConfigSetEventCB(Ql_iotEventCB);
/* 启动平台连接 */
Ql_iotConfigSetConnmode(1);
提示:使用MQTT协议连接上开发者中心的设备会自动添加至平台。
5、配置MCU版本号
/* 配置外部MCU标识号和版本号,可选,如没有外部MCU则不需要配置 */
Ql_iotConfigSetMcuVersion("STM32","1_0_0");
6、OTA请求
前提:OTA升级期间请确保设备已成功连接开发者中心。
1)在开发者中心制定完成升级计划及激活后,设备需调用 Ql_iotCmdOtaRequest() 函数请求OTA升级。
2)设备可无需请求OTA,确保设备在线,等待平台每隔10分钟主动匹配下发升级计划,例如:10:00、10:10。
提示:此API接口适用于2.9.2及以上的QuecThing版本。
- 示例代码如下所示:c
/* ota 请求*/ Ql_iotCmdOtaRequest(0);
7、设备确认升级
发送OTA请求指令后,若该设备已包含在创建的升级计划产品内,则会自动调用 Ql_iotEventCB 回调函数并上报 {7,10700} 事件。事件内容包括组件标识+源版本+目标版本+最低电池电量+最低信号强度+固件包大小。若确认设备满足升级策略要求即可调用 Ql_iotCmdOtaAction(1) 函数进行确认升级。
下发升级计划,上报的事件内容如下所示。(该事件包含:组件标识、源版本、目标版本、OTA 升级最小电量、OTA 升级最小信号强度、OTA 升级需要磁盘空间)
cvoid (*eventCB)(7,10700,"<componentNo>,<sourceVersion>,<targetVersion>,<batteryLimit>,<minSignalIntensity>,<useSpace>");
事件回调函数处理示例代码如下所示:
cvoid Ql_iotEventCB(quint32_t event, qint32_t errcode, const void *value, quint32_t valLen) { switch (event) { /* OTA事件 */ case QIOT_ATEVENT_TYPE_OTA: { switch (errcode) { /* 检测到有升级任务 */ case QIOT_OTA_TASK_NOTIFY: { char *words[100]; /* 字符串分解 */ quint32_t count = Quos_stringSplit((char *)value,HAL_STRLEN(value), words, sizeof(words) / sizeof(words[0]),",", FALSE); printf("recv ota task\r\n"); if(count < 6) { break; } /* 需确认设备是否满足升级策略要求 */ printf("componentNo:%s,sourceVersion:%s,targetVersion:%s,batteryLimit:%s,minSignalIntensity:%s,minSignalIntensity:%s\r\n", words[0],words[1],words[2],words[3],words[4],words[5]); /* 设备开始确认升级*/ Ql_iotCmdOtaAction(1); break; } } } } }
8、设备升级流程反馈
SOTA升级成功的流程分为 开始下载、下载中、下载完成、更新中、更新完成 5个步骤。每更新一个步骤都会自动调用事件回调函数 Ql_iotEventCB 并上报相应的事件。SOTA升级事件反馈如下所示。
设备开始下载固件包(该事件包含:组件标识、固件包大小、固件包 MD5 值)
cvoid (*eventCB)(7,10701,"<componentNo>,length,<MD5>");
固件包下载中
cvoid (*eventCB)(7,10702,NULL,0);
固件包下载完成 (该事件包含:组件标识、固件包大小、固件包的当前块起始位置、当前文件块大小)
cvoid (*eventCB)(7,10703,"<componentNo>","<length>,<startaddr>,<piece_length>");
MCU固件更新中
MCU 接收升级包后需运行用户提前编写好的MCU程序将固件包写入本地闪存里,从而实现固件更新。
1)MCU读取固件升级包
当模块接收完升级固件后,需调用 Ql_iotCmdOtaMcuFWDataRead() 读取出固件包,然后再通过串口或者其他连接方式传输到MCU中。
c/* MCU通过API读取文件 */ void Ql_iotEventCB(quint32_t event, qint32_t errcode, const void *value, quint32_t valLen) { switch (event) { /* OTA事件 */ case QIOT_ATEVENT_TYPE_OTA: { switch (errcode) { /* 下载完成 */ case QIOT_OTA_DOWNLOADED: { char *words[100]; quint32_t count = Quos_stringSplit((char *)value,HAL_STRLEN(value), words, sizeof(words) / sizeof(words[0]),",", FALSE); printf("ota download complete\r\n"); if(count < 4) { break; } printf("componentNo:%s,length:%s,startaddr:%s,piece_length:%s\r\n",words[0],words[1],words[2],words[3]); /* 如果是SOTA下载完成,则通过API读取文件 */ if(strcmp(QIOT_MCU_COMPONENT_NO,Quos_stringRemoveMarks(words[0])) == 0) { quint8_t readBuf[1024]={0}; for(int i=0;(i*1024)<words[3];i++) { if(Ql_iotCmdOtaMcuFWDataRead(i*1024,readBuf,sizeof(readBuf))>0) { printf("sota read file...ret:%d\r\n",ret); } else { printf("sota read file error"); break; } } } break; } } } } }
2)通知平台进入更新状态
MCU更新固件前,模块需主动调用 Ql_iotCmdOtaAction(3) 函数告知平台MCU已进入更新状态。
c/* 通知平台MCU进入更新中的状态 */ Ql_iotCmdOtaAction(3);
3)设置新的MCU版本
MCU升级完成后,模块需主动设置新的MCU版本并上报给开发者中心。
cQl_iotConfigSetMcuVersion("STM32","2_0_0");
更新MCU固件成功(上报新的MCU版本号到平台后,会响应更新完成的事件)
cvoid (*eventCB)(7,10705,NULL,0);
四、升级监控
在计划列表中点击 升级监控,在设备升级列表,可查看该计划下所有设备的升级状态。
点击 组件详情 可查看具体设备的升级日志,如下图所示。