MCU開發(fā)利器:調(diào)試系統(tǒng)之UART
搞MCU軟件開發(fā)的同學(xué),對于調(diào)試,并不陌生。開發(fā)階段,大家使用最多的調(diào)試手段:在調(diào)試器(eg:lauterbach)中,設(shè)置斷點(diǎn)(Breakpoint),通過程序進(jìn)入斷點(diǎn)的方式確認(rèn)問題。但是,此方式畢竟有其局限性,eg:
本文引用地址:http://m.butianyuan.cn/article/202308/450092.htm非開發(fā)人員(eg:測試人員)不能或者沒有條件通過此方式進(jìn)行程序調(diào)試;
車輛量產(chǎn)后,出現(xiàn)bug時(shí),無法連接調(diào)試器,不能獲取問題發(fā)生時(shí)的車輛工況信息
......
所以,談到解決bug,我們就需要思考不同階段的不同調(diào)試策略。本文聚焦UART(universal asynchronous receiver transmitter,通用異步收發(fā)器)調(diào)試系統(tǒng)。
關(guān)于調(diào)試(Debug),在Autosar規(guī)范中,也給出了多個(gè)調(diào)試模塊,比如:
DET(Default ErrorTracer)系統(tǒng),此模塊側(cè)重檢查BSW(Basic Software)模塊開發(fā)和運(yùn)行時(shí)的錯(cuò)誤,并不能將錯(cuò)誤信息以緩存的方式輸出。
DLT(Diagnostic Log and Trace)系統(tǒng),此模塊可以將SW-Cs、BSW、RTE、Det以及Dem記錄的信息,以Message的形式通過外部接口輸出,如此,即可利用外部的上位機(jī)監(jiān)控程序的運(yùn)行狀態(tài),或者將MCU運(yùn)行的時(shí)時(shí)狀態(tài)存儲(chǔ)下來,以便后續(xù)bug問題分析。
DLT與DET的關(guān)系如下所示:
車輛量產(chǎn)后的問題,相比于DET,DLT更適合,這類似于Linux等系統(tǒng)的日志系統(tǒng),可以將程序運(yùn)行的時(shí)時(shí)狀態(tài)記錄下來,以便于出現(xiàn)問題時(shí),確認(rèn)問題原因。本文所討論的UART調(diào)試系統(tǒng)類似DLT,但是,相對于DLT,更輕量化,自由度也更大。
1、UART調(diào)試系統(tǒng)
UART調(diào)試系統(tǒng),故名思意,就是利用串口功能,將log信息輸出給上位機(jī),示意如下所示:
(一)為什么要log系統(tǒng)?
如文章開篇提到的問題:車輛量產(chǎn)以后,出現(xiàn)bug問題時(shí),無法使用調(diào)試器進(jìn)行調(diào)試,同時(shí),受限于DEM模塊記錄故障信息的能力,無法通過NVM存儲(chǔ)的有限數(shù)據(jù)確認(rèn)車輛問題時(shí)的運(yùn)行工況,比如:網(wǎng)絡(luò)狀態(tài)、某些模塊局部變量狀態(tài)等。如果能像飛機(jī)黑匣子一樣,將問題車運(yùn)行的日志記錄下來,通過DTC信息(快照數(shù)據(jù)、拓展數(shù)據(jù))+日志信息即可最大程度的還原車輛故障時(shí)工況,進(jìn)而有效確認(rèn)問題原因。
(二)UART調(diào)試系統(tǒng)
在MCU上使用調(diào)試系統(tǒng),需要構(gòu)造一個(gè)類似PC端的Printf接口,也就是重定向功能。利用MCU具有的外設(shè),設(shè)計(jì)一個(gè)輸出系統(tǒng),而UART是最常用的外設(shè)。關(guān)于UART調(diào)試系統(tǒng),網(wǎng)上資源很多,本文不過多講解,文末給出一個(gè)源碼鏈接。
2、利用UART系統(tǒng)進(jìn)行MCU程序調(diào)試
本文分享的UART調(diào)試系統(tǒng)來自Lwip,玩Lwip系統(tǒng)的同學(xué)應(yīng)該比較熟悉。使用Lwip調(diào)試系統(tǒng)注意點(diǎn):
(一)參數(shù)配置
在debug.h文件中,定義了一個(gè)宏:LWIP_DEBUGF,此宏引用了Ifx_Lwip_printf接口,如下所示:
而Ifx_Lwip_printf接口封裝了串口發(fā)送接口(sendUARTMessage),如下所示:
s8_tIfx_Lwip_printf(constchar*format, ...){#ifdef__LWIP_DEBUG__charstr[MAXCHARS + 4];s8_tresult = ERR_CONN;
va_list args;va_start(args, format);vsnprintf(str, MAXCHARS, format, args);va_end(args);{Ifx_SizeT cnt = 0;while(str[cnt]!=0)cnt++;sendUARTMessage(str, cnt);sendUARTMessage("rn", 2);}#endifreturnresult;}
使用調(diào)試系統(tǒng)時(shí),需要使能Debug開關(guān),第一個(gè)參數(shù)需要設(shè)置狀態(tài)和層級(jí),參數(shù)配置示意如下:
TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE。如下所示:
TCP_DEBUG使能需要在opt.h文件中配置,如下所示:
/*** TCP_INPUT_DEBUG:Enable debugging in tcp_in.c for incoming debug.*/#if!defined TCP_INPUT_DEBUG || defined __DOXYGEN__#defineTCP_INPUT_DEBUG LWIP_DBG_ON#endif
(二)串口上位機(jī)輸出信息
在程序任意需要輸出信息的位置,添加LWIP_DEBUGF語句,輸出的調(diào)試信息如下所示:
如上的信息流就類似黑匣子信息,可以根據(jù)開發(fā)人員或者架構(gòu)意圖,預(yù)埋一些關(guān)鍵信息,以便于后期的排查。
當(dāng)然,凡是有利有弊,雖然這樣的調(diào)試系統(tǒng),可以很方便的增加調(diào)試信息,對開發(fā)人員友好(個(gè)人很喜歡這樣的調(diào)試系統(tǒng)),但是,增加這樣的調(diào)試系統(tǒng)需要消耗軟/硬件資源。
硬件:意味著需要增加一個(gè)用于調(diào)試的串口UART,也可以使用其他外設(shè),eg:Ethernet。log系統(tǒng)需要緩存信息,因此需要消耗一塊物理存儲(chǔ)空間,對于MCU這種內(nèi)存資源有限的單片機(jī),一般需要把信息傳遞給車機(jī)或者中控這類資源豐富的控制器。舉例:MCU將log信息傳遞給HUD(Head Up Display,抬頭顯示器),log信息由HUD存儲(chǔ),之后通過對應(yīng)總線將信息輸出給外部上位機(jī),示意如下:
軟件:增加一個(gè)調(diào)試模塊,本身就需要增加對應(yīng)的軟件,消耗部分資源。同時(shí),由于軟件模塊的增加,也會(huì)增加部分CPU負(fù)擔(dān),如果調(diào)試信息過多,會(huì)進(jìn)一步加重CPU負(fù)擔(dān)。所以,這里就需要考慮增加多大的CPU開銷是系統(tǒng)所能承受的。
2、Lwip UART調(diào)試系統(tǒng)源碼
本文源碼鏈接:
https://github.com/Kaixinguo2021/TC397_Tasking_UART_Logging.git
評(píng)論