Air系列模块(本文指2G和4G模块)支持三种开发模式:AT开发、Lua开发、CSDK开发,本文仅介绍AT和Lua两种开发模式的远程升级功能。不同开发模式的固件组成部分也不相同:
AT开发模式:core固件
Lua开发模式:core固件+脚本
不同模块,不同开发模式,支持的远程升级功能也不尽相同,对比如下图所示
|
是否支持远程升级功能 |
远程升级成功后,新版本脚本运行异常,是否自动回退到最后一次烧录版本 |
4G模块 AT模式 |
支持core固件远程升级 |
远程升级成功后,永远不回退 |
4G模块 Lua模式 |
支持2种方式远程升级: 1、core固件+脚本全量升级 2、脚本单独升级 |
远程升级成功后,永远不回退 |
2G模块 Lua模式 |
支持脚本单独远程升级 不支持core固件远程升级 |
支持自动回退,可以通过sys.setRollBack接口来设置“是否回退”,以及“开机运行多长时间后出现的异常,才允许回退” |
2G模块 AT模式 |
不支持任何方式的远程升级 |
|
二、远程升级功能原理
2.1、4G模块(AT/Lua版本)
4G模块的flash总容量为16MB,其中有一个FBF分区(0022之前的core中,FBF分区总空间为5.375MB;0022以及之后的core中,FBF分区总空间为5.875MB),用于存放远程升级包。模块从网络端将远程升级包成功下载保存到FBF分区后,下次重启时,BOOTLOADER程序会从FBF分区将远程升级包解析、搬运到CODE区,而后再清除FBF分区的使用标志,就完成了一次远程升级过程。
Lua版本中,下载远程升级包,保存到FBF分区的过程如下(可参考lib/update.lua辅助理解):
1、执行rtos.fota_start()打开写FBF分区功能,返回0表示打开成功,其余表示失败
2、下载升级包,如果升级包较小,可以先保存到一个文件中,下载结束之后,循环执行rtos.fota_process(curData, totalLen)将升级包内容分段写到FBF分区,curData为当前要写入的分段数据内容,totalLen为升级包的总大小(单位为字节),返回0表示写成功,其余表示失败;如果升级包较大,可以边下载边写FBF分区
3、执行rtos.fota_end()关闭写FBF分区功能,返回0表示关闭成功,其余表示失败
注意:无论第2步是否成功,第1步只要成功,必须执行第3步,第1步和第3步成对出现,并且在一次升级过程中,仅执行一次即可
2.2、2G模块(Lua版本)
2G模块的flash总容量有4MB和8MB两种,其中有一个文件系统分区(不同固件的文件系统空间也不相同,可以在脚本中通过rtos.get_fs_free_size()来打印当前剩余的文件系统空间),此分区可以存放程序运行过程中实时创建的文件,也可以存放远程升级包。模块从网络端将远程升级包成功下载保存为文件系统分区的/luazip/update.bin文件后,下次重启时,内核core程序会解压缩/luazip/update.bin文件,将解压缩出来的新版本脚本和资源文件存放在文件系统分区,然后删除/luazip/update.bin文件,就完成了一次远程升级过程,自动重启以后运行的脚本代码为文件系统分区中的新版本脚本文件。
整个过程如下图所示
三、远程升级功能使用方法
3.1、4G模块(AT版本)
支持合宙服务器和自建服务器远程升级
使用方法参考:http://oldask.openluat.com/article/984
3.2、4G模块(Lua版本)
支持合宙服务器、阿里云服务器和自建服务器远程升级
合宙服务器使用方法参考:http://oldask.openluat.com/article/915
阿里云服务器使用方法参考:http://oldask.openluat.com/article/877
自建服务器使用方法参考:http://oldask.openluat.com/article/107
3.3、2G模块(Lua版本)
支持合宙服务器、阿里云服务器和自建服务器远程升级
合宙服务器使用方法参考:http://oldask.openluat.com/article/984
阿里云服务器使用方法参考:http://oldask.openluat.com/article/877
自建服务器使用方法参考:http://oldask.openluat.com/article/107
四、常见问题
4.1、请求下载升级包,服务器返回失败
登录IOT网站,进入项目,打开“固件升级->升级日志”,根据IMEI查询升级记录错误描述
如果IOT网站查询不到,搜索设备日志,获取服务器返回的错误码
然后对照下表分析:
错误码 |
错误码含义 |
导致错误的可能原因 |
17 |
无权限 |
设备IMEI不在你的账户下 |
25 |
无效的项目 |
脚本中main.lua的PRODUCT_KEY和IOT网站上产品的productKey不一致 |
26 |
无效的固件 |
Ø 确认一下main.lua中的PROJECT和IOT网站上的升级配置项中的PROJECT字段是否一致 Ø 如果是4G模块,要确保模块型号和IOT网站上的升级配置项模块型号是否一致;例如模块型号是Air720D,则IOT网站上也必须是Air720D Ø 如果是4G模块,要确保模块中使用的CORE版本号小于等于IOT网站上升级配置项中的CORE版本号;例如模块中使用的是V0017,则IOT网站上只允许大于等于V0017 Ø 如果是2G模块,要确保模块中使用的CORE版本号和IOT网站上升级配置项中的CORE版本号一致;例如模块中使用的是Luat_V0035_8955,则IOT网站上也必须是Luat_V0035_8955 |
27 |
已是最新版本 |
如果确认不是最新版本,可能原因为: Ø 设备IMEI不属于IOT网站上的产品;可将IMEI发给合宙技术支持人员确认 Ø IOT网站的升级配置项,没有配置“允许该设备升级” Ø 如果是4G模块,配置的是全固件升级(core和脚本都升级),但是上传的升级包,却只有脚本;例如模块中是core(V0017)、脚本(1.0.0),IOT网站上配置的是core(V0021)、脚本(1.0.1),但是上传升级包时,升级包是一个小于1M字节的文件,此时就会认为升级包中仅包含脚本,不包含core;所以设备请求升级时,返回错误 |
40 |
循环升级 |
当同一的IMEI,频繁的请求从A版本升级到B版本,并且从服务器下载B版本成功。超过一定频率,服务器就会返回此错误,一般有如下几种情况会导致此现象的发生 Ø 下载B版本之后,重启应用B版本过程中,发生错误,导致失败;此时仍然运行A版本,会再次请求B版本。一直这样循环 Ø 下载B版本之后,重启应用B版本成功,但是运行B版本时,很快发生了异常,导致版本回退到A版本;此时仍然运行A版本,会再次请求B版本。一直这样循环 Ø 用户在压力挂测远程升级功能,会循环请求测试 第1种和第2种情况,是程序运行异常所致,所以必须解决异常后,再考虑升级,否则一直频繁下载,会导致sim卡流量超出,造成经济损失 如果是第3种情况,可以手动解除限制,允许再次升级,解除限制的方法为: 登录IOT网站,进入项目,打开“设备列表->解除禁止升级” |
5 |
升级包文件中没有包含core |
如果设备中的core版本和升级包文件名中包含的core版本不一致,则升级包文件中应该要包含core,但是升级包文件小于1M,所以判断升级包中并没有包含core,不允许升级 |
4.2、升级配置项固件名称重复
同一产品下,允许配置多个升级配置项,但是固件名称不能重复,如下图所示
4.3、2G模块下载升级包之后,重启应用新版本失败
下面以“本地烧录的脚本为1.0.0,要远程升级到1.0.1”为例说明此问题
当1.0.0版本成功下载1.0.1升级包文件之后,会自动重启,然后从升级中解压缩出来1.0.1版本的所有脚本和资源文件,保存到文件系统中,如果文件系统空间不足,就会出现应用新版本失败的问题
目前仅出现过文件系统空间不足导致的失败问题,此问题的典型日志如下图所示:
TTS的lod,文件系统空间比较紧张,尤其要注意控制项目的脚本大小
比较可靠的一种文件系统剩余空间是否能够保证成功升级的计算方法为:“升级包bin文件”+“生成升级包时,在luatools的目录ClearScr下的所有文件”< 模块剩余文件系统空间(通过rtos.get_fs_free_size()计算出来)的85%
可参考:http://oldask.openluat.com/article/110
辅助理解
4.4、2G模块远程升级后的版本回退功能
2G模块仅支持远程升级脚本,下面以“本地烧录的脚本为1.0.0,要远程升级到1.0.1”为例说明回退功能
当成功升级到1.0.1版本后,1.0.1运行过程中,如果出现异常(例如对nil值进行算数运算:a = nil+3;这些异常可以通过errDump功能模块上报调试服务器),并且1.0.1配置了允许回退功能,则会删除1.0.1的脚本,自动重启后,运行本地烧录的1.0.0版本,可参考2.2章节的示意图。如果1.0.0版本使用了errDump功能模块,则会自动上报这个异常到errDump服务器;即使1.0.0版本没有errDump功能模块,如果没有新的错误异常产生,这个错误异常也会保存到设备中,可以再升级一个带有errDump功能的新版本,新版本升级后,仍然会上报这个错误异常到errDump服务器;如果使用的是合宙官方的errDump服务器,可以通过如下方式查询这个错误:
登录iot.openluat.com,随便选择一个产品,点进去,点击左侧的 “查询debug” 菜单, 输入设备imei号、开始结束日期,点击搜索即可(友情提醒:开始和结束日期的跨度越大,搜索速度越慢)
为什么要设计回退功能呢,功过是非暂且不评;那么有没有什么办法不允许回退版本呢,以task版本为例,有一个sys.setRollBack(flag,secs)可以灵活配置,可在本示例中的1.0.1脚本中调用这个接口配置,详情参考API说明
注意:一旦发生回退,是回退到最后一次本地烧录的版本,假设本地烧录的是1.0.0,后来远程升级到1.0.1,1.0.1又远程升级到1.0.2,.......,一直远程升级到1.0.9,只要1.0.1到1.0.9中的任何一个版本发生回退,都是回退到1.0.0版本
另外:V0035以及之前的core有个bug,如果远程升级下载升级包的过程中,重启设备,会自动回退到最后一次本地烧录的版本。如果无法更新core至V0036以及之后的版本,要尽可能的在脚本程序中,最大限度的处理这种异常:例如远程升级下载升级包过程中不要主动重启;自建的升级服务器,升级包下载后,如果校验失败,通过调用os.remove("/luazip/update.bin")删除升级包;原则就是,不要让错误或者不完整的升级包存在
4.5、远程升级对NVM、文件系统中文件的影响
远程升级功能本身对NVM中的原来保存的参数、运行过程中创建的文件没有任何影响
有关NVM的详细说明参考:http://oldask.openluat.com/article/76
4.6、远程升级包的正确性检查
远程升级包下载之后,下次重启会首先对升级包的准确性进行检查(算法不便透漏),检查通过之后才会应用升级
4.7、下载升级包过程中,如果发生异常重启,有什么影响
下载过程中,异常重启,导致升级包没有下载完整;此时异常重启,不会导致模块死机或者变砖,只是校验升级包不对,直接将升级包删除,然后2G和4G模块运行的软件代码不太相同:
1. 2G模块:如果设备中core固件的版本号是0035或者之前的版本,core中存在一个bug,会导致重启后运行的是设备最后一次本地烧录的脚本;0036以及之后的core版本不存在此bug,重启后仍然运行远程升级之前的脚本
2. 4G模块:重启后运行的是升级前的固件
4.8、下载升级包之后自动重启,重启后发现一直在不断重启
升级包中打包的文件如果含有中文名,例如:测试说明.txt,会导致模块下载升级包之后,一直不断重启的问题
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!