件斷點到底是什麼?

roc_guo發表於2021-06-16

傳說中的軟體斷點到底是什麼?
所以,軟體斷點到底是什麼?所以,軟體斷點到底是什麼?
不知道道友是否有這樣的經歷,程式碼全速執行的時候,等了很久發現並沒有得到想要的結果,然後暫停之後發現程式死在了迴圈裡面,或者斷言裡面。

那麼我們是否有辦法在程式斷言失敗的時候,讓程式自動停下來呢?而不是苦苦等待結果呢?

如果用常規的方法,肯定是在斷言裡面加入斷點,只要斷言失敗,那麼程式自然就停下來了。

但是我們知道,KEIL 加入斷點後有可能在再次開啟工程後消失,而且STM32微控制器支援的斷點數量也有限,有沒有好的方法?

有的,就是軟體斷點。

你可以在需要停止CPU執行的程式碼中加入這條語句:

__breakpoint(0);  //後面的立即數不怎麼重要

這樣,當你的程式斷言失敗了之後,如果執行到這條語句,線上除錯模式下就會自動停止微控制器執行(如果不在線上除錯模式,也會進入停止執行,所以需要後面的最佳化方案)。

比如 hardfault 錯誤很難查,但是你可以在進入這個中斷後,立刻執行一條彙編軟體斷點程式碼:

BKPT  0

或者直接在中斷處理函式中加入程式碼:

void HardFault_Handler(void) 
{ 
    __breakpoint(0); 
}

這樣一來,一旦執行到這個函式,微控制器就會馬上自動停止執行,而且你還可以透過 stack 視窗檢視是從哪裡跳進這個函式的,這樣就能快速定位這種錯誤了!

只有在滿足條件下,才會在你設定斷點位置自動停止在斷點處。比如一個條件下,會導致整個程式出問題,那麼你可以在應用程式中新增程式碼,讓其在滿足條件時自動停止執行(前提是處於線上除錯,否則沒有任何列印資訊的情況下停止執行是很麻煩的事情)。

但有的時候,我只想讓軟體斷點在進入除錯模式時生效,正常執行時不產生軟體斷點,又該如何處理;換句話說,如何判斷微控制器處於除錯模式還是正常模式。

C 語言版

if(*((uint32_t*)0xE000EDF0) & 0x00000001) // 判斷是否工作在除錯模式 
{ 
    __breakpoint(0); 
} 
彙編版
DEMCR          EQU     0xE000EDF0 
 
            LDR     r0, =DEMCR 
            LDR     r0,[r0,#0x00] 
            AND     r0,r0,#0x00000001 
            CBZ     r0,no_debug 
            BKPT    0 
no_debug  ; 地址標籤

適用於 STM32f1x or Cortex-M3/M4 平臺,其他平臺自行研究

注意,剛下載程式時判斷也會成立,必須斷開偵錯程式後再上電才可退出除錯模式(或者其他方式退出除錯模式)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2776850/,如需轉載,請註明出處,否則將追究法律責任。

相關文章