FOTA(远程升级)
一. 概述
update是物联网中比较常用的功能,本文介绍如何用Air724开发板,和合宙IOT后台如何做update升级。
LuatOS-Air开发模式下,固件分为两部分:core和script
远程升级时:core为差分升级;script为全量覆盖升级
远程升级时:可以仅升级script;可以仅升级core;也可以同时升级core+script
支持合宙iot平台升级和自建第三方服务器升级
二. 材料准备
-
EVB_Air724UG_A13开发板一套,包括天线SIM卡,USB线。
-
PC电脑,以及登录官方IOT后台 https://iot.openluat.com/
三. API说明
API接口说明参考:update API
四. 合宙iot平台升级core+script过程
1. iot平台创建产品
-
登录合宙iot平台
-
如果没有账户,注册一个账户
-
我的项目->新建产品
-
复制PRODUCT_KEY
2. 模块端脚本修改,生成升级包
core | 旧版本core | 新版本core |
---|---|---|
例子 | LuatOS-Air_V4002_RDA8910 | LuatOS-Air_V4003_RDA8910 |
要求 | 1、大于等于旧版本core版本号 | 2、新旧版本core支持的功能相同(功能特性说明) |
script main.lua | 旧版本 (模块端本地烧录的) | 新版本 (生成的量产文件,远程升级包) | 要求 |
---|---|---|---|
PROJECT (项目名称) | LUAT_IOT_SERVER_UPDATE | LUAT_IOT_SERVER_UPDATE | 新旧版本保持一致 |
VERSION (软件版本号) | 1.0.0 | 1.0.1 | 大于等于旧版本VERSION |
PRODUCT_KEY (项目密钥) | 3TNamWSWhGQKS7pXWyIjoBZWC4xFRMCU | 3TNamWSWhGQKS7pXWyIjoBZWC4xFRMCU | 和iot平台创建的产品 ProductKey保持一致 |
注意:脚本中要require"update"加载update功能模块,才能支持远程升级,可以参考update的demo
3. 按照新版本的需求,修改main.lua
如下图所示,PROJECT和PRODUCT_KEY保持不变,PRODUCT_KEY需和服务器保持一致,VERSION修改为1.0.1。
4. 使用Luatools生成新版本的升级包
如下图所示
在Luatools目录下的4G远程升级文件 下,生了一个后缀名为dfota.bin的文件LUAT_IOT_SERVER_UPDATE_1.0.1_LuatOS-Air_V4003_RDA8910.dfota.bin,这个就是新版本的升级包
如果不需要升级底层core,则只需要勾选,升级文件包含脚本选项即可。
5.在合宙iot平台配置升级包
进入iot平台创建的产品,打开我的项目->固件列表->创建固件,如下图所示
点击确定之后,升级配置完成,如下图所示
添加需要升级的模块imei,如下图所示
6. 模块开机,完成升级
烧录旧版本的模块开机后,连接升级服务器,下载差分升级包,自动重启,重启过程中完成固件升级,整个过程的关键日志如下图所示
7.云平台查看升级日志
登录云平台,选择对应设备升级的产品->固件升级->升级日志->输入对应的imei并选择日期->搜索
可以看到设备在此日期下的空中升级日志。正常升级成功的情况下,短时间内会有两次升级请求,第一次请求升级获取到升级包之后,设备重启升级成功会再次向云平台请求是否有更高版本的固件可以升级。直到升级结果为 “已是最新版本” 服务器没有更高版本的固件为止。
设备升级失败等情况,可对照以下表格寻求解决方案。
响应码 | 响应信息 | 问题以及解决办法 | 云平台日志结果 |
---|---|---|---|
3 | 无效的设备 | 检查请求键名(imei小写)正确性 | 无 |
17 | 无权限 | 设备会上报imei、固件名、项目key。 服务器会以此查出设备、固件、项目三 条记录, 如果 这三者不在同一个用户名下,就会认为无权限。 设备不在项目key对应的账户下, 可寻找合宙技术支持查询该设备在哪个账户下, 核实情况后可修改设备归属 | 无权限 |
21 | 21 | 不允许8910从1.2升到1.3 | 21 |
25 | 无效的项目 | productkey不一致,检查是否存在拼写错误, 检查模块是否在本人账户下,若不在本人账户下,请联系合宙工作人员处理 | 未找到项目 |
26 | 无效的固件 | 固件名称错误,项目中没有对应的固件。用户自己修改了固件名称,可对照升级日志中设备当前固件名与升级配置中固件名是否相同(固件名称,固件功能要完全一致,只是版本号不同)。 | 找不到固件 |
27 | 已是最新版本 | 1、设备固件版本高于云平台 2、固件版本设备脚本版本高于云平台版本 3、用户项目升级配置中未添加该设备 4、云平台升级配置中,是否升级配置为否 | 已是最新版本 设备不在配置的升级设备列表中 |
40 | 循环升级 | 云平台进入设备列表搜索被禁止的imei,解除禁止升级就好了。 云平台防止模块在升级失败后,反复请求升级导致流量耗尽, 在模块一天请求升级六次后会禁止模块升级。可在平台解除。 | 检测到循环升级 (已禁止升级,请到设备列表解除) |
43 | 请等待 | 云平台生成差分升级包需要等待, 一到三分钟后云平台生成完成差分包便可以请求成功。 | 正在生成版本,请等待 |
44 | 基础版本缺失 | 平台未收录设备固件(多为定制固件, 可寻找合宙技术支持人员添加,需提供定制固件邮件) | 基础CORE版本缺失 |
注意:
1、用户可以使用postman测试云平台升级接口,以下是对应字段以及意义,字段顺序没有要求。
样例
http://iot.openluat.com/api/site/firmware_upgrade?
project_key=dHfCNSiXXZtnHzZAohcHIJkWM5vZBNZc&imei=866714049393862
&firmware_name=luat_IoT_SERVER_UPDATE_LuatOS-Air_RDA8910_TTS_NOVOLTE_FLOAT
&version=1.3.1
&core_version=3032
&dfota=1
2、表格中的响应码与响应信息为模块升级时日志中显示的结果,可以在测试升级时获取到结果
五. 合宙iot平台仅升级core或者仅升级script过程
和升级core+script过程相比,仅有一点不同:
2.2.2步骤生成升级包时:
1、如果仅升级core,勾选 升级文件包含core,不勾选 升级文件包含脚本
2、如果仅升级script,勾选 升级文件包含script,不勾选 升级文件包含core
六. 自建第三方服务器升级过程
使用合宙iot平台升级,操作简单,升级原理如下:
只需要将新版本的升级包配置在合宙iot平台即可
模块请求升级时,合宙iot平台自动生成core差分包和script全量包:
1、core差分包:根据模块中的版本信息在合宙的erp系统中找到对应的升级包,然后将这个升级包和iot平台上配置的新版本升级包,做差分处理,生成core对应的差分包
2、script全量包:直接根据iot平台上配置的新版本升级包,提取出来script全量包
3、将core差分包和script全量包合成一个文件,发送给模块
使用自建第三方服务器升级,操作可以简单也可以复杂:
简单的做法是:服务器设计完善,完全参考合宙iot升级后台设计,自己的服务器可以获取到已经出错的所有core版本对应的升级包
复杂的做法是:完全手动生成core差分包+script全量包。例如已经出货的core版本有0017、0018、0019,现在要统一升级到0020,则需要按照如下步骤操作:
1、手动生成:从0017到0020的core差分包+script全量包、从0018到0020的core差分包+script全量包、从0019到0020的core差分包+script全量包
2、模块请求升级时,服务器根据模块中的core版本返回对应的升级包文件
手动生成差分包的过程如下:
用合宙提供的web工具制作差分包。工具地址 在线生成差分包
操作步骤:
1、准备:模块中使用的旧版本core升级文件
此文件指的是模块中旧版本core发布包中的dfota.bin文件(从合宙官方渠道下载),例如以LuatOS-Air_V0017_RDA8910.dfota.bin为例,在下图中的LuatOS-Air_V0017_RDA8910文件夹中
]
2、准备:需要升级的新版本升级文件
使用luatools生成升级文件,无论core是否需要升级,升级文件必须包含core,因为差分会用到
参考2.2.2章节生成新版本的升级文件,例如:LUAT_IOT_SERVER_UPDATE_1.0.1_LuatOS-Air_V0022_RDA8910.dfota.bin
3、生成差分包
使用luatools生成升级文件,无论core是否需要升级,升级文件必须包含core,因为差分会用到
使用在线生成差分包生成即可
](undefined "undefined")
4、差分包上传到自建服务器
lua固件默认支持HTTP获取升级包,引用库文件require"update"
启动远程升级功能
-- update.request(cbFnc,"www.userserver.com/update")
-- update.request(cbFnc,nil,4*3600*1000)
@function[opt=nil] cbFnc,每次执行远程升级功能后的回调函数,回调函数的调用形式为:
cbFnc(result),result为true表示升级包下载成功,其余表示下载失败。如果没有设置此参数,则升级包下载成功后,会自动重启
@string[opt=nil] url,使用http的get命令下载升级包的url,如果没有设置此参数,默认使用LuatOS-Air iot平台的url如果用户设置了url,注意:仅传入完整url的前半部分(如果有参数,即传入前一部分),http.lua会自动添加,以及后面的参数"www.userserver.com/updatefirmware_upgrade",则http.lua会在此url后面补充下面的参数,自建服务器时,服务器可根据模块信息,向模块下发相应的固件升级包,以及模块管理工作。
意义 | 键名 | 值 |
---|---|---|
项目key | project_key | 4ELoj3kWnm3KXdSO3DGnRTkykBiu3SC8 |
模块imei | imei | 866714049393860 |
固件名称 | firmware_name | LUAT_IOT_SERVER_UPDATE_LuatOS-Air_RDA8910_TTS_NOVOLTE_FLOAT |
固件版本号 | core_version | 3032 |
默认为一 | dfota | 1 |
软件版本号 | version | 1.6.9 |
@number[opt=nil] period,单位毫秒,定时启动远程升级功能的间隔,如果没有设置此参数,仅执行一次远程升级功能
5、使用其他协议实现自建服务器远程升级
可参考脚本库中update.lua
配置。无论使用哪种协议,远程升级的关键是获取正确的升级固件包。
七. 常见问题
1、差分包下载完成之后,对差分包会不会有校验?
差分包下载完成之后,下次重启过程中,会对差分包进行校验; 如果校验通过,则自编程应用新版本,之后自动删除差分包; 如果校验失败,则自动删除差分包 所以说,差分包下载过程中,如果异常断电或者异常重启,并不会出现程序丢失或者变砖的问题
2、远程升级完需要多长时间?
升级时间根据差分包的大小不同,升级时间会不同。跨越的版本越大,差分包越大,升级所需的时间越长。实测,升级一个600k左右的差分包,3分钟内能升级完成。
### 3、空中升级能跨基线升级吗? 不可以,1.2基线升级1.3基线会升级失败。
4、空中升级结束后模块变砖
1、密钥加密脚本与未加密脚本和luac加密之间不能相互空中升级,如果本地烧录的脚本为未加密脚本,云平台脚本为密钥加密的脚本,升级结束后模块会变砖。脚本加密详细介绍
5、luatools升级文件无资源文件选项是什么意思,资源文件包括哪些类型?
升级资源无资源文件:表示打包升级包时,不会包含选中的资源文件 资源文件:非lua脚本的文件都算资源文件
6、使用update函数更新的时候,出现这个错误是什么原因(-96)
当返回值为-96时,可能是由于多种原因造成的。但是返回-96时就是固件校验错误。 具体原因查看上面:设备升级失败列表
7、升级服务已经配置了全项目升级,为啥还是有些设备报不在升级列表
确认前面是否有低版本配置了IMEI号
8、请问差分工具有离线版本吗?
没有
9、关于V30XX_RDA8910_RBTTSQRLLSDFT 更名为 V31XX_RDA8910_BT_TTS_FLOAT
一、更名原因
1.版本命名不规范和定制固件命名方式重合 2.升级到LVGL7.11 导致模块flash空间不足
二、版本区别
V31XX_RDA8910_BT_TTS_FLOAT 不支持LVGL 功能 V30XX_RDA8910_RBTTSQRLLSDFT 版本支持LVGL ,其他功能完全一样
三、更名影响
如果之前使用V30XX_RDA8910_RBTTSQRLLSDFT且没用LVGL的话,可以直接升级到V31XX_RDA8910_BT_TTS_FLOAT ,功能上完全兼容。
四、远程升级注意事项
从V30XX_RDA8910_RBTTSQRLLSDFT 升级到V31XX_RDA8910_BT_TTS_FLOAT 需要将生成的升级包中的【V31XX_RDA8910_BT_TTS_FLOAT.dfota.bin】 改为 【V31XX_RDA8910_RBTTSQRLLSDFT.dfota.bin】再进入 IOT 系统升级 如图:
10、远程升级对NVM,文件系统的影响
一、远程升级时,会清除原有的para.lua吗?
默认不会 如果需要清除,根据产品的业务逻辑,在合适的时间点,调用nvm.restore()恢复出厂设置即可
二、远程升级时,可以在config.lua中增加新的参数吗?
可以,需要执行一次初始化动作才会生效,一般是直接重启执行初始化
三、远程升级时,可以在config.lua中删除旧的参数吗?
可以,但是操作起来比较复杂,不建议这样做 如果旧的参数没用了,可以在config.lua中一直保留;脚本代码不要再读写这些参数就行了 NVM详细说明见:nvm(参数存储)
四、远程升级时,自己创建的文件会被删除吗?
不会,会保留
11、循环升级
现象
iot日志现象
串口日志现象
ap日志现象
三次握手,连接成功后立刻断开,服务端可以收到请求信息(实际未连接成功,服务器也未下发差分文件,服务器误以为模块下载成功了,判定此次请求为升级成功,到达模块升级上限,服务器便会禁止模块升级)。
测试步骤
1、空中升级时反复请求升级,请求升级地址可以请求到差分文件。(排除下载地址问题,排除服务器问题)
2、使用开发板烧录旧版固件(pac文件),复现问题。(开发板升级没问题,排除差分包问题)
3、烧录socket demo链接测试服务器(客户自己的服务器正常连接,测试服务器连接失败,流量卡白名单问题)
12、开机后fota升级,底层会检测电量吗?
不会
13、手动生成差分包失败
1、生成升级文件的时候,需要选升级文件包含core选项
2、确保上传文件正确,升级版本和基础版本CORE支持的功能需要相同,选择.bin后缀的升级文件
14、724可以远程降级吗?
合宙iot平台,不支持远程降级操作,如果新脚本有问题,可以把代码恢复到之前的版本,然后把版本号+1。例如:新脚本为1.0.2,之前版本为1.0.1,需要恢复到1.0.1版本,需要把1.0.2代码恢复成1.0.1版本对应代码,版本号改为1.0.3,然后在去升级。 core为差分升级,故不支持远程降级。