Tickless 具體實現
1、宏 configUSE_TICKLESS_IDLE
要想使用 Tickless 模式,首先必須將 FreeRTOSConfig.h 中的宏 configUSE_TICKLESS_IDLE設置為 1,代碼如下:
#define configUSE_TICKLESS_IDLE 1 //1 啟用低功耗 tickless 模式
2、宏 portSUPPRESS_TICKS_AND_SLEEP()
使能 Tickless 模式以后當下面兩種情況都出現的時候 FreeRTOS 內核就會調用宏portSUPPRESS_TICKS_AND_SLEEP()來處理低功耗相關的工作。
● 空閑任務是唯一可運行的任務,因為其他所有的任務都處于阻塞態或者掛起態。
● 系統處于低功耗模式的時間至少大于 configEXPECTED_IDLE_TIME_BEFORE_SLEEP個時鐘節拍,宏 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 默認在文件 FreeRTOS.h 中定義為 2,我們可以在 FreeRTOSConfig.h 中重新定義,此宏必須大于 2!
portSUPPRESS_TICKS_AND_SLEEP()有個參數,此參數用來指定還有多長時間將有任務進入就緒態,其實就是處理器進入低功耗模式的時長(單位為時鐘節拍數),因為一旦有其他任務 進 入 就 緒 態 處 理 器 就 必 須 退 出 低 功 耗 模 式 去 處 理 這 個 任 務 。portSUPPRESS_TICKS_AND_SLEEP()應該是由用戶根據自己所選擇的平臺來編寫的,此宏會被空閑任務調用來完成具體的低功耗工作。但是!如果使用 STM32 的話編寫這個宏的工作就不用我們來完成了,因為 FreeRTOS 已經幫我們做好了,有沒有瞬間覺得好幸福啊。當然了你也可以自己去重新編寫,不使用 FreeRTOS 提供的 ,如果自己編寫的話需要先將configUSE_TICKLESS_IDLE 設置為 2。宏 portSUPPRESS_TICKS_AND_SLEEP 在文件 portmacro.h 中定義。
3、宏 configPRE_SLEEP_PROCESSING ()和 configPOST_SLEEP_PROCESSING()
在真正的低功耗設計中不僅僅是將處理器設置到低功耗模式就行了,還需要做一些其他的處理,比如:
● 將處理器降低到合適的頻率,因為頻率越低功耗越小,甚至可以在進入低功耗模式以后關閉系統時鐘。
● 修改時鐘源,晶振的功耗肯定比處理器內部的時鐘源高,進入低功耗模式以后可以切換到內部時鐘源,比如 STM32 的內部 RC 振蕩器。
● 關閉其他外設時鐘,比如 IO 口的時鐘。
● 關閉板子上其他功能模塊電源,這個需要在產品硬件設計的時候就要處理好,比如可以通過 MOS 管來控制某個模塊電源的開關,在處理器進入低功耗模式之前關閉這些模塊的電源。
有關產品低功耗設計的方法還有很多,大家可以上網查找一下,上面列舉出的這幾點在處理器進入低功耗模式之前就要完成處理。FreeRTOS 為我們提供了一個宏來完成這些操作,它就是 configPRE_SLEEP_PROCESSING(),這個宏的具體實現內容需要用戶去編寫。如果在進入低功耗模式之前我們降低了處理器頻率、關閉了某些外設時鐘等的話,那在退出低功耗模式以后就 需 要 恢 復 處 理 器 頻 率 、 重 新 打 開 外 設 時 鐘 等 , 這 個 操 作 在 宏configPOST_SLEEP_PROCESSING()中完成,同樣的這個宏的具體內容也需要用戶去編寫。這兩個宏會被函數 vPortSuppressTicksAndSleep()調用,我們可以在 FreeRTOSConfig.h 定義這兩個宏,如下:
/********************************************************************************/
/* FreeRTOS 與低功耗管理相關配置 */
/********************************************************************************/
extern void PreSleepProcessing(uint32_t ulExpectedIdleTime);
extern void PostSleepProcessing(uint32_t ulExpectedIdleTime);
//進入低功耗模式前要做的處理
#define configPRE_SLEEP_PROCESSING PreSleepProcessing
//退出低功耗模式后要做的處理
#define configPOST_SLEEP_PROCESSING PostSleepProcessing
函數 PreSleepProcessing()和 PostSleepProcessing()可以在任意一個 C 文件中編寫,本章對應的例程是在 main.c 文件中,函數的具體內容在下一節詳解。
4、宏 configEXPECTED_IDLE_TIME_BEFORE_SLEEP
處理器工作在低功耗模式的時間雖說沒有任何限制,1 個時鐘節拍也行,滴答定時器所能計時的最大值也行。但是時間太短的話意義也不大啊,就 1 個時鐘節拍,我這剛進去就得出來!所 以 我 們 必 須 對 工 作 在 低 功 耗 模 式 的 時 間 做 個 限 制 , 不 能 太 短 了 , configEXPECTED_IDLE_TIME_BEFORE_SLEEP 就是用來完成這個功能的。此宏默認在文件FreeRTOS 中有定義,如下:
#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
#endif
#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2
#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2
#endif
默認情況下 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 為 2 個時鐘節拍,并且最小不能小于 2 個時鐘節拍。如果要修改這個值的話可以在文件 FreeRTOSConfi.h 中對其重新定義。此宏會在空閑任務函數 prvIdleTask()中使用!
到此為止,FreeRTOS 中低功耗的基礎大家都已經掌握了,可以在自己已經有的代碼中加入此機制,看看功耗是否有降低。使能上面第一個宏定義,然后實現其他三個宏定義即可將低功耗機制加入自己的項目中。
-
嵌入式
+關注
關注
5086文章
19140瀏覽量
305844 -
內核
+關注
關注
3文章
1375瀏覽量
40311 -
FreeRTOS
+關注
關注
12文章
484瀏覽量
62217
發布評論請先 登錄
相關推薦
評論