任務(wù)調(diào)度—搶占式,時(shí)間片和合作式
將介紹 FreeRTOS 操作系統(tǒng)支持的任務(wù)調(diào)度方式:搶占式,時(shí)間片和合作式
1 關(guān)于合作式調(diào)度器的特別說(shuō)明?
????????合作式調(diào)度主要用在資源有限的設(shè)備上面,現(xiàn)在已經(jīng)很少使用了。出于這個(gè)原因,后面的?FreeRTOS 版本中不會(huì)將合作式調(diào)度刪除掉,但也不會(huì)再進(jìn)行升級(jí)了。
2 FreeRTOS 支持的調(diào)度方式?
????FreeRTOS 操作系統(tǒng)支持三種調(diào)度方式:搶占式調(diào)度,時(shí)間片調(diào)度和合作式調(diào)度。實(shí)際應(yīng)用主要是搶占式調(diào)度和時(shí)間片調(diào)度,合作式調(diào)度用到的很少。
◆ 搶占式調(diào)度?
????每個(gè)任務(wù)都有不同的優(yōu)先級(jí),任務(wù)會(huì)一直運(yùn)行直到被高優(yōu)先級(jí)任務(wù)搶占或者遇到阻塞式的 API 函數(shù), 比如 vTaskDelay。
◆ 時(shí)間片調(diào)度?
????每個(gè)任務(wù)都有相同的優(yōu)先級(jí),任務(wù)會(huì)運(yùn)行固定的時(shí)間片個(gè)數(shù)或者遇到阻塞式的 API 函數(shù),比如 vTaskDelay,才會(huì)執(zhí)行同優(yōu)先級(jí)任務(wù)之間的任務(wù)切換。
3 什么是調(diào)度器?
調(diào)度器就是使用相關(guān)的調(diào)度算法來(lái)決定當(dāng)前需要執(zhí)行的任務(wù)
????◆ 調(diào)度器可以區(qū)分就緒態(tài)任務(wù)和掛起任務(wù)(由于延遲,信號(hào)量等待,郵箱等待,事件組等待等原因而使得任務(wù)被掛起)。
????◆ 調(diào)度器可以選擇就緒態(tài)中的一個(gè)任務(wù),然后激活它(通過(guò)執(zhí)行這個(gè)任務(wù))。當(dāng)前正在執(zhí)行的任務(wù)是運(yùn)行態(tài)的任務(wù)。?
????◆ 不同調(diào)度器之間最大的區(qū)別就是如何分配就緒態(tài)任務(wù)間的完成時(shí)間。
????嵌入式實(shí)時(shí)操作系統(tǒng)的核心就是調(diào)度器和任務(wù)切換,調(diào)度器的核心就是調(diào)度算法。任務(wù)切換的實(shí)現(xiàn)在 不同的嵌入式實(shí)時(shí)操作系統(tǒng)中區(qū)別不大,基本相同的硬件內(nèi)核架構(gòu),任務(wù)切換也是相似的。調(diào)度算法就有些區(qū)別了。下面我們主要了解一下搶占式調(diào)度器和時(shí)間片調(diào)度器。
4 搶占式調(diào)度器?
搶占式:每個(gè)任務(wù)都被分配了不同的優(yōu)先級(jí),搶占式調(diào)度器會(huì)獲得就緒列表中優(yōu)先級(jí)最高的任務(wù),并運(yùn)行這個(gè)任務(wù)。
????如果用戶在 FreeRTOS 的配置文件 FreeRTOSConfig.h 中禁止使用時(shí)間片調(diào)度,那么每個(gè)任務(wù)必須配置不同的優(yōu)先級(jí)。
????當(dāng) FreeRTOS 多任務(wù)啟動(dòng)執(zhí)行后,基本會(huì)按照如下的方式去執(zhí)行:
◆ 首先執(zhí)行的最高優(yōu)先級(jí)的任務(wù) Task1,Task1 會(huì)一直運(yùn)行直到遇到系統(tǒng)阻塞式的 API 函數(shù),比如延遲, 事件標(biāo)志等待,信號(hào)量等待,Task1 任務(wù)會(huì)被掛起,也就是釋放 CPU 的執(zhí)行權(quán),讓低優(yōu)先級(jí)的任務(wù)得到執(zhí)行。
◆ FreeRTOS 操作系統(tǒng)繼續(xù)執(zhí)行任務(wù)就緒列表中下一個(gè)最高優(yōu)先級(jí)的任務(wù) Task2,Task2 執(zhí)行過(guò)程中有兩種情況:
????Task1由于延遲時(shí)間到,接收到信號(hào)量消息等方面的原因,使得Task1從掛起狀態(tài)恢復(fù)到就緒態(tài), 在搶占式調(diào)度器的作用下,Task2 的執(zhí)行會(huì)被 Task1 搶占。?
????Task2 會(huì)一直運(yùn)行直到遇到系統(tǒng)阻塞式的 API 函數(shù),比如延遲,事件標(biāo)志等待,信號(hào)量等待,Task2 任務(wù)會(huì)被掛起,繼而執(zhí)行就緒列表中下一個(gè)最高優(yōu)先級(jí)的任務(wù)。
◆ 如果用戶創(chuàng)建了多個(gè)任務(wù)并且采用搶占式調(diào)度器的話,基本都是按照上面兩條來(lái)執(zhí)行。根據(jù)搶占式調(diào)度器,當(dāng)前的任務(wù)要么被高優(yōu)先級(jí)任務(wù)搶占,要么通過(guò)調(diào)用阻塞式 API 來(lái)釋放 CPU 使用權(quán)讓低優(yōu)先級(jí)任務(wù)執(zhí)行,沒(méi)有用戶任務(wù)執(zhí)行時(shí)就執(zhí)行空閑任務(wù)。
下面我們通過(guò)如下的框圖來(lái)說(shuō)明一下?lián)屨际秸{(diào)度在 FreeRTOS 中的運(yùn)行過(guò)程

運(yùn)行條件:?
◆ 這里僅對(duì)搶占式調(diào)度進(jìn)行說(shuō)明。?
◆ 創(chuàng)建 3 個(gè)任務(wù) Task1,Task2 和 Task3。?
◆ Task1 的優(yōu)先級(jí)為 1,Task2 的優(yōu)先級(jí)為 2,Task3 的優(yōu)先級(jí)為 3。
????FreeRTOS 操作系統(tǒng)是設(shè)置的數(shù)值 越小任務(wù)優(yōu)先級(jí)越低,故Task3 的優(yōu)先級(jí)最高,Task1 的優(yōu)先級(jí)最低。?
◆ 此框圖是 FreeRTOS 操作系統(tǒng)運(yùn)行過(guò)程中的一部分。
運(yùn)行過(guò)程描述如下:
◆ 此時(shí)任務(wù) Task1 在運(yùn)行中,運(yùn)行過(guò)程中由于 Task2 就緒,在搶占式調(diào)度器的作用下任務(wù) Task2 搶占Task1 的執(zhí)行。Task2 進(jìn)入到運(yùn)行態(tài),Task1 由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。
◆ 任務(wù) Task2 在運(yùn)行中,運(yùn)行過(guò)程中由于 Task3 就緒,在搶占式調(diào)度器的作用下任務(wù) Task3 搶占 Task2 的執(zhí)行。Task3 進(jìn)入到運(yùn)行態(tài),Task2 由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。
◆ 任務(wù) Task3 運(yùn)行過(guò)程中調(diào)用了阻塞式 API 函數(shù),比如 vTaskDelay,任務(wù) Task3 被掛起,在搶占式調(diào) 度器的作用下查找到下一個(gè)要執(zhí)行的最高優(yōu)先級(jí)任務(wù)是 Task2,任務(wù) Task2 由就緒態(tài)進(jìn)入到運(yùn)行態(tài)。
◆ 任務(wù) Task2 在運(yùn)行中,運(yùn)行過(guò)程中由于 Task3 再次就緒,在搶占式調(diào)度器的作用下任務(wù) Task3 搶占 Task2 的執(zhí)行。Task3 進(jìn)入到運(yùn)行態(tài),Task2 由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。?
????上面就是一個(gè)簡(jiǎn)單的不同優(yōu)先級(jí)任務(wù)通過(guò)搶占式調(diào)度進(jìn)行任務(wù)調(diào)度和任務(wù)切換的過(guò)程。
5 時(shí)間片調(diào)度器
????在小型的嵌入式 RTOS 中,最常用的的時(shí)間片調(diào)度算法就是 Round-robin 調(diào)度算法。
????這種調(diào)度算法可以用于搶占式或者合作式的多任務(wù)中。另外,時(shí)間片調(diào)度適合用于不要求任務(wù)實(shí)時(shí)響應(yīng)的情況。 實(shí)現(xiàn) Round-robin 調(diào)度算法需要給同優(yōu)先級(jí)的任務(wù)分配一個(gè)專門(mén)的列表,用于記錄當(dāng)前就緒的任務(wù), 并為每個(gè)任務(wù)分配一個(gè)時(shí)間片(也就是需要運(yùn)行的時(shí)間長(zhǎng)度,時(shí)間片用完了就進(jìn)行任務(wù)切換)
????在 FreeRTOS 操作系統(tǒng)中只有同優(yōu)先級(jí)任務(wù)才會(huì)使用時(shí)間片調(diào)度,另外還需要用戶在 FreeRTOSConfig.h 文件中使能宏定義: #define configUSE_TIME_SLICING ????1
????默認(rèn)情況下,此宏定義已經(jīng)在 FreeRTOS.h 文件里面使能了,用戶可以不用在 FreeRTOSConfig.h 文 件中再單獨(dú)使能。
下面我們通過(guò)如下的框圖來(lái)說(shuō)明一下時(shí)間片調(diào)度在 FreeRTOS 中的運(yùn)行過(guò)程

運(yùn)行條件:?
◆ 這里僅對(duì)時(shí)間片調(diào)度進(jìn)行說(shuō)明。
◆ 創(chuàng)建 4 個(gè)同優(yōu)先級(jí)任務(wù) Task1,Task2,Task3 和 Task4。
◆ 每個(gè)任務(wù)分配的時(shí)間片大小是 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍。?
運(yùn)行過(guò)程描述如下:
◆ 先運(yùn)行任務(wù) Task1,運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過(guò)時(shí)間片調(diào)度切換到任務(wù) Task2。
◆ 任務(wù) Task2 運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過(guò)時(shí)間片調(diào)度切換到任務(wù) Task3。?
◆ 任務(wù) Task3 在運(yùn)行期間調(diào)用了阻塞式 API 函數(shù),調(diào)用函數(shù)時(shí),雖然 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍的時(shí)間片大小還沒(méi)有用完,此時(shí)依然會(huì)通過(guò)時(shí)間片調(diào)度切換到下一個(gè)任務(wù) Task4。(注意,沒(méi)有用完的時(shí)間片不會(huì)再使用,下次任務(wù) Task3 得到執(zhí)行還是按照 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍運(yùn)行)?
◆ 任務(wù) Task4 運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過(guò)時(shí)間片調(diào)度切換到任務(wù) Task1。
上面就是一個(gè)簡(jiǎn)單的同優(yōu)先級(jí)任務(wù)通過(guò)時(shí)間片調(diào)度進(jìn)行任務(wù)調(diào)度和任務(wù)切換的過(guò)程。
????