資源:http://blog.csdn.net/zhzht19861011/article/category/6191478
資源:可以下載安富萊的STM32-V5開發版資料中的FreeRTOS教程,里面有詳細介紹各個功能,可以在http://wenku.baidu.com/search?word=%B0%B2%B8%BB%C0%B3STM32-V6%BF%AA%B7%A2%B0%E5FreeRTOS%BD%CC%B3%CC&lm=0&od=0&fr=top_home中查找相應的文檔
移植的步驟在網上都能找到,這里只指出使用過程中遇到的問題
一、
1. 關於systick的設置
一般在stm32上運行實時操作系統,都會使用systick作為實時系統的時鍾滴答,所以會涉及到systick的設置,在freeRTOS的FreeRTOSConfig.h文件中可以找到:
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
這個表示CPU的時鍾為72MHZ,FreeRtos的時鍾頻率為1000HZ,這兩個值可以根據實際的配置情況進行更改,
在port.c中有如下條件語句:
#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#endif
表示如果我們沒有配置systick,那么freeRTOS就會根據 configCPU_CLOCK_HZ 和 configTICK_RATE_HZ 兩個宏來對systick的寄存器進行配置;
2. FreeRTOS與ucos-ii的內存管理
UCOS-II把內存區域(memory partition)分成相同大小的內存塊來使用,從而避免了內存碎化(fragmentation)帶來的困擾。這種內存管理方式的缺點在於:大小不同的內存塊必須提前訂制,無法通用。
freeRTOS里最常用到的內存管理方式是:不固定內存塊的大小;選擇滿足要求的最小空閑內存塊使用,並將多余的部分划分出去形成一個新的內存塊。這種管理方式有可能產生碎片,不過使用起來要方便一些。
3. FreeRTOS中斷分級
3.1 在官方推薦中,強烈建議STM32的優先級分組采用4,即:
/* 優先級分組設置為4, 優先配置好NVIC */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
也就是說只有4個位的搶占優先級(0 ~ 16),而沒有從優先級;為什么這樣設計? 這得從FreeRTOS的對中斷優先級的處理說起。在FreeRTOS中,FreeRTOS將優先級通過
configMAX_SYSCALL_INTERRUPT_PRIORITY(在FreeRTOSConfig.h中)分成兩組進行處理:
1. 當中斷的優先級數值高於configMAX_SYSCALL_INTERRUPT_PRIORITY的值(實際該中斷優先級要小於configMAX_SYSCALL_INTERRUPT_PRIORITY對應的優先級,因為在STM32中,優先級數值越高,表明優先級越低)時,說明該中斷可以被FreeRTOS系統進行屏蔽(通過FreeRTOS進入臨界區屏蔽),同時,在該中斷的中斷服務例程中可以使用FreeRTOS 的API函數;
2.當中斷的優先級數值低於configMAX_SYSCALL_INTERRUPT_PRIORITY的值時,說明該中斷可以不能被FreeRTOS系統進行屏蔽(即使FreeRTOS進入臨界區也不能),同時,在該中斷的中斷服務例程中不能使用FreeRTOS 的API函數;這些中斷稱為:不受FreeRTOS管理的中斷
3.2 不受FreeRTOS管理的中斷
講解不受FreeRTOS 管理的中斷之前要說一個小知識點----中斷延遲。中斷延遲時間是衡量RTOS 實時操作系統的一項重要指標,那什么又是中斷延遲呢?從中斷觸發到執行中斷服務程序的第一條指令這段時間就是中斷延遲時間。
FreeRTOS 內核源碼中有多處開關全局中斷的地方,這些開關全局中斷會加大中斷延遲時間。比如在源碼的某個地方關閉了全局中斷,但是此時有外部中斷觸發,這個中斷的服務程序就需要等到再次開啟全局中斷后才可以得到執行。開關中斷之間的時間越長,中斷延遲時間就越大,這樣極其影響系統的實時性。如果這是一個緊急的中斷事件,得不到及時執行的話,后果是可想而知的。針對這種情況,FreeRTOS 就專門做了一種新的開關中斷實現機制。關閉中斷時僅關閉受FreeRTOS管理的中斷,不受FreeRTOS 管理的中斷不關閉,這些不受管理的中斷都是高優先級的中斷,用戶可以在這些中斷里面加入需要實時響應的程序。FreeRTOS 能夠實現這種功能的奧秘就在於FreeRTOS 開關中斷使用的是寄存器basepri,而像uCOS 這種使用的是primask,詳情請看下面整理的表格:
對寄存器basepri 我們舉一個例子,幫助大家理解,比我們配置寄存器basepri 的數值為16,所有優先級數值大於等於16 的中斷都會被關閉,優先級數值小於16 的中斷不會被關閉。對寄存器basepri 寄存器賦值0,那么被關閉的中斷會被打開。這個就是FreeRTOS 開關中斷的實現方案。
4. FreeRTOS優先級
4.1 在FreeRTOS中,不同任務可以設置同一個優先級;多個任務可以共享一個優先級,RTOS調度器為相同優先級的任務分享CPU時間,在每一個RTOS 系統節拍中斷到來時進行任務切換
4.2 在RTOS內核中,每個有效優先級都會消耗一定量的RAM,因此這個值不要超過你的應用實際需要的優先級數目。每一個任務都會被分配一個優先級,優先級值從0~ (configMAX_PRIORITIES - 1)之間。低優先級數表示低優先級任務。空閑任務的優先級為0(tskIDLE_PRIORITY),因此它是最低優先級任務。 處於就緒狀態的相同優先級任務使用時間片調度機制共享處理器時間。
5. FreeRTOS堆棧
堆棧大小不是以字節為單位而是以字為單位的,比如在32位架構下,棧大小為100表示棧內存占用400字節的空間。
6.configUSE_TASK_NOTIFICATIONS
設置宏configUSE_TASK_NOTIFICATIONS為1(或不定義宏configUSE_TASK_NOTIFICATIONS)將會開啟任務通知功能,有關的API函數也會被編譯。設置宏 configUSE_TASK_NOTIFICATIONS為0則關閉任務通知功能,相關API函數也不會被編譯。默認這個功能是開啟的。開啟后,每個任務多增加8字節RAM。
這是個很有用的特性,一大亮點。
每個RTOS任務具有一個32位的通知值,RTOS任務通知相當於直接向任務發送一個事件,接收到通知的任務可以解除任務的阻塞狀態(因等待任務通知而進入阻塞狀態)。相對於以前必須分別創建隊列、二進制信號量、計數信號量或事件組的情況,使用任務通知顯然更靈活。更好的是,相比於使用信號量解除任務阻塞,使用任務通知可以快45%(使用GCC編譯器,-o2優化級別)。
7. 互斥信號量和二值信號量
關於互斥量和二進制信號量簡單說:
- 互斥型信號量必須是同一個任務申請,同一個任務釋放,其他任務釋放無效。當多個任務使用同一個資源時,可以使用互斥信號量對共享資源進行互斥;
- 二進制信號量,一個任務申請成功后,可以由另一個任務釋放。
- 互斥型信號量是二進制信號量的子集
- FreeRTOS的互斥信號量有一個優先級繼承機制,可以防止優先級翻轉的問題;而二值信號量則沒有;
優先級繼承防止優先級翻轉問題:
- 創建2個任務Task1和Task2,優先級分別為1和3,也就是任務Task2的優先級最高。
- 任務Task1和Task2互斥訪問串口打印printf。
- 使用FreeRTOS的互斥信號量實現串口打印printf的互斥訪問。
- 低優先級任務Task1執行過程中先獲得互斥資源printf的執行。此時任務Task2搶占了任務Task1的執行,任務Task1被掛起。任務Task2得到執行。
- 任務Task2執行過程中也需要調用互斥資源,但是發現任務Task1正在訪問,此時任務Task1的優先級會被提升到與Task2同一個優先級,也就是優先級3,這個就是所謂的優先級繼承(Priority inheritance),這樣就有效地防止了優先級翻轉問題。任務Task2被掛起,任務Task1有新的優先級繼續執行。
- 任務Task1執行完畢並釋放互斥資源后,優先級恢復到原來的水平。由於互斥資源可以使用,任務 Task2獲得互斥資源后開始執行。
上面就是一個簡單的FreeRTOS互斥信號量的實現過程。
8. 任務划分
8.1 任務的結構
任務的結構按照任務的執行方式可以分為三類:單次執行類、周期執行類和事件觸發類
9. 數據通信
注意: 當對共享資源進行寫操作的任務只有一個時,只要其優先級高於所有其他進行讀操作的任務,就可以在進行寫操作時不必關中斷,這是因為低優先級任務執行讀操作不可能在這個時候奪取運行權。而低優先級執行任務執行讀操作必須采取關中斷措施來訪問全局變量,這是因為高優先級任務在進行寫操作時,隨時有可能被觸發而獲得運行權。
二、需要了解
-
RTOS的軟件定時器功能
-
任務切換方式(任務管理)和調度器
2.1 任務切換
任務切換的實現在不同的嵌入式實時操作系統中區別不大,基本相同的硬件內核架構,任務切換也是相似的
2.2 調度器
調度器的核心是調度算法,嵌入式實時操作系統中,調度算法會有些區別
-
調度方式
FreeRTOS支持:搶占式調度、時間片調度和合作式調度;實際應用主要是搶占式調度和時間片調度,合作式調度用到很少;在FreeRTOS代碼中會保持合作式調度,但不會再進行更新
3.1 搶占式調度
每個任務都有不同的優先級,任務會一直運行直到被高優先級的任務搶占或遇到阻塞式的API函數,如vTaskDelay();
3.2 時間片調度
每個任務都有相同的優先級,任務會運行固定的時間片個數或遇到阻塞式的API函數,比如vTaskDelay,才會執行同優先級任務之間的人物切換
二、任務划分
-
IRQ任務:IRQ任務是指通過中斷服務程序進行觸發的任務,此類任務應該設置為所有任務里面優先級最高的。
-
高優先級后台任務:比如按鍵檢測,觸摸檢測,USB消息處理,串口消息處理等,都可以歸為這一類任務。
-
低優先級的時間片調度任務:比如emWin的界面顯示,LED數碼管的顯示等不需要實時執行的都可以歸為這一類任務。實際應用中用戶不必拘泥於將這些任務都設置為優先級1的同優先級任務,可以設置多個優先級,只需注意這類任務不需要高實時性。
-
空閑任務:空閑任務是系統任務。
-
特別注意:IRQ任務和高優先級任務必須設置為阻塞式(調用消息等待或者延遲等函數即可),只有這樣,高優先級任務才會釋放CPU的使用權,,從而低優先級任務才有機會得到執行。 這里的優先級分配方案是我們推薦的一種方式,實際項目也可以不采用這種方法。調試出適合項目需求的才是最好的。