1. 程式人生 > >基於Arduino Due的FreeRTOS程式設計(AtmelSAM3X8E)--第一篇

基於Arduino Due的FreeRTOS程式設計(AtmelSAM3X8E)--第一篇

引言:本文介紹了FreeRTOS實時OS的基本功能,以及在SAM微控制器上如何配置和使用FreeRTOS的基本功能。本文涵蓋了一下幾大塊內容:

l  什麼是Real-Time的應用以及什麼是實時作業系統

l  如何建立並配置一個FreeRTOS的專案

l  如何使用FreeRTOS的基本功能

l  如何使用圖形化Debug工具來跟蹤實時OS的系統執行

本文的示例是基於Atmel Software Framework(ASF)的,凡是基於SAM器件並使用高於ASF3.8.1版本的ASF都可以編譯通過。

1、關於RTOS的一些基本概念

1.1   什麼是實時應用程式

實時應用程式和普通程式的區別就在於執行操作的時間。一個實時的應用會在一個可以預知的時間(並且這個時間是可以確定)內執行有關的操作,例如一個實時的應用可以確保使用者在按下ESC鍵以後0.2ms結束資料的傳送,而不是啟動某個結束執行緒,並且這個執行緒的執行是需要系統按照優先順序排程的。通常情況下,一個實時系統的需求會分為軟實時(soft real-time)和硬實時(Hard real-time)需求,在系統設計的時候要綜合考慮這兩方面需求:

l  軟實時需求:當時間底限被破壞的時候,整個系統的可用性不會被破壞,只是帶來體驗上的延時。

l  硬實時需求:當時間底限被破壞以後,整個系統失敗。例如:安全氣囊如果在指定的時間內沒有彈出,保護系統將失效。

1.2   實時系統和多工

對於大多數作業系統來說,支援多工是一個最基本的特性。在多工的基礎上,網路、外設介面和使用者介面等等的支援才能被引入。嵌入式系統並不用支援全部的上述介面,只需要選擇性的支援一部分。嵌入式系統所選用的作業系統通常只含有對多工基本功能的支援。這些作業系統的體積大小不一,從300位元組到10K位元組不等。但他們都足夠小,一邊裝入微控制器的內部快閃記憶體。

一個實時的作業系統通常包括以下的多工特性:

l  多工併發執行

l  排程器來決定哪個任務執行

l  排程器可以搶佔一個正在執行的任務的資源

l  支援任務間的通訊

1.3   FreeRTOS的介紹

FreeRTOS是個實時系統的核心,很多基於Contex –M3/M4的應用程式可以在這個核心的基礎上構建,以滿足對於硬實時性的需求。多數Context-M3/M4系列的微控制器只有一個核心,所以在任意時刻,只有一個任務可以執行。核心(排程器)根據分配給每個任務的優先順序來決定哪個任務在哪個時刻執行。通常而言,應用設計者可以為硬實時性高的任務分配較高的優先順序,對實時性較低的任務分配較低的優先順序,以確保硬實時需求比軟實時需求有更高的優先順序。

1.3.1         FreeRTOS的核心

FreeRTOS的核心是目標無關的,並且作為獨立的元件被整合在Atmel Software Framework裡釋出。可以使用Atmel Studio的ASF嚮導將核心模組加入到任何標準工程中,或者使用手動方式向在IAR中向獨立的ASF工程檔案中新增。

圖 FreeRTOS模組的組成

Cortex- M3/M4/M0+ port包括所有標準的FreeRTOS的特徵:

l  Pre-emptive和Co-operation的操作

l  具有柔性的任務優先順序分配

l  軟時鐘

l  二進位制訊號量

l  反射訊號量

l  計數訊號量

l  互斥

l  Tick hook functions

l  空閒鉤掛函式

l  棧溢位檢查

l  “跟蹤”鉤掛的巨集定義

1.3.2         FreeRTOS的多工管理機制

FreeRTOS允許在同一時刻處理多個任務,但只能有一個任務執行(單核)。因此,系統需要一個排程器將時間片分配給各個任務。排程器是FreeRTOS核心的核心,它依據分配給任務的優先順序和它的狀態來選擇要執行的任務。任務狀態的轉換和任務的排程如下圖:


圖 任務的狀態和排程過程中狀態的轉換

l  總狀態:執行態和非執行態

l  非執行態分為:Suspended、ready和Blocked三個子狀態

l  Suspend:任務被應用程式掛起(deactivated)

l  Blocked:為獲得同步事件任務被阻塞

l  Ready:任務準備執行,但有更高級別的任務正在執行。

任務排程的時候,瞄準那些“ready”狀態的任務並決定哪些任務可以被執行。FreeRTOS根據任務被建立時分配的優先順序來決定。任務的優先順序是排程器判斷和執行排程時考慮的唯一要素。每一次時鐘的滴答都會促使排程器考慮哪個任務需要被喚醒。


圖 核心和任務之間的排程關係

核心程式碼(排程器)負責在兩個任務之間協調時間片的分配。當第一個任務(Task1)從執行狀態變到非執行狀態的時候,例如,程式執行結束,主程式main()呼叫Return,系統的都會自動呼叫排程器程式碼,排程器會按照排程演算法從所有當前是“ready”的任務中選擇一個執行。從上圖可見,排程器的執行時間都很短,對於Task的執行時間可以忽略不計。

1.3.3         FreeRTOS的記憶體管理

FreeRTOS沒有設定Task數量的上限,只要配套的硬體和記憶體可以支援如此眾多的任務。FreeRTOS作為一個實時的作業系統,可以支援週期性和非週期性的任務。


圖 任務的記憶體分配

系統的核心在每建立一個任務或者一個核心物件的時候分配一塊記憶體空間,這塊被分配給任務或者物件的空間叫做“棧”。棧的大小可以在建立任務的時候配置。每個棧都包含“Task File”和“Task Control Board(TCB)”,它們被核心用來處理任務。所有的Stack被儲存在被稱之為“堆”(HEAP)的結構裡。堆管理器是依據Heap_x.c這個核心檔案的內容來完成的,到底選擇哪一個Heap_x.c是由需求決定的。

l  Heap_1.c:最簡單的實現,並且在分配完記憶體以後,不能釋放。

l  Heap_2.c:使用了“最佳適應”演算法,允許之前分配的記憶體被回收。

l  Heap_3.c:封裝了標準的C函式malloc()和free(),在大多數情況下,可以被選用的C編譯器支援。封裝使得malloc和free函式的使用是執行緒安全的。

l  Heap_4.c: 使用了“第一適應”演算法,和heap_2.c不同的是,它可以將臨皆被釋放的記憶體融合成一個大的記憶體塊。

除了Heap_3.c以外的所有模型都可以通過“configTOTAL_HEAP_SIZE”來配置,而Heap_3.c的堆大小配置則是通過連結器指令碼來完成的。

2、開發板和偵錯程式

本次實驗採用了市面上較為常見的Cortex處理器開發板Arduino Due,其微控制器為AtmelSAM3X8E,跟蹤和偵錯程式採用了JLink Lite,如下圖:


圖 Arduino Due開發板和Jlink Lite

未完待續…