FreeRTOS 系統(tǒng)時(shí)鐘節(jié)拍和時(shí)間管理
1?時(shí)鐘節(jié)拍
????時(shí)鐘節(jié)拍是特定的周期性中斷,這個(gè)中斷可以看做是系統(tǒng)心跳。中斷之間的時(shí)間間隔取決于不同的應(yīng)用,一般是 1ms – 100ms。時(shí)鐘的節(jié)拍中斷使得內(nèi)核可以將任務(wù)延遲若干個(gè)時(shí)鐘節(jié)拍,以及當(dāng)任務(wù)等待事件發(fā)生時(shí),提供等待超時(shí)等依據(jù)。時(shí)鐘節(jié)拍率越快,系統(tǒng)的額外開(kāi)銷(xiāo)就越大。
????FreeRTOS 的系統(tǒng)時(shí)鐘節(jié)拍可以在配置文件 FreeRTOSConfig.h 里面設(shè)置:
#define configTICK_RATE_HZ ????( ( TickType_t ) 1000 )?
????如上所示的宏定義配置表示系統(tǒng)時(shí)鐘節(jié)拍是 1KHz,即 1ms.
2?時(shí)間管理
????1 時(shí)間延遲
????FreeRTOS 中的時(shí)間延遲函數(shù)主要有以下兩個(gè)作用:
????◆ 為周期性執(zhí)行的任務(wù)提供延遲。
????◆ 對(duì)于搶占式調(diào)度器,讓高優(yōu)先級(jí)任務(wù)可以通過(guò)時(shí)間延遲函數(shù)釋放 CPU 使用權(quán),從而讓低優(yōu)先級(jí)任務(wù)可以得到執(zhí)行
下面我們通過(guò)如下的框圖來(lái)說(shuō)明一下延遲函數(shù)對(duì)任務(wù)運(yùn)行狀態(tài)的影響

運(yùn)行條件:
◆ 僅對(duì)任務(wù) Task1 的運(yùn)行狀態(tài)做說(shuō)明。
◆ 調(diào)度器支持時(shí)間片調(diào)度和搶占式調(diào)度。?
運(yùn)行過(guò)程描述如下:
◆ 起初任務(wù) Task1 處于運(yùn)行態(tài),調(diào)用 vTaskDelay 函數(shù)后進(jìn)入到阻塞狀態(tài).
◆ vTaskDelay 函數(shù)設(shè)置的延遲時(shí)間到,由于任務(wù) Task1 不是當(dāng)前就緒的最高優(yōu)先級(jí)任務(wù),所以不能進(jìn)入到運(yùn)行狀態(tài),只能進(jìn)入到就緒狀態(tài),也就是 ready 狀態(tài)。
◆ 一段時(shí)間后,調(diào)度器發(fā)現(xiàn)任務(wù) Task1 是當(dāng)前就緒的最高優(yōu)先級(jí)任務(wù),從而任務(wù)從就緒態(tài)切換到運(yùn)行態(tài)。
◆ 由于時(shí)間片調(diào)度,任務(wù) Task1 由運(yùn)行態(tài)切換到就緒態(tài)。 上面就是一個(gè)簡(jiǎn)單的任務(wù)運(yùn)行狀態(tài)的切換過(guò)程。
????2 FreeRTOS 的時(shí)間相關(guān)函數(shù)????
????FreeRTOS 時(shí)間相關(guān)的函數(shù)主要有以下 4 個(gè):
????◆ vTaskDelay ()?
????◆ vTaskDelayUntil ()?
????◆ xTaskGetTickCount()?
????◆ xTaskGetTickCountFromISR()
◆ 參數(shù) xTicksToDelay 用于設(shè)置延遲的時(shí)鐘節(jié)拍個(gè)數(shù),范圍 1- 0xFFFFFFFF。
延遲時(shí)間的最大值在 portmacro.h 文件里面有定義:
typedef uint32_t TickType_t;?
#define portMAX_DELAY ( TickType_t )0xffffffffUL?
即延遲時(shí)間的范圍是:1- 0xFFFFFFFF
xTaskGetTickCount 用于獲取系統(tǒng)當(dāng)前運(yùn)行的時(shí)鐘節(jié)拍數(shù)。
使用這個(gè)函數(shù)要注意以下問(wèn)題:?
1. 此函數(shù)用于在任務(wù)代碼里面調(diào)用,如果在中斷服務(wù)程序里面調(diào)用的話,需要使用函數(shù) xTaskGetTickCountFromISR,這兩個(gè)函數(shù)切不可混用
xTaskGetTickCountFromISR 用于獲取系統(tǒng)當(dāng)前運(yùn)行的時(shí)鐘節(jié)拍數(shù)。
使用這個(gè)函數(shù)要注意以下問(wèn)題:?
1. 此函數(shù)用于在中斷服務(wù)程序里面調(diào)用,如果在任務(wù)里面調(diào)用的話,需要使用函數(shù) xTaskGetTickCount, 這兩個(gè)函數(shù)切不可混用。
函數(shù) vTaskDelayUntil 用于周期性延遲。?
◆ 第 1 個(gè)參數(shù),存儲(chǔ)任務(wù)上次處于非阻塞狀態(tài)時(shí)刻的變量地址。
◆ 第 2 個(gè)參數(shù),周期性延遲時(shí)間。
使用這個(gè)函數(shù)要注意以下問(wèn)題:?
1. 使用此函數(shù)需要在 FreeRTOSConfig.h 配置文件中配置如下宏定義為 1
#define INCLUDE_vTaskDelayUntil ????1
函數(shù) vTaskDelayUntil 實(shí)現(xiàn)的是周期性延遲,而函數(shù) vTaskDelay 實(shí)現(xiàn)的是相對(duì)性延遲,反映到實(shí)際應(yīng)用上有什么區(qū)別呢?
運(yùn)行條件:
◆ 有一個(gè) bsp?函數(shù),這個(gè)函數(shù)處理時(shí)間大概耗時(shí) 2ms。
◆ 有兩個(gè)任務(wù),一個(gè)任務(wù) Task1 是用的 vTaskDelay 延遲,延遲 10ms,另一個(gè)任務(wù) Task2 是用的 vTaskDelayUntil 延遲,延遲 10ms。?
◆ 不考慮任務(wù)被搶占而造成的影響
◆ Task1:
????bsp+ vTaskDelay (10)????????????????? ? ?---> ????????????bsp?+ vTaskDelay (10)?
|----2ms + 10ms 為一個(gè)周期------| ????????????????????????|----2ms + 10ms 為一個(gè)周期----|
◆ Task2:
????????????bsp?+ vTaskDelayUntil ?????????????????????????? ? --------->???????? bsp?+ vTaskDelayUntil?
|----10ms 為一個(gè)周期(2ms 包含在 10ms 內(nèi))---|????????????? ??? |----10ms 為一個(gè)周期------|
使用:
用vTaskDelay實(shí)現(xiàn)vTaskDelayUntil():