背景介紹
FreeRTOS 以其移植方便,高度可定制,footprint 小,使其在嵌入式操作系統中的份額不容小覷! 尤以免費 license,頗受開發者青睞。
問題描述
客戶在基于cortex-m3的平臺上使用FreeRTOS系統提供的定時器功能時,意外發現定時器的精確度不夠高。譬如,設置1秒鐘的定時器,理論上1秒超時,并且執行相應的回調函數。但是調試卻發現,有時回調函數是在1.4秒后被執行!這對于精度要求較高的實時系統,是不能接受的!
問題復現與分析
首先在stm32f407-discovery平臺移植FreeRTOS,并創建一個定時器,在其回調函數里toggle led燈,并測量被執行的時間。鑒于FreeRTOS是一個多任務可搶占式系統,這個問題需要在多種情況下分析。
Case 1 :
單任務,即系統里僅有timertask和idle task。整個系統最高優先級為4,Timer task的優先級為默認優先級2。
在這種環境下,回調函數能精確的以1秒的時長超時執行回調函數。雖然此刻精度能滿足要求,但是實際的系統一般會包含多個task。
以下為測試的日志,顯而易見,該定時器嚴格1秒鐘超時。
expired 1000
expired 2000
expired 3000
expired 4000
expired 5000
expired 6000
…
Case 2 :
多任務,即系統里不僅有timertask和idle task,還有用戶創建的task。整個系統最高優先級為4,Timer task的優先級為默認優先級2。
以下為測試的日志。
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 1000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 3000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 4000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 5000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 6000
…
此時定時器回調函數有時能準確地被調度執行,有時則偏差較大,與期望值整整延遲了1秒鐘。
Case 3 :
多任務,即系統里不僅有timer task和idle task,還有用戶創建的task。整個系統最高優先級為4,Timertask的優先級為默認優先級4。這樣設置優先級,是希望能通過將timer task設置為最高優先級,以期望調度器能優先調度執行timer task。
以下為實測的日志。
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 1000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 3000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 4000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 5000
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
UART Printf Example:retarget the C library printf function to the UART
expired 6000
…
雖然調整了timertask的優先級至最高,但是依然會出現嚴重的偏差。
解決方案
考慮到FreeRTOS定時器的精準性不高,建議客戶使用SysTick或者MCU的外設硬件定時器。 重要通知 - 請仔細閱讀
意法半導體公司及其子公司(“ST”)保留隨時對ST 產品和/ 或本文檔進行變更、更正、增強、修改和改進的權利,恕不另行通知。買方訂貨之前應獲取關于ST 產品的最新信息。ST 產品的銷售依照訂單確認時的相關ST 銷售條款。 買方自行負責對ST 產品的選擇和使用, ST 概不承擔與應用協助或買方產品設計相關的任何責任。
ST 不對任何知識產權進行任何明示或默示的授權或許可。
轉售的ST 產品如有不同于此處提供的信息的規定,將導致ST 針對該產品授予的任何保證失效。
ST 和ST 徽標是ST 的商標。所有其他產品或服務名稱均為其各自所有者的財產。
本文檔中的信息取代本文檔所有早期版本中提供的信息。
文章來源:微信公眾號 融創芯城(一站式電子元器件、PCB、PCBA購買服務平臺,項目眾包平臺)