學習之路主要為FreeRTOS操作系統在STM32F103(STM32F103C8T6)上的運用,采用的是標準庫編程的方式,使用的IDE為KEIL5。
注意!!!本學習之路可以通過購買STM32最小系統板以及部分配件的方式進行學習,也可以通過Proteus仿真的方式進行學習。
后續文章會同時發表在個人博客(jason1016.club)、CSDN;
視頻會發布在bilibili(UID:399951374)
RTOS 系統的核心是任務管理,而任務管理的核心是任務切換,任務切換決定了任務的執行順序,任務切換效率的高低也決定了一款系統的性能
一、什么時候執行任務切換(啥時候切換)
執行系統調用就是執行 FreeRTOS 系統提供的相關 API 函數,比如任務切換函數 taskYIELD(),FreeRTOS 有些 API 函數也會調用函數 taskYIELD(),這些 API 函數都會導致任務切換,這些 API 函數和任務切換函數 taskYIELD()都統稱為系統調用。
FreeRTOS 中滴答定時器(SysTick)中斷服務函數中也會進行任務切換
二、任務切換函數PendSV(怎么切換)
PendSV函數原理(優勢)
將 PendSV 設置為最低的異常優先級,可以讓 PendSV 異常處理在所有其他中斷處理完成后執行,這對于上下文切換非常有用,也是各種 OS 設計中的關鍵。
因此,用PendSV作為任務切換函數的話,就把任務切換事件放在系統執行的最底層了,避免了任務切換會打斷正在運行的中斷事件這個問題
PendSV 異常將上下文切換請求延遲到所有其他 IRQ 處理都已經完成后,此時需要將 PendSV 設置為最低優先級。若 OS 需要執行上下文切換,他會設置 PendSV 的掛起壯態,并在 PendSV 異常內執行上下文切換
PendSV使用時機和方法(該切換時怎么切換)
-
- 在接收到上述系統調用的時候,通過SVC(中斷控制和壯態寄存器 ICSR)? 掛起PendSV,最后在空閑狀態執行PendSV中執行任務切換操作
- 在接收到Systick中斷后,由SVC(Systick)掛起PendSV,最后在空閑狀態執行PendSV中執行任務切換操作
三、查找下一個要運行的任務(切換成什么?切換成某一優先級的任務列表)
通用方法
任務添加時會根據優先級大小賦值給就緒任務列表數組( pxReadyTasksLists[]),一個優先級一個列表,同優先級的就緒任務都掛到相對應的列表中。uxTopReadyPriority 代表處于就緒態的最高優先級值,系統按就緒態的最高優先級的高到低遍歷,再依次執行對應的任務級列別,而針對同一優先級列表內的任務,則會按照次序依次執行。
硬件方法
硬件方法就是使用處理器自帶的硬件指令來實現,原理與上述方法相似,不同點在于:使用硬件方法的時候 uxTopReadyPriority 就不代表處于就緒態的最高優先級了,而是使用每個 bit 代表一個優先級,bit0 代表優先級 0,bit31 就代表優先級 31,當某個優先級有就緒任務的話就將其對應的 bit 置 1。
四、時間片調度(同一優先級任務列表的任務切換)
這里提出一個問題,當有兩個一樣重要(優先級相等)的任務需要我們去執行的話,我們應該怎么處理?大家都知道即使移植了freertos的單片機同一時間也只能執行一個任務,當面對有個多個同等優先級的任務的情況,freertos給出的答案是時間片調度執行。
在 FreeRTOS 中允許一個任務運行一個時間片(一個時鐘節拍的長度)后讓出 CPU 的使用權,讓擁有同優先級的下一個任務運行,FreeRTOS 中的這種調度方法就是時間片調度
這樣的調度方式就好比我們平時看到的風扇葉面,一個頁面代表一個同等優先級的任務,當我們執行得慢的時候,我們還能分清具體是那個葉面,而等風扇快速轉動起來后我就分不清葉面的類型甚至頁面的個數了。單片機同樣如此當單片機以幾十幾百HZ運行,并且將時間片稀釋得非常少的時候,我們就分不清他具體在執行什么任務了,乃至于我們會出現“單片機這幾個任務是同時執行的錯覺”,這也是為什么風扇轉起來就像個圓的。這就是FreeRTOS處理多(同優先級)任務的方法。
本文為作者獨立編寫,本BLOG上所有的原創文章未經本人許可,不得用于商業用途及傳統媒體。網絡媒體轉載請注明出處,否則屬于侵權行為。?