重启原因分析

# 简介 在使用LuatOS-Air二次开发时,经常会遇见死机,无限重启等问题。导致脚本程序无法正常进行,再次烧录困难等。下面就讲解一下如何发现到如何解决这个问题。 # 分析重启原因 分析重启原因首先要知道重启开机原因,才能进行下一步判断。在LuatOS-Air脚本里添加一段打印重启开机原因脚本: ```lua sys.taskInit(function() sys.wait(3000) reason=rtos.poweron_reason() log.info("开机原因",reason) end) ``` 开机原因表: |POWERON事件| 代码| 解释| | --- | --- | --- | | rtos. POWERON_KEY| 0| 按键开机 | | rtos. POWERON_CHARGER| 1| 充电开机| | rtos. POWERON_ALARM| 2| 闹钟开机| | rtos. POWERON_RESTART| 3| 软件重启开机| | rtos. POWERON_EXCEPTION| 4| 异常开机| | rtos. POWERON_EXCEPTION| 5| reset键重启开机| | rtos. POWERON_EXCEPTION| 6| 异常开机(底层出错)| | rtos. POWERON_HOST| 7| HOST工具控制重启开机(仅限2G模块)| | rtos. POWERON_WATCHDOG| 8| 其他原因| | rtos. POWERON_WATCHDOG| 255| 其他原因| 1.开机原因:0 所以,如果模块重启前有频繁的通信操作,且没有固定的语句报错(无规律性),重启后上报的poweron reason为0,此时应该重点排查供电问题。如果存在瞬间电压跌落,可能会导致模块出现异常。 2.开机原因:3,6, 8 当poweron reason为3时,通常有两种情况:代码主动执行rtos.restart()或者sys.restart()实现软重启;代码运行出错(语法错误,内存不足、AT执行超时等多种可能性),底层自动重启; 当poweron reason为6时,只有这一种情况:底层出错,请上报bug; 当poweron reason为8时,通常是这种情况:Lua代码跑飞,底层亦无响应时,由外部看门狗芯片重启模块。 一般不会出现poweron reason为255,如出现,请联系FAE。 为了调试方便,建议开发者首先在任意lua文件中加入如下代码: ```lua require”sys” require”log” sys.timerLoopStart(function() log.info("RAM free size:", 1024 - collectgarbage("count"), "KB") log.info("ROM free size:", rtos.get_fs_free_size(), "KB") end, 5000) For luaScript: require”sys” sys.timer_loop_start(function() print("RAM free size:", 1024 - collectgarbage("count"), "KB") print("ROM free size:", rtos.get_fs_free_size(), "KB") end, 5000) ``` 加入如上代码后,模块在运行时,即可间隔5秒打印一次RAM、ROM使用情况。 代码报错: | 序号错误提示| 错误原因 | 解决方法| | --- | --- | --- | | attempt to index %s| 变量/函数 索引错误 | 修改代码| | attempt to call %s| 变量/函数 引用错误| 修改代码| | disp.init: error param width(%d) height(%d)| disp初始化时,设置了错误的宽、高| 修改为正确数值| | disp.init: pixel depth must be 16| disp像素色深必须是16位| 修改代码| | i2c.write: data must be number,string,table| i2c数据必须是数值、字符串或table|修改数据类型 | | i2c.read: size must < %d| i2c读取错误,数据长度超限| | | bad argument #%d (%s)| audio错误的参数| 修改传入的参数| | calling " LUA_QS " on bad self (%s)| audio错误的调用| | | name conflict for module " LUA_QS, libname| 命名冲突| 修改名称| | too many results to unpack| unpack方法传参错误| | | attempt to use a closed file| 文件已关闭,无法调用| 打开文件| | file is already closed| 文件已关闭| 打开文件| | wrong number of arguments| 传参 参数 个数错误| 检查传参内容| | string slice too long| 字符串过长| | | attempt to use an invalid ICONV_TYPENAME| Iconv不支持的类型| | | BUG: Unable to fetch CJSON configuration| cjson配置错误| | | JSON parser does not support UTF-16 or UTF-32JSON| 不支持utf-16或utf-32字符编码| | | Memory allocation error in CJSON protected call| 无法为CJSON分配内存 | | | invalid pin| GPIO配置错误,不存在该pin| 检查代码和硬件设计手册| | invalid PIO operation| GPIO非法操作| | | uart.setup can't be called on virtual UARTs| UART无法初始化| 检查代码,uart.setup相关配置| |invalid number| UART错误的端口号| 检查代码,uart.setup相关配置 | | invalid format| Uart.setup错误的配置参数 | 检查代码,uart.setup相关配置| # AT+RESET导致模块死机(软件重启死机) ## 1. 引发的问题 ## 1.1 空中升级失败 ​ 模块在ota升级时会请求升级包,升级包下载完成后软件重启失败,间接导致升级失败。 ## 1.2 luatools重启模块失败 ​ luatools工具使模块重启实际是通过端口向模块发送(AT+RESET)指令,使模块重启。实际上也属于软件重启。 ## 1.3 lua程序中,重启死机 ​ 当然lua代码中,也属于软件重启,也会死机。 ## 2.原因 ​ 模块的RESET_IN_N引脚与GND短路 # 常见问题 * 烧录脚本后一直重启 1.可能是脚本BUG,仔细检查脚本逻辑,有无死循环等 2.开发板供电不稳等,仔细参考硬件设计:[电源参考设计](https://hmi.wiki.luatos.com/doc/65042949/e6zPC3k9/I2hhHyzr) * 如何进行闹钟开机设置? 参考 [如何用开发板实现alarm功能](https://doc.openluat.com/wiki/21?wiki_page_id=2161) * rtos.restart和sys.restart一样吗? rtos.restart()是软件重启的接口,无返回值,调用该接口后,系统进行重启; sys.restart("用户自定义字符串")也是软件重启的接口,返回值为用户自定义的字符串,用户可以很方便的在LuatOS-Airloos中查看自定义字符串。 打开lib中的sys.lua文件,搜索restart函数,可以看到,其实sys.restart()函数也是调用了rtos.restart()的底层库,只不过多了一句用户自定义打印。 ```lua function restart(r) assert(r and r ~= "", "sys.restart cause null") if errDump and errDump.appendErr and type(errDump.appendErr) == "function" then errDump.appendErr("restart[" .. r .. "];") end log.warn("sys.restart", r) rtos.restart() end ```