目錄
1. 嵌入式操作系統
1.1 定義
關於嵌入式系統,至今沒有確切的定義,下面給出三個比較常用的定義:
- 系統定義
當外界事件或數據產生時,能夠接受並以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制所有實時任務協調一致運行的嵌入式操作系統。
注:在工業控制、 軍事設備、 航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。我們常常說的嵌入式操作系統都是嵌入式實時操作系統。比如μCOS-III,eCOS。故對嵌入式實時操作系統的理解應該建立在對嵌入式系統的理解之上加入對響應時間的要求。
- IEEE定義
嵌入式系統是“用於控制、監視或者輔助操作機器和設備的裝置”(Devices used to control, monitor, or assist the operation of equipment, machinery or plants)。
- 一般定義
以應用爲中心、以計算機技術爲基礎、軟件硬件可裁剪、功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統。
其實還有一種通俗的理解:嵌入式操作系統是爲了區別於通用的計算機系統,人們把嵌入到對象體系中,爲實現對象體系智能化控制的計算機系統,稱作嵌入式計算機系統,簡稱嵌入式系統。
1.2 嵌入式操作系統分類
按對外部事件的響應能力來分類,嵌入式操作系統有分時操作系統和實時操作系統。如果操作系統能使計算機系統及時的響應外部事件請求,並能控制所有實時設備和實時任務協調運行,且能在一個規定的時間內完成對事件的處理,那麼這種系統就稱爲實時操作系統(RTOS)。
按時間的正確程度來分,實時操作系統又分爲硬件的實時操作系統和軟件的實時操作系統。系統必須在極其嚴格的時間內完成的任務叫做硬件的實時操作系統,如果不是很嚴格的話就是軟件的實時操作系統。
分時操作系統就是按時間片輪轉完成各個任務。
基於時間觸發的嵌入式系統也很重要,這種方式簡單可靠、有很好的可預測性,在一些安全關鍵的領域也得到了廣泛的應用。
1.3 嵌入實時操作系統市場
Micrium(μCOS-III,II)Net 大的趨勢是一直在下降,FreeRTOS是小型嵌入式RTOS裏面佔有率最高的。RTX(由KEIL公司設計,現在KEIL已經被併入ARM公司旗下)也是榜上有名,RTX設計的也非常強勁,將基於Cortex-M3/M4架構的ARM芯片性能發揮到極致,比如中斷零延遲特性。
2. FreeRTOS 簡介
FreeRTOS由美國的Richard Barry於2003年發佈,Richard Barry是FreeRTOS的擁有者和維護者,在過去的十多年中FreeRTOS歷經了9個版本,與衆多半導體廠商合作密切,累計開發者數百萬,是目前市場佔有率最高的RTOS。
2.1 優勢
- 佔有率高流行
常用的RTOS有國外的FreeRTOS、μC/OS、RTX和國內的FreeRTOS、Huawei LiteOS和AliOS-Things等,其中尤以國外開源且免費的FreeRTOS的市場佔有率最高
- 易移植
FreeRTOS的移植比較簡單,只需要用戶添加需要的源碼文件,不需要做任何的底層工作,再添加三個宏定義即可
- 易上手
作爲開源免費的 RTOS ,官方配套的手冊在 RTOS 的基礎知識說明、 API 函數說明及其舉例方面做的 都非常好,用戶上手比較容易。
- 開源免費
2.2 版權
FreeRTOS於2018年被亞馬遜收購,改名爲AWS FreeRTOS,版本號升級爲V10,且開源協議也由原來的GPLv2+修改爲MIT,與GPLv2+相比,MIT更加開放,你完全可以理解爲是爲所欲爲的免費。V9以前的版本還是維持原樣,V10版本相比於V9就是加入了一些物聯網相關的組件,內核基本不變。亞馬遜收購FreeRTOS也是爲了進軍眼下炒的火熱的物聯網和人工智能。
2.3 收費問題
2.3.1 FreeRTOS
FreeRTOS是一款 “開源免費”的實時操作系統,遵循的是GPLv2+的許可協議。這裏說到的開源,指的是你可以免費得獲取到FreeRTOS的源代碼,且當你的產品使用了FreeRTOS且沒有修改FreeRTOS內核源碼的時候,你的產品的全部代碼都可以閉源,不用開源,但是當你修改了FreeRTOS內核源碼的時候,就必須將修改的這部分開源,反饋給社區,其它應用部分不用開源。免費的意思是無論你是個人還是公司,都可以免費地使用,不需要掏一分錢。
2.3.2 OpenRTOS
FreeRTOS 和 OpenRTOS 擁有的代碼是一樣的,但是可從官方獲取到的服務卻是不一樣的。FreeRTOS號稱免費,OpenRTOS號稱收費,它們的具體區別見表格
2.3.3 SaveRTOS
SaveRTOS也是基於FreeRTOS,但是SaveRTOS爲某些特定的領域做了安全相關的設計,有關SaveRTOS獲得的安全驗證具體見表格 。當然,SaveRTOS也是需要收費.
3. FreeRTOS 獲取資料
FreeRTOS的源碼和相應的官方書籍均可從官網 https://www.freertos.org/ 獲得,官網首頁
3.1 獲取源碼
點擊Download Source 按鈕,可以下載FreeRTOS最新版本的源碼。
如果想下載以往版本的可從託管網址:https://sourceforge.net/projects/freertos/files/FreeRTOS/下載。截止到目前,已經更新到V10.2.1
3.2 獲取書籍
點擊PDF Books可以下載FreeRTOS官方的兩本電子書,分別爲FreeRTOS V10.0.0 Reference Manual.pdf和Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf,一本是API參考手冊,另外一本是手把手入門教程。
3.3 快速入口
Quick Start Guide是網頁版的快速入門教程
4. FreeRTOS的編程風格
搞懂它的編程的風格很重要,這可以大大提供我們閱讀代碼的效率.
4.1 編碼標準
FreeRTOS核心源碼文件的編寫遵循MISRA代碼規則,同時支持各種編譯器。但考慮到有些編譯器的性能還比較弱,不支持C語言的新標準C99和C11的一些特性和語法,所以FreeRTOS的源碼中就沒有引入C99和C11的新特性,但是有一個例外,源碼中有用到頭文件stdint.h(這個文件是C99標準才引入的)。
如果用戶使用的編譯器沒有這個頭文件的話,可以將FreeRTOS源碼文件中,此路徑下FreeRTOS/Source/include的一個stdint.readme文件修改爲 stdint.h 文件後用於這個編譯器.
- MISRA
MISRA (The Motor Industry Software Reliability Association 汽車工業軟件可靠性聯會) 是位於英國的一個跨國汽車工業協會,其成員包括了大部分歐美汽車生產商。其核心使命是爲汽車工業提供服務和協助,幫助廠方開發安全的、高可靠性的嵌入式軟件。這個組織最出名的成果是所謂的MISRA C Coding Standard,這一標準中包括了127條C語言編碼標準,通常認爲,如果能夠完全遵守這些標準,那你的C代碼是易讀、可靠、可移植和易於維護的。現在很多嵌入式開發者都以MISRA C來衡量自己的編碼風格,比如uC/OS-II就宣傳99%遵守MISRA標準。
4.2 命名規則
變量:
- uint32_t定義的變量都加上前綴ul。u代表unsigned 無符號,l代表long長整型。
- uint16_t定義的變量都加上前綴us。u代表unsigned無符號,s代表short短整型。
- uint8_t定義的變量都加上前綴uc。u代表unsigned無符號,c代表char字符型。
- stdint.h文件中未定義的變量類型,在定義變量時需要加上前綴x,比如BaseType_t和TickType_t定義的變量。
- stdint.h文件中未定義的無符號變量類型,在定義變量時要加上前綴u,比如UBaseType_t 定義的變量要加上前綴ux。
- size_t 定義的變量也要加上前綴ux。
- 枚舉變量會加上前綴e。
- 指針變量會加上前綴p,比如uint16_t定義的指針變量會加上前綴pus。
- 根據MISRA代碼規則,char定義的變量只能用於ASCII字符,前綴使用c。
- 根據MISRA代碼規則,char *定義的指針變量只能用於ASCII字符串,前綴使用pc。
函數:
- 加上了static聲明的函數,定義時要加上前綴prv,這個是單詞private的縮寫。
- 帶有返回值的函數,根據返回值的數據類型,加上相應的前綴,如果沒有返回值,即void類型 ,函數的前綴加上字母v。
- 根據文件名,文件中相應的函數定義時也將文件名加到函數命名中,比如tasks.c文件中函數vTaskDelete,函數中的task就是文件名中的task。
宏定義:
- 根據宏定義所在的文件,文件中的宏定義聲明時也將文件名加到宏定義中,比如宏定義configUSE_PREEMPTION 是定義在文件 FreeRTOSConfig.h裏面。宏定義中的config就是文件名中的config。另外注意,前綴要小寫。
- 除了前綴,其餘部分全部大寫,同時用下劃線分開。
在編程的時候,如果用戶沒有明確指定char的符號類型,那麼編譯器會默認的指定char型的變量爲無符號或者有符號。正是因爲這個原因,在FreeRTOS中,我們都需要明確的指定變量char是有符號的還是無符號的。在keil中,默認char是無符號的,但是也可以配置爲有符號的
4.3 數據類型
在FreeRTOS中,使用的數據類型雖然都是標準C裏面的數據類型,但是針對不同的處理器,對標準C的數據類型又進行了重定義,給它們取了一個新的名字,比如char重新定義了一個名字portCHAR,這裏面的port表示接口的意思,就是FreeRTOS要移植到這些處理器上需要這些接口文件來把它們連接在一起。但是用戶在寫程序的時候並非一定要遵循FreeRTOS的風格,我們還是可以直接用C語言的標準類型。在FreeRTOS中,int型從不使用,只使用short和long型。在Cortex-M內核的MCU中,short爲16位,long爲32位。
reeRTOS中詳細的數據類型重定義在portmacro.h這個頭文件中實現
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
- TickType_t
如果用戶使能了宏定義 configUSE_16_BIT_TICKS,那麼TickType_t定義的就是16位無符號數,如果沒有使能,那麼TickType_t定義的就是32位無符號數。對於32位架構的處理器,一定要禁止此宏定義,即設置此宏定義數值爲0即可。
- BaseType_t
這個數據類型根據系統架構的位數而定,對於32位架構,BaseType_t定義的是32位有符號數,對於16位架構,BaseType_t定義的是16位有符號數。如果BaseType_t被定義成了char型,要特別注意將其設置爲有符號數,因爲部分函數的返回值是用負數來表示錯誤類型。
- UBaseType_t
這個數據類型是BaseType_t類型的有符號版本。
- StackType_t
棧變量數據類型定義,這個數量類型由系統架構決定,對於16位系統架構,StackType_t定義的是 16位變量,對於32位系統架構,StackType_t定義的是32位變量。
4.4 排版和註釋
- 縮進
Tab製表符用於縮進,Tab一次縮進4個字符空間。
- 註釋 FreeRTOS中註釋不會超過80個字符寬度,除非對函數的參數進行註釋時。源碼中主要是採用/* */的形式進行註釋,不採用C++中的雙斜槓風格來註釋。
- 代碼效果 FreeRTOS的源碼被設計的儘可能易於閱讀和查看