1、前言
在嵌入式項(xiàng)目中,我們經(jīng)常會(huì)碰到各種各樣的異常和故障,比如客戶(hù)說(shuō),某個(gè)問(wèn)題可能需要一天,一周,甚至以月為周期才能復(fù)現(xiàn)一次問(wèn)題。諸如此類(lèi)問(wèn)題,著實(shí)令工程師苦惱,因?yàn)楹茈y去捕獲信息來(lái)分析和復(fù)現(xiàn)問(wèn)題,這里給大家分享一些我的經(jīng)驗(yàn)和技巧。
2、方法
我們都知道調(diào)試是非常高效的分析手段,相信大家對(duì)斷點(diǎn)(breakpoint)并不陌生,事實(shí)上,斷點(diǎn)還可以設(shè)置條件的,當(dāng)條件滿(mǎn)足時(shí)再觸發(fā)斷點(diǎn),這對(duì)于分析疑難雜癥非常有用。接下來(lái)我將介紹如何在 STM32CubeIDE 中使用條件斷點(diǎn),以及如何使用觀(guān)察點(diǎn)。
2.1. 斷點(diǎn)/breakpoint
斷點(diǎn)就是當(dāng)程序到達(dá)某個(gè)點(diǎn)時(shí),斷點(diǎn)可使程序暫停運(yùn)行。我們?cè)谡{(diào)試界面先設(shè)置一個(gè)斷點(diǎn),鼠標(biāo)右擊該斷點(diǎn)進(jìn)入斷點(diǎn)的屬性界面。
為了演示,我在斷點(diǎn)的屬性界面中,為斷點(diǎn)增加了一則條件:(*(int *) 0x42020414 ==0x01)&&(hspi1.Init.NSSPMode == 0x40000000)。此處的“0x42020414”就是 GPIOB 的 ODR 寄存器的地址, “0x40000000”就是“SPI_NSS_PULSE_ENABLE”的宏定義,所以該條件的含義是:當(dāng) PB0 輸出高電平時(shí),并且SPI1 的 NSSPMode=SPI_NSS_PULSE_ENABLE 時(shí),觸發(fā)該斷點(diǎn)。
2.2. 觀(guān)察點(diǎn)/watchpoint
與條件斷點(diǎn)稍微不同,觀(guān)察點(diǎn)也是一種特殊的斷點(diǎn),當(dāng)表達(dá)式的值發(fā)生變化時(shí),它會(huì)使程序暫停運(yùn)行。那么如何設(shè)置觀(guān)察點(diǎn)呢?
還是在調(diào)試界面,首先我們?cè)?outline 界面,或者將變量添加到Variables/Expression/LiveExpression 界面,然后找到該變量,右擊選擇“ToggleWatchpoint”。
在之后出現(xiàn)的界面中,設(shè)置觀(guān)察點(diǎn)的屬性。為了演示,我這里設(shè)置了這樣的條件:當(dāng)ret 變量被寫(xiě)入的時(shí)候,并且 ret 的值不等于 2 的時(shí)候,觀(guān)察點(diǎn)生效,如下圖所示。大家還可以根據(jù)需要,勾選上“Read”選項(xiàng),就可以設(shè)置變量在被讀的時(shí)候是否生效,非常的方便實(shí)用。
3、小結(jié)
這些方法在調(diào)試疑難雜癥時(shí)是非常有用的,但是弊端在于,必須連接仿真器進(jìn)入調(diào)試模式。
在 Cortex-M3 以及更高級(jí)的內(nèi)核(如 M4,M33,M7 等)中,對(duì)于不連接調(diào)試器的場(chǎng)景,我們還可以利用 SWV,以及 DWT 等調(diào)試單元來(lái)提前預(yù)埋監(jiān)控程序,實(shí)現(xiàn)對(duì)內(nèi)存/變量,以及函數(shù)的監(jiān)控和調(diào)試。如“LAT1256 使用 STM32 的 DWT 單元監(jiān)控內(nèi)存”提供了類(lèi)似的調(diào)試方法的說(shuō)明。
同樣,我們還可以通過(guò) STM32CubeMonitor 來(lái)實(shí)現(xiàn)非侵入式的監(jiān)控。對(duì)于疑難雜癥,我們的方法是非常多的,大家可以選擇合適的方式來(lái)分析問(wèn)題。