重启原因分析
# 简介
在使用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
```