博客專欄

        EEPW首頁 > 博客 > 斷言不是錯誤!

        斷言不是錯誤!

        發布人:魚鷹談單片機 時間:2022-01-21 來源:工程師 發布文章

        斷言機制估計很多道友都用過,在 ST 的標準庫中,經常可以看到它的身影:

        1.png

        它的實現方式也是非常簡單的,就是通過 USE_FULL_ASSERT 宏進行控制:

        2.png

        如果斷言失敗,就會執行 assert_failed 函數,一般實現函數如下:

        void assert_failed (uint8_t* file, uint32_t line)

        {

          static char buff[128];  

          sprintf (buff,"%s,%d", file, line);

          __breakpoint(0);

        }

        當然這里的 sprintf 函數也常常使用 printf 代替,這樣就可以直接通過串口打印出來了,而魚鷹這個在沒有串口的情況下,可以通過內存 buff 顯示出來,比較方便在線調試。

        而 __breakpoint(0) 一般由死循環 while(1) 代替,而魚鷹覺得 while(1) 不夠好,因為斷言失敗后,可能很久你才能發現而進入該死循環,而使用  __breakpoint 可以讓你在 在線調試 模式下,立刻停止程序運行,從而可以快速定位問題。

        不管哪種實現方式,斷言失敗的結果一般只有暫停程序了,類似 linux 內核的 panic 。

        而這是設計者希望看到的,但有些開發者認為不應該這樣,因為程序一旦死循環,如果開啟了看門狗,會導致整個程序復位,對于產品而言,復位是很嚴重的 BUG 。

        “我不希望我的產品復位,所以請修改你的代碼,不讓他產生斷言失敗,可以嗎?”

        不可以。

        斷言本身不是錯誤,它只是發現你程序的 BUG ,進而提醒你。

        斷言失敗,往往是很嚴重的問題,嚴重到這段代碼或功能無法正常執行,所以你修改的地方應該是調用者,而不是產生斷言的代碼,請不要顛倒主次,否則沒有從根本上解決問題。

        就比如最上面的 GPIO 外設指針檢查斷言部分,如果調用者傳入一個非 GPIO 的指針進入函數,從而產生斷言失敗,那么你會選擇關閉斷言機制還是說檢查你的代碼是否存在問題呢?

        當然是后者。

        所以,如果產生了斷言失敗的情況,請不要慌,不要認為這是一種錯誤,而應該根據斷言失敗的位置,定位斷言失敗的根本原因,而不是試圖通過關閉斷言的方式讓程序繼續運行下去,這只會讓你的程序運行得更糟糕,同時也更難定位問題。

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



        關鍵詞: 單片機

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 宝坻区| 靖州| 藁城市| 无棣县| 城固县| 永川市| 宁武县| 从化市| 澎湖县| 奉贤区| 越西县| 黄大仙区| 文水县| 宜黄县| 宁德市| 岳阳市| 宝丰县| 汝州市| 嫩江县| 开化县| 宁安市| 浙江省| 容城县| 大丰市| 五原县| 米林县| 新建县| 兴海县| 道孚县| 长春市| 梁河县| 巴彦县| 吉首市| 龙胜| 上虞市| 福泉市| 井陉县| 崇义县| 中山市| 乐都县| 横山县|