摘 要:本文研究了實時操作系統μC/OS-Ⅱ在ARM微處理器上的內核移植。首先介紹了實時操作系統μC/OS-Ⅱ和ARM7微處理器,在此基礎上,分析了內核移植的條件和主要內容,最后對代碼移植的正確性進行測試。
關鍵詞:ARM;μC/OS-Ⅱ;移植
1 引言
嵌入式系統是一個分散的工業,充滿了競爭、機遇與創新,沒有哪個系列的處理器和操作系統能夠壟斷全部市場,因此留給各個公司的創新余地很大。研究嵌入式系統,一個必不可少的基礎工作就是實現嵌入式操作系統在相關處理器平臺上的移植。本文基于目前應用非常廣泛的ARM處理器體系結構,對μC/OS-II嵌入式實時操作系統內核的移植工作做了分析和介紹,并對代碼移植的正確性進行驗證。
2 μC/OS-Ⅱ操作系統簡介
μC/OS-Ⅱ是一個著名的源代碼開放的嵌入式實時操作系統(RTOS),由美國人Jean J.Labrosse編寫出來。μC/OS-Ⅱ讀作\"micro controller OS 2\",意為\"微控制器操作系統版本 2\"。μC/OS-Ⅱ結構小巧,適合小型控制系統,具有執行效率高,占用空間小,實時性能優良和可擴展性能強等特點,具有可剝奪實時內核,提供了實時系統所需的基本功能,其中包括任務的調度與管理,時間管理,任務間同步與通信,內存管理和中斷服務等功能。
μC/OS-Ⅱ可用于8位、16位和32位單片機或DSP。良好的持續發展能力、高性能的內核以及友好的用戶開發壞境,使其迅速在嵌入式實時操作系統領域占據一席之地。
3 ARM7微處理器簡介
ARM(Advanced RISC Machines),是英國Advanced RISC Machines Limited公司設計開發的通用32位RISC微處理器體系結構。ARM處理器因其卓越的性能和顯著優點,已成為高性能、低功耗、低成本嵌入式處理器的代名詞,成為32位嵌入式應用領域、全球范圍內最廣泛使用的處理器。ARM7系列微處理器采用亞微米制造工藝,是一種低電壓、低功耗的32位RISC處理器,其內核基于ARMV4T(馮·諾依曼)體系結構,分為3級流水線,最高時鐘頻率為66MHz,使用3V/5V供電模式,最適合用于對價位和功耗要求較高的消費類應用。ARM7系列微處理器具有如下特點:具有嵌入式ICE-RT邏輯,調試開發方便;極低的功耗,適合對功耗要求較高的應用,如便攜式產品;能夠提供0.9MIPS/MHz的三級流水線結構;代碼密度高并兼容16位的Thumb指令集;對操作系統的支持廣泛,包括Windows CE、Linux、Palm OS等;指令系統與ARM9系列、ARM9E系列和ARM10E系列兼容,便于用戶的產品升級換代;主頻最高可達130MIPS,高速的運算處理能力能勝任絕大多數的復雜應用。
4 實時操作系統μC/OS-Ⅱ在ARM上的內核移植
4.1 移植的條件
處理器的C編譯器能產生可重入代碼;在程序中用C語言就可以打開或關閉中斷;處理器支持中斷,并且能夠產生定時中斷;處理器能夠容納一定數量的硬件堆棧;處理器有將堆棧指針和其他CPU寄存器存儲和讀出到堆棧(或者內存)的指令。
4.2 移植μC/OS-Ⅱ主要包括的內容
重新定義一系列與編譯器相關的數據類型。具體定義代碼如下:
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;/*8位無符號整數*/
typedef signed char INT8S;/*8位有符號整數*/
typedef unsigned short INT16U;/*16位有符號整數*/
typedef signed short INT16S;/*16位無符號整數*/
typedef unsigned long INT32U;/*32位無符號整數*/
typedef signed long INT32S;/*32位有符號整數*/
typedef float FP32;/*單精度浮點數*/
typedef double FP64;/*雙精度浮點數*/
設置一個常量來標識堆棧增長方向。
typedef unsigned int OS_STK /*堆棧的單位,堆棧入口寬度為16位*/
#define OS STK GROWTH 1/*定義堆棧的增長方向,1表示高地址向低地址增長*/
聲明用于開關中斷和任務切換的宏。具體代碼如下:
#define OS_ENTER_CRITICAL() ARMEnableInt() /*開啟中斷*/
#define OS_NTER_CRITICAL() ARMDisabIeInt() /*關閉中斷*/
#define OS_TASK_SW() OSCtxSw() /*任務切換*/
用匯編語言編寫與處理器相關的函數(OS_CPU.A.ASM)
為了方便移植,大部分的μC/OS-Ⅱ代碼是用C語言寫的,但仍需要用C和匯編語言寫一些與處理器相關的代碼,這是因為μC/OS-Ⅱ在讀寫處理器寄存器時只能通過匯編語言來實現。它包括以下四個子函數:OSStartHighRdy()是運行優先級最高的就緒任務、OSCtxsw()是任務級的任務切換函數、OSIntCtxSw()是中斷級的任務切換函數、OSTickISR()是系統時鐘節拍中斷服務函數
5 用C語言編寫6個與操作系統相關的函數(OS_CPU_C.C)
OSTaskInit:OSTaskCreate()和OSTaskCreateExt()通過調用OSTaskStkInit()來初始化任務的堆棧結構。在用戶建立任務的時候,用戶傳遞任務的地址,pdata指針,任務的堆棧棧頂和任務的優先級給OSTaskCreate()和OSTaskCreateExt()。一旦用戶初始化了堆棧,OSTaskStkInit()就需要返回堆棧指針所指的地址。OSTaskCreate()和OSTaskCreateExt()會獲得該地址并將它保存到任務控制塊(OS_TCB)中。
OSTaskCreateHook:當用OSTaskCreate()和OSTaskCreateExt()建立任務時就會調用OSTaskCreateHook()。當μC/OS-Ⅱ設置完自己內部結構以后,會在調用任務調度程序之前調用OSTaskCreateHook()。 當 OSTaskCreateHook()被調用時,會收到指向已建立任務的OS_TCB指針,這樣可訪問所有的結構成員。
OSTaskDelHook:當任務被刪除時會調用OSTaskDelHook()。該函數在任務從μC/OS-Ⅱ的內部任務鏈表中解開之前被調用。當它被調用時,會收到指向正被刪除任務的OSJCB指針,這樣可訪問所有的結構成員。
OSTaskSwHook:當發生任務切換的時候就會調用OSTaskSwHook()。OSTaskSwHook()可以直接訪問OSTCBCur和OSTCBHighRdy,因為它們是全局變量。OSTCBCur指向被切換出去的任務的OS_TCB,而OSTCBHighRdy指向新任務 OS_TCB。
OSTaskStatHook:OSTaskStatHook()每秒鐘都會被OSTaskStat()調用一次。用戶可以用OSTaskStatHook()來擴展統計功能。
OSTimeTickHook:OSTimeTickHook()在每個時鐘節拍都會被OSTaskTick()調用。OSTimeTickHook()是在節拍被μC/OS-Ⅱ真正處理并通知用戶的移植實例或應用程序之前被調用的。
完成了上述工作以后,μC/OS-Ⅱ就可以正常的運行在ARM處理器上了
結束語
μC/OS-II作為一個優秀的實時操作系統已經被移植到各種體系結構的微處理器上,而ARM體系結構在嵌入式領域也獲得了廣泛的應用和支持。將μC/OS-II移植到ARM平臺上,能夠使我們更深入地了解實時操作系統的構造,加快在ARM平臺上的應用和開發,并為更高層次上的擴展和改進打下基礎。
參考文獻
[1]Jean J, 邵貝貝譯. Labrosse. 嵌入式實時操作系統μC/OS-II. 北京 航空航天大學出版社. 2003.
[2]田澤. 嵌入式系統開發與應用教程. 北京: 北京航空航天大學出版社, 2004.