嵌入式開發輸出調試信息的幾種方法
時間:2023-10-20 來源:華清遠見
一、嵌入式開發為什么需要輸出調試信息?
穩嚴文:因為輸出調試信息是嵌入式開發中一項非常重要的實踐,它有助于保證軟件的可靠性、穩定性和性能,也是故障排查的關鍵工具之一。
白話文:程序猿想知道自己敲的代碼是否正確、是否按照要求運行,但是代碼跑起來看不見、摸不著,那么就可以通過輸出調試信息可以自由看到結果。
嵌入式開發輸出調試信息主要有以下作用:
錯誤排查與問題定位
輸出調試信息可以幫助你在代碼中發現和定位錯誤。當程序出現異常行為或崩潰時,通過查看輸出的調試信息,你可以更容易地找到問題的根本原因, 比如內存泄漏或者越界訪問。通過查找異常條件、變量值、函數調用堆棧等信息,有助于快速定位和解決問題。
實時反饋
在開發過程中逐步增加新功能或者修改現有功能時,輸出調試信息可以提供實時反饋。這使得可以快速地檢查修改的效果。
代碼驗證和邏輯分析
輸出調試信息可用于驗證代碼是否按預期工作。你可以在關鍵代碼段插入打印語句,以監視變量的值和程序的流程,從而確保代碼的邏輯正確性。這有助于提前發現潛在問題,減少后期調試的工作量。
驗證硬件連接
通過輸出與外部設備或模塊的通信信息,可以驗證硬件連接是否正確,是否能夠正確地與外部設備進行通信。
狀態監控
輸出調試信息可以實時監控系統的狀態。這對于嵌入式系統特別有用,你可以實時追蹤傳感器數據、設備狀態、通信狀態等,并在需要時采取相應的措施。
性能分析
輸出調試信息可以幫助你評估程序的性能。你可以測量程序的執行時間,查看代碼路徑是否有效率,以及檢查是否有不必要的延遲。
二、嵌入式開發輸出調試信息常用的幾種方法
通過串口輸出log
這是一種常見的調試方法。可以在STM32微控制器上配置一個UART(串口通信)模塊,將調試信息發送到計算機或者其他設備上,然后在相應的終端軟件(比如串口調試工具)中查看輸出的log信息。
輸出log信息到SRAM
這種方法通常用于在沒有外部調試接口(比如串口)的情況下,將調試信息保存在芯片的內部存儲器中,比如SRAM(Static Random Access Memory)。可以使用類似于sprintf函數的方式將調試信息格式化后寫入SRAM中,然后通過其他手段(例如JTAG/SWD接口)將SRAM中的信息讀取出來進行分析。
通過SWO輸出log
Serial Wire Output (SWO) 是一種用于調試的硬件接口,進行調試信息的輸出。這種方法相對于串口輸出更為靈活,但需要相應的硬件和調試工具的支持。可以在調試器/編程器(如ST-Link)中配置SWO輸出,然后使用調試工具進行連接并查看log信息。SWO可以在不影響CPU執行速度的情況下,以高速輸出調試信息。
三、如何通過串口輸出log?
要通過串口輸出log信息,需要配置STM32的串口模塊并使用相應的庫函數或者驅動程序來發送數據。具體步驟如下:
CubeMX配置
1)啟用 Debug Serial Wire

2)啟用串口USART1

3)啟用ADC的ADC_IN4(PA4引腳作為光照模塊的模擬輸入引腳,用于產生數據)

編寫程序
在代碼中,可以使用類似于C語言標準庫中的printf函數來格式化輸出log信息。
因為要使用printf,所以需要添加stdio.h頭文件,并且為其重定向輸出。
1)添加頭文件

2) 重定向標準輸出(注意:每個MCU的重定向有區別,根據自己的芯片自行配置,將標準輸出重定向至USART的發送數據寄存器,查看自己MCU的手冊自行配置)

3)編寫代碼,定義一個變量接收ADC轉換的值,再將其打印至串口進行調試輸出

終端調試輸出
1)下載并運行代碼
通過IDE將代碼燒錄到STM32芯片上,然后運行。
2)連接串口線
確保你的開發板上已經連接了串口線,一端連接到STM32的相應串口引腳(例如:PA9、PA10),另一端連接到計算機或者其他設備的串口接口(或者通過串口轉USB模塊連接到計算機的USB接口)。
3)用串口調試助手輸出信息

四、如何輸出log信息到SRAM?
要將調試信息輸出到STM32的SRAM(靜態隨機存取存儲器),可以使用類似于sprintf函數將格式化的字符串寫入SRAM中。具體步驟如下:
1. 初始化SRAM
在你的工程中,確保你已經正確初始化了SRAM。通常,SRAM會被映射到特定的地址空間中,你可以使用相應的地址來訪問它。(因為芯片不同,請自行查閱手冊或百度)
2. 使用sprintf函數
在你的代碼中,你可以使用類似于C語言標準庫中的sprintf函數將格式化的字符串寫入一個緩沖區中。例如:
1)先定義一個緩沖區

2)再把格式化后的字符串寫入到buf中

3.將字符串寫入SRAM
使用SRAM的地址,將buf中的內容寫入到SRAM中。可以使用指針或者類似于memcpy的函數來實現。(注意加頭文件 #include <string.h> )代碼如下:

注意:SRAM的具體地址和大小取決于你的STM32型號和硬件配置,需要根據具體情況進行相應的調整(可在Keil IDE中點擊Books跳轉查找),在STM32F051中SRAM的起始地址為0x20000000。

4. 讀取SRAM中的信息
在需要查看log信息的時候,您可以從SRAM的地址中讀取信息并輸出到串口或者其他輸出設備上。(這里,我們直接輸出到串口)


當然,也可以在IDE的中用Debug進行查看


這種方法的好處是,即使你的STM32芯片上沒有外部調試接口(如串口),仍然可以在設備上保存和查看調試信息。但請注意,SRAM是易失性內存,斷電后信息會丟失,因此只適用于臨時調試目的。
如何通過SWO輸出log?
溫馨小TOP
名詞解釋:
SWD:串行線調試(Serial Wire Debug)
SWO:串行線輸出(Serial Wire Output)
SWV:串行線查看器(Serial Wire Viewer)
ITM:指令跟蹤宏單元(Instrumentation Trace Macrocell)
關于SWO和ITM
SWO串行線輸出是單引腳、異步串行通信,可在Cortex-M3/M4/M7上使用,并由主調試器探測支持。
它是利用Cortex內核中ITM模塊來實現此功能。連接引腳如下所示:

SWO輸出,需要一根SWO(引腳)線,同時需要借助SWV(查看器)查看數據。
ITM 的一個主要用途,就是支持調試消息的輸出(如printf 格式的輸出)。ITM 包含 32 個刺激(Stimulus)端口,允許不同的軟件把數據輸出到不同的端口,從而讓調試主機可以把它們的消息分離開。 和基于 UART 的文字輸出不同,使用 ITM 輸出不會對應用程序造成很大的延遲,在 ITM 內部有一個 FIFO,它使寫入的輸出消息得到緩沖。
SWO引腳配置
SWO引腳可以理解為UART的Tx引腳,如果不連接此引腳,則(SWV)終端不會接收打印信息。
對于STM32而言,只要是Cortex-M3/M4/M7內核的MCU都有SWO引腳。
而Cortex-M0則沒有此項功能,包含STM32F0、STM32L0和STM32G0等。
在STM32CubeMX工具中,Debug選項進行如下配置即可。
(注意:此處使用的是最常用的芯片STM32F103C8T6)

4.ITM發送源碼
此方法和前面UART實現printf打印輸出區別就是:將重定義代碼中UART發送字符,改為ITM發送字符。


Keil SWO輸出配置
點擊魔術棒——>點擊Debug——>點擊Settings

注意:Clock和ITM STimulus Ports根據情況自行設置

5.輸出調試
這里使用Debug(printf)Viewer輸出調試信息,當然,還有其他方法(比如:基于IAR的Terminal IO 、基于ST-LINK Utility的Serial Wire Viewer、基于J-Link的SWO Viewer)。 直接點擊Debug,按照以下步驟操作:

點擊運行即可看到調試輸出的結果

六、優缺點總結
1、通過串口輸出log
優點:
易于實現:串口通信是一種相對簡單的通信方式,適用于大多數STM32微控制器。
實時性:可以實時輸出信息,便于實時監控設備狀態。
穩定性:穩定可靠,通常不容易出現干擾或錯誤。
缺點:
占用硬件資源:需要占用一個UART模塊,如果需要同時使用多個UART模塊,資源分配可能會成為問題。
物理連接:需要連接物理的串口線,有時需要繁瑣的線路布線。
有線連接:通常需要連接到計算機或者其他設備,不適用于遠程調試。
2、輸出log信息到SRAM
優點:
適用于無外部接口:當設備沒有外部調試接口時,這是一種有效的調試手段。
低成本:不需要額外的硬件,僅需要一個可用的SRAM。
缺點:
臨時性:SRAM是易失性內存,斷電后信息會丟失,只適用于臨時調試目的。
需要額外的代碼:需要編寫代碼將信息寫入SRAM,增加了開發工作量。
不適用于遠程調試:無法將信息傳輸到遠程地點,只適用于本地調試。
3、通過SWO輸出log
優點:
靈活性:SWO接口提供了一種靈活的調試方法,可以用于實時調試和性能分析。
無需額外硬件:只需要一個支持SWO的調試器/編程器,無需額外的硬件設備。
適用于遠程調試:可以通過SWD接口進行遠程調試。
缺點:
相對復雜:相對于串口輸出,SWO輸出的配置和使用可能需要更多的設置和調試工作。
需要支持SWO的硬件:不是所有的STM32開發板和調試器都支持SWO功能。
注意:每種方法都有其適用的場景,要根據具體的項目需求、硬件資源和調試環境,選擇合適的輸出調試信息的方法。有時候也可以根據實際情況結合多種方法,以獲取更全面的調試信息。

