首頁>技術>

前言:前面陸續寫了4篇【微控制器裸機程式碼框架設計思路】,有些細心的讀者發現了存在小bug,

所以特地補充了一篇來說明bug的原因以及解決方案

bug現象:當g_task_ticks在定時器中斷函式中自增,當超過65535之後,就一定會溢位變成了0.

此時就會出現一直執行該任務,而不會按照定時週期來。

我舉例說明如下:

假如當g_task_ticks =65530, g_task_ticks>timeout時,會執行一次該任務,同時timeout會重新賦值成65530+500=494,那麼下一個輪迴,g_task_ticks=65531 > 494,任務又會被執行,這個時候就異常了,無法做到定時500個心跳來執行一次任務。

實際我模擬效果如下,可以看到此bug現象,在g_task_ticks快要溢位之前的那一段,任務被一直執行,根本不會按照預期設定的定時時間來。

解決方案:當前獲取的g_task_ticks減去上次執行該任務時的backupTicks值,如果大於定時時間timeout,那麼就執行該任務。

模擬結果如下:

思考一下:為何這種寫法,就不會有bug呢?

舉例說明:假設此時g_task_ticks=65530,此時滿足定時條件,那麼

backupTicks=65530,同時執行一次該任務,當g_task_ticks還是會繼續自增,當超過65535時,就會出現0 - 65530 > 500 這樣的判斷條件,那這個條件非常關鍵,那麼0-65530 實際上是負數嗎?不是的,因為我們定義的都是unsigned int,所以這個0 - 65530 實際上等同於65536 - 65530 = 6, 6 >500 為假,就不會被執行了,

如上塗顏色部分,很難理解,這個涉及到計算機儲存數值的基礎知識。

首先:0-65530= -65530,這個數字在記憶體中二進位制如何表示呢,用計算器可以幫助我們,可以看出紅色的框框,是表示-65530的,而實際上我們的變數只有32位,那麼我們擷取綠色的部分,仔細瞧一瞧,果真是6,!終於找到答案了。

如果你還不會理解,請假設g_task_ticks是1個位元組,用手仔細推導試試看吧,推導過程截圖如下

7
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 嚐鮮 Vue3.0+Vite 自定義導航欄+彈窗元件