博客專欄

        EEPW首頁 > 博客 > 傳說中的軟件斷點到底是什么?

        傳說中的軟件斷點到底是什么?

        發布人:魚鷹談單片機 時間:2021-06-03 來源:工程師 發布文章

        不知道道友是否有這樣的經歷,代碼全速運行的時候,等了很久發現并沒有得到想要的結果,然后暫停之后發現程序死在了循環里面,或者斷言里面。

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

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

        但是我們知道,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 平臺,其他平臺自行研究


        注意,剛下載程序時判斷也會成立,必須斷開調試器后再上電才可退出調試模式(或者其他方式退出調試模式)


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞: 程序

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 望都县| 江阴市| 霞浦县| 海晏县| 务川| 安丘市| 扶风县| 东港市| 长葛市| 伽师县| 昌邑市| 舞阳县| 化州市| 甘孜县| 克东县| 庐江县| 仙游县| 吉安市| 武平县| 安溪县| 泽州县| 甘泉县| 灵台县| 东城区| 措美县| 兖州市| 长乐市| 巴林右旗| 巴马| 中方县| 襄汾县| 左权县| 蓬莱市| 三门县| 山阴县| 建宁县| 红原县| 盐池县| 阿巴嘎旗| 兰西县| 威远县|