<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 斷言不是錯誤!

斷言不是錯誤!

發(fā)布人:魚(yú)鷹談單片機 時(shí)間:2022-01-21 來(lái)源:工程師 發(fā)布文章

斷言機制估計很多道友都用過(guò),在 ST 的標準庫中,經(jīng)??梢钥吹剿纳碛埃?/p>

1.png

它的實(shí)現方式也是非常簡(jiǎn)單的,就是通過(guò) USE_FULL_ASSERT 宏進(jìn)行控制:

2.png

如果斷言失敗,就會(huì )執行 assert_failed 函數,一般實(shí)現函數如下:

void assert_failed (uint8_t* file, uint32_t line)

{

  static char buff[128];  

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

  __breakpoint(0);

}

當然這里的 sprintf 函數也常常使用 printf 代替,這樣就可以直接通過(guò)串口打印出來(lái)了,而魚(yú)鷹這個(gè)在沒(méi)有串口的情況下,可以通過(guò)內存 buff 顯示出來(lái),比較方便在線(xiàn)調試。

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

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

而這是設計者希望看到的,但有些開(kāi)發(fā)者認為不應該這樣,因為程序一旦死循環(huán),如果開(kāi)啟了看門(mén)狗,會(huì )導致整個(gè)程序復位,對于產(chǎn)品而言,復位是很?chē)乐氐?BUG 。

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

不可以。

斷言本身不是錯誤,它只是發(fā)現你程序的 BUG ,進(jìn)而提醒你。

斷言失敗,往往是很?chē)乐氐膯?wèn)題,嚴重到這段代碼或功能無(wú)法正常執行,所以你修改的地方應該是調用者,而不是產(chǎn)生斷言的代碼,請不要顛倒主次,否則沒(méi)有從根本上解決問(wèn)題。

就比如最上面的 GPIO 外設指針檢查斷言部分,如果調用者傳入一個(gè)非 GPIO 的指針進(jìn)入函數,從而產(chǎn)生斷言失敗,那么你會(huì )選擇關(guān)閉斷言機制還是說(shuō)檢查你的代碼是否存在問(wèn)題呢?

當然是后者。

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

*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: 單片機

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>