摘要:嵌入式操作系統的移植是設計開發的重要一環,文章從全局和細節上分別研究了UCOS-II移植過程中的技術要點,并著重從移植后代碼的可靠性、健壯性和通用性等方面進行了研究。
關鍵詞:嵌入式;操作系統移植;UCOS
中圖分類號:TP316文獻標識碼:A文章編號:1006-8937(2012)05-0068-01
由于基于ARM7內核的各種芯片之間有著很大的差異,這些差異主要表現在存儲系統不同、片內外設不同、中斷源不同等。這就造成了嵌入式操作系統移植的不可避免性,而嵌入式操作系統移植效果的優劣直接影響著目標系統的整體質量。文中采用LPC2000系列ARM7微控制器以及ADS編譯器對UCOS-II的移植過程進行了測試研究。
1UC/OS-II的移植步驟
UC/OS-II是一個占先式的實時多任務內核,由ANSI C語言編寫,包含小部分匯編代碼供不同架構的處理器使用,能夠管理64個任務,主要系統功能包括:內存塊管理、任務管理、消息隊列管理、信號量、互斥信號量、事件標志組、消息郵箱等。從移植UCOS-II的過程來看,邏輯上可分作三大組成部分:與處理器無關的內核代碼、與處理器有關的核心代碼、與軟硬件環境設置有關的配置代碼。其中與處理器無關的內核代碼主要包括OS_CORE.C、OS_FLAG.C、OS_MBOX.C、OS_MEM.C、OS_MUTEX.C、OS_Q.C、OS_SEM.C、OS_TASK.C、OS_TIME.C、UCOS_II.C、UCOS_II.H,它們主要實現任務管理、信號量、內存管理、消息隊列、系統調度等功能;與處理器有關的核心代碼主要包括OS_CPU.H、OS_CPU_A.ASM、OS_CPU_C.C,它們主要與操作系統的移植相關;與軟硬件環境設置有關的配置代碼主要包括OS_CFG.H、INCLUDES.H,它們主要用于剪裁和設置操作系統。以上文件名為UCOS-II的默認設置,無須嚴格按照上述名稱命名文件。
由UCOS-II的邏輯結構可以看出,其移植工作主要集中在與處理器有關的核心代碼部分。實際測試中遵循了如下步驟。第一,對OS_CPU.H進行移植,這部分工作主要包括:首先定義與處理器有關的數據類型,如BOOLEAN、INT8U、INT8S等;其次進行與處理器有關的宏定義主要包括OS_ENTER_CRITICAL以及OS_EXIT_CRITICAL;再次編寫軟中斷函數主要包括OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。第二,對OS_CPU_A.ASM進行移植,依據ADS編譯器擴展名規則將文件名改為OS_CPU_A.S,主要工作是編寫4個匯編語言函數,名稱為OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()、OSTickISR()。USOS-II啟動時調用OSStart(),而OSStart()又調用OSStartHighRdy()運行優先級最高的任務。第三,移植OS_CPU.H。在OS_CPU_C.C文件中,需要編寫以下10個C函數,名稱分別為OSTaskStkInit()、OSTaskCreateHook()、OSTaskDelHook()、OSTaskSwHook()、OSTaskIdleHook()、OSTaskStatHook()、OSTaskTickHook()、OSInitHookBegin()、OSInitHookEnd()、OSTCBInitHook()。任務堆棧初始化函數OSTaskStkInit的定義按照移植時規定的堆棧結構進行,其他九個函數按照設計要求編寫,或者為空。
2UCOS-II移植的技術要點
2.1數據類型的處理
在C語言中常用的int、short等數據類型與處理器類型密切相關,這就意味著采用上述類型定義后的程序本身具有不可移植性,為此在代碼編寫中需要采用移植性強的數據類型進行替換,因此這些數據類型定義也便成了代碼移植工作的一部分,當然依編譯器的選擇不同也會略有差異,在ADS編譯器中部分相關參考代碼如下:
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int INT32S;
2.2任務與函數調用的封裝
ARM7內核具有7中工作模式,帶T后綴的具有兩套指令集,在提升處理器功能和效率的同時也帶來了復雜性。在移植過程中應設法編制接口函數將底層復雜性與操作系統層的管理和應用隔離開,為了達到這個目的可以采用軟件終端SWI(software interruption),而且在ADS編譯器中也提供了相應的支持,即__swi關鍵字。采用該關鍵字聲明一個莫須有的函數,調用時則在該處插入SWI指令,且可以設定中斷功能編號,以及完成參數傳遞等。比如:
__swi(0x00) void OS_TASK_SW(void)/*任務切換函數*/
__swi(0x00) void _ OSStartHighRdy(void) /*運行頂級優先任務*/
__swi(0x00) void _ OS_ENTER_CRITICAL (void) /*關中*/
__swi(0x00)void_OS_EXIT_CRITICAL(void)/*開中*/
2.3中斷服務的切換
如果在OS_CPU.H做過相應的聲明,采用OS_TASK_SW函數切換任務,則函數OSCtxSw是可以省略的,所以通常情況下OSCtxSw并不是移植初期需要關注的要點。前文提到基于ARM7的不同芯片之間的中斷系統存在差異,這就要求移植后的操作系統要保證目標機的中斷系統穩定運行保障系統的可靠性。而在中斷服務程序中切換任務時需要調用函數OSIntCtxSw,因此OS_CPU_A.S的移植要點在與保證OSIntCtxSw準確性,其代碼主要任務包括保護現場、將當前任務堆棧指針保存到對應的任務控制塊TCB(task control block)、獲取新任務的堆棧指針等。OS_CPU_A.S中的__ OSStartHighRdy()與之存在調用關系,OSStartHighRdy()須在OS_CPU_C.C中定義。部分相關代碼如下:
OSIntCtxSw_OSHR
獲取新任務堆棧指針
LDR R4,[R6]
ADD SP,R4,#68;
LDR LR,[SP, #-8]
MSR CPSR_c,#(NoInt|SVC32Mode);切換至管理模式
MOV SP,R4;設置堆棧指針
LDMFD SP!,{R4, R5};CPSR,關中次數
恢復新任務的關中計數器
LDR R3,=IECounter;為關中計數器分配寄存器
STR R4,[R3]
MSR SPSR_cxsf,R5;恢復CPSR
LDMFD SP!,{R0-R12, LR, PC }^;運行新任務
關中計數器為全局變量,不同的任務由各自的關中計數器,在任務切換時分別堆?;ゲ挥绊?,從而隔離了任務切換時可能造成的相互影響。
3結語
嵌入式操作系統的移植往往是影響全局且復雜性較強的工作。這類系統的移植也必然要建立在移植者對整體軟硬件系統有深入準確的掌握基礎之上。文中針對UCOS-II結合ARM7內核處理器以及ADS編譯器測試并總結了移植的步驟和部分技術要點,此類工作需要豐富的實踐和理論研究才能日臻完善。文中所論有很多不足之處和不全面的地方,需要在日后的實踐中不斷更正總結。
參考文獻:
[1] 武國平,史儀凱.ARM7處理器Bootloader的設計與實現[J].
微處理機,2010,(5).
[2] 周立功.ARM嵌入式系統基礎教程[M].北京:北京航空航
天大學出版社,2006.
[3] 寧杰城,王春,周新志.ARM7內核上的uC/OS—II嵌入式系
統移植[J].中國測試技術,2005,(2).