• 欢迎大家分享资料!前往留言板评论即可!

Air系列模块重启原因分析及应对策略(三)

合宙 模组资料网 4年前 (2021-05-15) 316次浏览 0个评论 扫描二维码

前两篇文章我们分别从软件、硬件角度讲述了模块重启的原因和解决方法。本文作为该系列的终篇,将详细说一下如何应对,让重启损失减到最低。

鲁棒性

提高鲁棒性才是最根本目标。为了达到这一点,应对代码进行反复测试,才能把大多数隐患解决掉(某哲人说过,当你发现一个bug,那么还有10个隐含bug未被发现)。只有通过各种极端环境下的测试,才能确保上线无忧。

发个GPRS DTU的测试表,大家体会一下:

项目 测试目的 测试方法 评测标准 结果判断标准
在线空闲测试 测试GPRS DTU维持已建链路的能力。GPRS DTU通过心跳保持连接 连上数据中心后不发任何数据,观察它能维持链路多久 应至少能维持平均1小时以上的链路持续时间,不发生断线重连 如果DTU或数据中心任何一方无法收到对方的数据包,则为不合格
数据中心关闭后恢复测试

测试GPRS DTU在数据中心中断服务并恢复后的快速响应、恢复能力 数据中心短时间关闭(如1分钟);数据中心长短时间关闭(如1小时); DTU是否能快速连接上来,恢复时间应该在5分钟内,越快越好,(重复多次该项测试) DTU必须能100%恢复连接,否则为不合格
频繁双向小数据量测试

测试GPRS DTU频繁收发小数据包的能力 在数据中心和DTU端,每10秒向对方发送一个100字节左右的数据包,持续10分钟 没有发生断线重连,也没有丢失任何数据包 如果出现DTU断线后再也不上线,或上线后无法继续双向收发数据,出现丢包,内容错误,即为不合格;
双向大数据压力测试

测试GPRS DTU频繁收发大数据包的能力 在数据中心和DTU端,每2秒都向对方发送一个1000字节左右的数据包,持续30分钟 没有发生断线重连,也没有丢失任何数据包 如果出现DTU断线后再也不上线,或上线后无法继续双向收发数据,出现丢包,内容错误,传输过慢,即为不合格;
重复上电测试

某些时候,现场会出现临时断电然后恢复的情况,GPRS DTU应能保证可靠的登录数据中心 上电,然后等待GPRS DTU连接上数据中心,每次DTU都能在2分钟内登录到数据中心 重复进行20次测试 一旦发现有一次DTU始终无法连接到数据中心,则为不合格
拨号及短信干扰测试 DTU登录或在线运行过程中,可能会收到一些不明短信或电话呼叫, GPRS DTU应能保证这些情况不影响其正常工作 DTU上电,然后等待10秒左右,开始向DTU发送2条短信,以及2次呼叫, DTU应能正确的连接上数据中心,重复进行20次测试 一旦发现有一次DTU始终无法连接到数据中心,则为不合格
看门狗测试 有良好看门狗机制的产品,在DTU死机时,能使其CPU复位 瞬间短路几个管脚,让其程序跑飞,或者RAM数据错乱,使看门狗介入工作,复位CPU 重复多次测试该项,DTU必须能100%复位 如果不能复位则不合格
去卡测试 SIM卡短时接触不良,GPRS DTU应能自动恢复 GPRS DTU连接数据中心时,短时、长时取卡,然后再插卡,看GPRS DTU是否会掉线及正常收发数据 应可连接到数据中心,正常收发数据 如果不能连接到数据中心,或者收发数据,则不合格
电源波动测试 可能出现较大范围的电源波动,GPRS DTU应能适应这种电源波动 模拟允许值范围内的电压波动,和低压情况 GPRS DTU是否会出现再也无法连接数据中心的情况 如果不能连接到数据中心,或者收发数据,则不合格
欠费测试 常年运行过程中,很可能会出现因SIM卡欠费,导致无法使用GPRS业务,在进行充值后,GPRS DTU应自动恢复与中心的连接 找一张欠费的SIM卡插入GPRS DTU,等待10分钟,给SIM卡充值,看DTU是否能自动连接到数据中心   如果DTU始终无法自行连接数据中心,并且必须要人工复位一次才能恢复连接到数据中心,则视为不合格
域名解析测试 由于域名解析服务存在临时失效的情况,因此在使用域名解析时,需要加测这个项目 域名失效模拟,恢复域名的指向,然后观察DTU是否能自动连接到数据中心 恢复时间越短越好 如果DTU始终无法自动连接数据中心,则为不合格
去天线测试 常年运行过程中,很可能会因信号问题(基站或天线)导致无法使用GPRS业务,在信号恢复后,GPRS DTU应自动恢复与中心的连接 去掉天线,模拟信号丢失情况。等待10分钟,重新插入天线,看DTU是否能自动连接到数据中心   如果DTU始终无法自行连接数据中心,并且必须要人工复位一次才能恢复连接到数据中心,则视为不合格

一个 GPRS DTU 的测试尚且如此,更复杂的项目,需要测试的内容也更多。只有通过了测试,代码稳定运行不出错,才能顺利上线。

关于这方面呢,开发者可以阅读一下《Unix编程艺术》、《人月神话》、《黑客与画家》、《程序员修炼之道》、《软件随想录》等书籍。

LED

毕竟,有些时候的测试环境还是偏于理想化,而实际场景千差万别。会有很多意想不到的bug出现,而现场往往是没有调试的机会,甚至只能“盲·Debug”,这种情况下怎么办呢?

开发者可以在写代码时,定制LED闪烁规则,使用GPIO控制LED闪烁。如此一来即便是完全不懂的人,通过观察LED情况,查表也能知晓当前设备的状态了。譬如:

绿灯频闪——未附着;

绿灯慢闪——正在附着;

绿灯爆闪——系统错误;

绿灯常亮——附着成功,可以正常通信;

绿灯熄灭——无卡;

绿灯呼吸——正在通信;

 

实际上,通过控制电压域,甚至还可以实现不同亮度。

根据LED闪烁情况和现场实际环境,开发者大致可以锁定问题所在,后续使用OTA升级修复bug

 

不得不重启

某些极为特殊的情况下,模块“不得不重启”(比如人工断电),那么如何记录运行状态,并保证启动继续运行,就成了研究的重点。

如果有电池,切换到电池供电的情况下,立即上报工作状态到云端。等待再次开机后,从云端获取工作状态并继续。如果没有电池,那么定期保存工作状态到配置文件似乎成了唯一的选项(请参考nvm demo)。

工作时,定时保存工作状态到模块内(10w次擦写+均衡磨损技术,不需要担心寿命问题),意外掉电时,至多损失某定时保存前的数据;模块上电开机后,首先读取配置文件,恢复工作状态,不会影响模块继续运行。

不过这里还有几个坑:

1、读写中,意外掉电导致的文件损坏;

2、计时器的时间戳变动;

3、待处理的数据。

关于“坑1”,nvm.lua 已经最大限度规避了。大致思路如下:

更新参数时:

1.新建一个param.temp的文件,将nvm_para.lua的文件内容与更新的内容合并好,写入param.temp

2.删除nvm_para.lua

3.param.temp更名为nvm_para.lua

开机时的处理:

1.如果nvm_para.lua存在,而param.temp不存在,不用做特殊处理;

2.如果nvm_para.lua存在,而param.temp也存在,删除param.temp

3.如果nvm_para.lua不存在, param.temp存在,将param.temp更名为nvm_para.lua

4.如果两者都不存在,恢复默认值;

感兴趣的童鞋可以去阅读nvm.lua的代码。

关于“坑2”,此计时器是指“基于时间戳的延迟N秒开启关闭某业务”。必须由配置文件的3个参数进行控制,即开始时间、持续时间、关闭时间、当前状态。其中,“持续时间”和“关闭时间”是互斥的。

例如,我要设置一个当前立即开始,延迟5分钟关闭gpio0输出的计时器,那么这四个变量应如下设定:

当前时间 = ???                                            当前模块时间戳,应定期更新

开始时间 = os.time()                                  根据当前时间戳设定数值

持续时间 = os.time() + 300                      当前时间戳 + 持续时间,设定数值

关闭时间 = 0                                                因“持续时间”已设定,所以“关闭时间”置0

当前状态 = True                                          当前的状态,开启/关闭

随后代码轮询是否到达“持续时间”的设定值。如果到达,则执行对应操作(如果设定“关闭时间”,则“持续时间”应为0)。

一切看似很美好,但是问题来了:一旦意外重启,模块的os.time()返回值必然出错,那么如何处理?答案并不复杂:上电开机后先根据“当前状态”参数去执行对应操作,打开gpio输出;然后重新设定:

当前时间 = ???                                            当前模块时间戳,应定期更新

开始时间 = os.time()                                  根据当前时间戳设定数值

持续时间 = os.time() + “持续时间”“当前时间”

                            重新设定持续时间

关闭时间 = 0                                                因“持续时间”已设定,所以“关闭时间”置0

当前状态 = True                                          当前的状态,开启/关闭


随后代码轮询是否到达“持续时间”的设定值即可。当然,更稳妥的方式是把计时交给服务端,完全受控即可避免计时出错的尴尬。

关于“坑3”,就是未发出的数据(uartsocketmqtt等),如果是非重要数据,丢就丢了吧……如果是比较重要的数据,同样可以使用nvm保存,上电后读取并继续处理。

最后,送给大家一个法宝,放在代码里,保证无bug哦:

Air系列模块重启原因分析及应对策略(三)


神马?你看到的是乱码?好吧,bug太多,佛祖已瘫……

–[[               _ooOoo_

                  o8888888o

                  88″ . “88

                  (| -_- |)

                  O\  =  /O

               ____/`—‘____

            
.’  \|     |// 
`.

           
/  \|||  : 
|||//  \

          
/  _||||| -:- |||||-  \

          
|   | \\    ///
|   |

          
| _|  ”-–/”  |   |

          
\  .-__  - 
___/-. /

        
___. .'<span>  </span>/--.--\<span>  </span>. . __

     
.”” ‘< 
`.___<|>/___.’ 
>'””.

    
| | :  - \.;\ _ /;./ - : |
|

    
\  \ -.<span>   </span>\_ __\ /__ _/<span>   </span>.- / 
/

-.____-._____/.-`____.-‘

                   `=—=’

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        
佛祖保佑       永无BUG                                     ]]

 


喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址