Air780E/Air780EP/Air780EQ/Air201模塊遇到死機(jī)問題如何分析
簡介
本文檔適用于合宙Air780E、Air780EP、Air780EQ、Air201
關(guān)聯(lián)文檔和使用工具:
從Ramdump里分析內(nèi)存泄漏問題
無法抓底層log的情況下如何導(dǎo)出死機(jī)dump
Luatools下載調(diào)試工具
EPAT抓取底層日志
Flashtools_v4.1.9下載
luatools和EPAT這2個(gè)工具,具體使用方法要了解,本文不做深入講解,EPAT抓取底層日志文檔內(nèi)有詳細(xì)使用說明
luatools用于捕獲從USB口的用戶log,即luat_debug_print輸出的log,僅用于csdk和luatos。AT版本沒有用戶log和用戶串口通道,需要使用EPAT工具抓取。
EPAT用于捕獲USB口,UART0(DBG_UART串口) 的底層log,在luatools沒有開啟的時(shí)候,EPAT同樣捕獲用戶log的大部分內(nèi)容,這個(gè)時(shí)候用戶log會從底層log輸出,標(biāo)識為luatos,等級為error,所以不要把用戶log當(dāng)做error!
luatools捕獲用戶log時(shí),自動識別GB2312還是UTF8編碼,也能正確打印64bit數(shù)據(jù)和浮點(diǎn)數(shù)據(jù)
EPAT只能識別GB2312編碼,不能正確打印64bit和浮點(diǎn)數(shù)據(jù),在用UART0捕獲數(shù)據(jù)時(shí)會丟失部分log,尤其是優(yōu)先級低的,所以用戶log的等級是error,優(yōu)先級高
雙方都是USB口對接的情況下,USB虛擬串口沒有波特率限制,任意選擇,實(shí)際傳輸速率都是一樣的
為啥要區(qū)分用戶log通道和底層log通道,因?yàn)橐菩静婚_放底層log解析方法
csdk固件默認(rèn)死機(jī)后存儲死機(jī)信息到flash后重啟,luatos固件死機(jī)后會存儲死機(jī)信息到flash,然后等EPAT或者luatools抓取死機(jī)信息,等待大約40秒左右會重啟
出現(xiàn)死機(jī)問題分析
A 怎么抓LOG
A1 認(rèn)識USB虛擬串口
由于電腦識別出來串口名字都是一樣的,因此需要從串口屬性上來區(qū)分對應(yīng)功能,具體看下面截圖紅框
A1.1 用戶log通道
A1.2 底層log通道
A1.3 用戶串口通道
A2 抓log
如果使用EPAT工具抓取日志,說明請看 EPAT抓取底層日志文檔
A2.1 USB可用
建議方案1,只用luatools勾選USB打印模式即可,沒有配置上的要求,luatools會自動識別log通道,需底層log的,工具配置--》log--》勾選ap log,luatools會自動識別log通道,底層log保存在log/4gdiag。luatools版本必須在2.2.1及以上
建議方案2,直接用EPAT,按照EPAT手冊操作即可,如果luatools開著,工具配置--》log--》不要勾選ap log
A2.2 USB不可用
只能用EPAT通過DBG_UART抓LOG了,需要6M波特率抓取(USB轉(zhuǎn)TTL工具也要支持6M波特率),如果是AT版本還需要通過發(fā)送以下指令配置
AT+ECPCFG=logCtrl,2 // 輸出全部日志 AT+ECPCFG=logPortSel,1 // 只從DBG_UART串口輸出日志 AT+ECPCFG=logBaudrate,6000000 // 設(shè)置波特率為6M
B 遇到死機(jī)怎么辦
設(shè)置死機(jī)不重啟方法
- AT固件:發(fā)送 AT+ECPCFG="faultAction",0 或者 AT*EXASSERT=1 指令開啟死機(jī)不重啟。
- LuatOS開發(fā):調(diào)用 mcu.hardfault(0) 接口開啟死機(jī)不重啟。
- CSDK開發(fā):在task中執(zhí)行 luat_debug_set_fault_mode(LUAT_DEBUG_FAULT_HANG); 開啟死機(jī)不重啟。
B1 EPAT抓底層log,固件設(shè)置成死機(jī)不重啟
EPAT會自動抓,并且自動彈出ramdump處理界面,按照手冊操作即可。
B2 luatools抓底層log,固件設(shè)置成死機(jī)不重啟
luatools也會自動抓ramdump,但是只能保存成文件,仍然需要用EPAT來手動進(jìn)入處理ramdump界面,后續(xù)處理見B1
B3 固件設(shè)置成死機(jī)重啟,或者沒有工具抓底層log
幫助文檔:無法抓底層log的情況下如何導(dǎo)出死機(jī)dump
C 死機(jī)重啟原因常見情況分析
死機(jī)需要底層log和ramdump處理結(jié)果綜合判斷,luatos固件還要看用戶log,這里討論如何定位出錯(cuò)代碼位置或者出錯(cuò)原因
C1 luavm拋出的異常
這個(gè)看用戶log就行,如果開啟了errdump,還能在iot平臺上看到
C2 斷言死機(jī)
看底層log就可以,搜索EcAssert字樣,可以看到斷言的位置
如果沒有底層log,ramdump里需要看list source的代碼上下是不是調(diào)用了ec_assert_regs,然后在stackframe with local里看看調(diào)用順序,大概率能看到斷言的位置。
斷言死機(jī)如果是malloc失敗,那么就是ram不足了。
C3 內(nèi)存不足
這是最常見的死機(jī)原因,而且9成9可以判斷是內(nèi)存泄露,剩下也有可能malloc時(shí)的參數(shù)不對,申請了不可能申請到的空間大小。內(nèi)存不足直接表現(xiàn),C2中已有部分描述,如果有底層log,還可以從死機(jī)時(shí)打印的信息來判斷
這里表示動態(tài)分配ram時(shí),最大的block只有712字節(jié)了,這是非常典型的內(nèi)存不足引起的死機(jī),正常來說,至少要有個(gè)70KB左右的空間來滿足LTE協(xié)議棧的需求
如果ramdump信息完整,則可以從ramdump里找到查找方向從Ramdump里分析內(nèi)存泄露問題
C4 看門狗死機(jī)
在底層log和ramdump里都能看到,
ramdump里能看到最后停在NMI Handler里。
看門狗死機(jī),要么死循環(huán),要么操作時(shí)間太長,消除死循環(huán),或者主動喂一下狗。壓力測試和RSA運(yùn)算時(shí)特別注意一下。
C5 疑難雜癥
真正遇到hardfault時(shí),需要先從底層日志里看死機(jī)的直接原因,也就是arm內(nèi)核遇到的致命錯(cuò)誤,當(dāng)然多種多樣,常見的地址錯(cuò)誤(常見data access)有數(shù)據(jù)存取時(shí)的總線錯(cuò)誤(常見precise data access,imprecise data access等等),指令錯(cuò)誤(常見switch to an invalid state (e.g., ARM))等等。
以下個(gè)人經(jīng)驗(yàn):
先要排除一下棧溢出的可能,一旦棧溢出,什么奇怪的現(xiàn)象都有可能發(fā)生,運(yùn)氣好的,觸發(fā)斷言,運(yùn)氣不好的,就什么錯(cuò)誤都可能發(fā)生,任務(wù)鏈表都可能被破壞,導(dǎo)致ramdump里的信息都會缺失。
如果ramdump信息完整,則可以從ramdump大致分析出有沒有棧溢出現(xiàn)象從Ramdump里看棧溢出
如果ramdump的信息看起來完整,stackframe with local里調(diào)用順序也比較合理,那么就能定位發(fā)生問題的函數(shù)和語句,后續(xù)就看代碼調(diào)試吧,這是比較理想的情況。
地址錯(cuò)誤的,大概率是讀寫了一個(gè)不可讀寫的地址,但是注意,有時(shí)候非ram和flash地址,直接讀取并不一定會出錯(cuò)。
總線錯(cuò)誤,大概率是數(shù)據(jù)對齊的問題,比如uint32_t *指針,去讀取一個(gè)uint8_t *指針指向的內(nèi)容,一旦uint8_t *指針存放的地址不是32位對齊的,編譯器又沒有對應(yīng)優(yōu)化處理,死機(jī)是很正常的
指令錯(cuò)誤,這種常見的函數(shù)指針用出問題,導(dǎo)致函數(shù)退出時(shí),PC指針已經(jīng)不能指向正確的代碼指令,從而執(zhí)行了非arm的指令
如果ramdump的信息都不完整,底層log也丟完,或者壓根沒法抓,建議通過刪減代碼,加打印語句等方法來定位出錯(cuò)的語句,多次嘗試縮小范圍,直到成功,有經(jīng)驗(yàn),對源碼了解的,能加快這一進(jìn)度。
-
模塊
+關(guān)注
關(guān)注
7文章
2695瀏覽量
47431 -
虛擬串口
+關(guān)注
關(guān)注
3文章
62瀏覽量
13876 -
合宙通信
+關(guān)注
關(guān)注
0文章
147瀏覽量
1737
發(fā)布評論請先 登錄
相關(guān)推薦
評論