uCOS-II在ARM上的移植
關(guān)鍵詞:uC/OS-II;ARM;移植
引言
隨著技術(shù)的進(jìn)步,嵌入式系統(tǒng)設(shè)計及其應(yīng)用在近年中,對人類生活產(chǎn)生了巨大影響,并將繼續(xù)改變?nèi)藗兾磥淼纳罘绞健Q芯壳度胧较到y(tǒng),一個必不可少的基礎(chǔ)工作就是實(shí)現(xiàn)嵌入式操作系統(tǒng)在相關(guān)處理器平臺上的移植。本文基于目前應(yīng)用非常廣泛的ARM處理器體系結(jié)構(gòu),對uC/OS-II嵌入式實(shí)時操作系統(tǒng)內(nèi)核的移植工作做了分析和介紹,并給出了在國內(nèi)一個開源項(xiàng)目 SkyEye 仿真器上的移植實(shí)例。
表2 CSPR的模式位
表3 ARM寄存器的命名和含義
uC/OS-II 概述
uC/OS-II 是一個簡單、高效的嵌入式實(shí)時操作系統(tǒng)內(nèi)核,被應(yīng)用到各種嵌入式系統(tǒng)中。目前,它支持 x86、ARM、PowerPC、MIPS 等眾多體系結(jié)構(gòu),并有上百個商業(yè)應(yīng)用實(shí)例,其穩(wěn)定性和可用性是經(jīng)過實(shí)踐驗(yàn)證的。同時,它的源代碼公開,可以從www.ucos-ii.com網(wǎng)站上獲得全部源碼以及其在各種體系結(jié)構(gòu)平臺上的移植范例。
最新的 uC/OS-II 2.0 版以上的內(nèi)核都具有可搶占的實(shí)時多任務(wù)調(diào)度功能,另外它還提供了許多系統(tǒng)服務(wù),例如信號量、消息隊列、郵箱、內(nèi)存管理、時間函數(shù)等,這些功能可以根據(jù)不同的需求進(jìn)行裁減??梢哉f,uC/OS-II是一個具備現(xiàn)代操作系統(tǒng)特點(diǎn)的RTOS,同時它結(jié)構(gòu)清晰、注解詳盡,具有良好的可擴(kuò)展性和可移植性,被廣泛地應(yīng)用于各種架構(gòu)的微處理器上。
ARM 的體系結(jié)構(gòu)
ARM是目前嵌入式領(lǐng)域由應(yīng)用最廣泛的RISC微處理器結(jié)構(gòu),以其低成本、低功耗、高性能等優(yōu)點(diǎn)占據(jù)了嵌入式系統(tǒng)應(yīng)用領(lǐng)域的領(lǐng)先地位。ARM系列的處理器當(dāng)前有ARM7、ARM9、ARM9E、ARM10等多個產(chǎn)品,此外,作為ARM公司合作伙伴的Intel,也提供基于XScale微體系結(jié)構(gòu)的相關(guān)處理器產(chǎn)品。所有的ARM處理器都共享ARM通用的基礎(chǔ)體系結(jié)構(gòu),開發(fā)者在不同的ARM處理器上做操作系統(tǒng)移植時,將大大節(jié)省工作量,降低軟件開發(fā)成本。
任何操作系統(tǒng)的移植都有相當(dāng)一部分工作和所用處理器的體系結(jié)構(gòu)密切相關(guān),因此在做具體的移植工作之前,需要了解該處理器的體系結(jié)構(gòu)和相應(yīng)的匯編語言。下面將簡要介紹ARM的體系結(jié)構(gòu),主要側(cè)重于與移植相關(guān)的一些概念。
處理器模式(CPU Mode):
ARM處理器可以工作在7種模式下,如表1所示。
除usr模式以外的其他模式都叫做特權(quán)模式,除 usr 和 sys 外的其他5種模式叫做異常模式。在usr模式下,對系統(tǒng)資源的訪問是受限制的,也無法主動地改變處理器模式。異常模式通常都和硬件相關(guān),例如中斷或執(zhí)行未定義指令等。與移植相關(guān)的處理器模式有兩種:svc態(tài)和irq態(tài),分別指操作系統(tǒng)的保護(hù)模式和通用中斷處理模式。這兩種模式之間的轉(zhuǎn)換可以通過硬件方式或軟件方式。uC/OS-II內(nèi)核在執(zhí)行過程中,大部分時間工作在svc態(tài),當(dāng)有硬件中斷,例如時鐘中斷到來時,CPU硬件自動完成從svc態(tài)進(jìn)入irq態(tài),在中斷程序結(jié)束處,則需要通過編程的方法使得CPU從irq態(tài)恢復(fù)到svc態(tài)。
程序狀態(tài)寄存器( PSR:Program status register )在任意一種處理器模式中,都使用同一個寄存器來標(biāo)識當(dāng)前處理器的工作模式,這個寄存器叫做 CPSR ( Current Program Status Register ),它的 [0--4] 位用來表示CPU Mode,表2 為CSPR的模式位每一種處理器異常模式,都有一個對應(yīng)的SPSR ( Saved Program Status Register )寄存器,用來保存進(jìn)入異常模式前的CPSR。SPSR的作用就是當(dāng)CPU從異常模式退出時,通過一條簡單的匯編指令就能夠恢復(fù)進(jìn)入異常模式前的CPSR,該值保存在當(dāng)前異常模式的SPSR中。例如:當(dāng)從usr態(tài)進(jìn)入中斷irq 態(tài)時,原先的 CPSR_all 將被保存在當(dāng)前的 SPSR_irq中,類似的異常模式下的 SPSR 還有 SPSR_fiq、SPSR_svc、SPSR_abt、SPSR_und。非異常模式的 usr和sys模式下沒有 SPSR,只有 CPSR。不能顯式地指定把 CPSR 保存到某個異常模式下的 SPSR,比如 SPSR_irq,而必須是變更到 irq 態(tài)之后CPU自動完成,不能硬性賦值,因?yàn)镾PSR_irq在其他狀態(tài)下不可見。
1、 ARM寄存器:( register )
ARM處理器共有37個寄存器,其中31個是通用寄存器,包括一個程序計數(shù)器 PC。另外6個就是上面提到的程序狀態(tài)寄存器。
·通用寄存器:
i. R0-R7:與所有處理器模式無關(guān)的寄存器,可以用作任何用途。
ii. R8-R14:與處理器模式有關(guān)的寄存器,在不同的模式下,對應(yīng)到不同的物理寄存器。其中 R13又叫做SP,一般用于堆棧指針。R14又叫做lr,一般用于保存返回地址。這兩個寄存器在每種異常模式下都對應(yīng)到不同的物理寄存器上,例如LR_irq、LR_svc、LR_fiq 等。
iii. R15:又叫做程序計數(shù)器,即PC,所有的模式下都使用同一個PC。
·狀態(tài)寄存器:
iv. CPSR:當(dāng)前程序狀態(tài)寄存器,所有的模式下都使用同一個 CPSR。
v. SPSR:保存的程序狀態(tài)寄存器,每種異常模式下都有自己的SPSR,一共有5種SPSR,即 SPSR_irq、SPSR_fiq、SPSR_svc、SPSR_abt、SPSR_und。usr和sys 態(tài)下沒有 SPSR 。
所有的ARM寄存器的命名和含義,可以用表3來說明,其中相同命名的都是同一個物理寄存器,不同命名的寄存器都對應(yīng)不同的物理寄存器。
表3 ARM寄存器的命名和含義
移植工作介紹
實(shí)際上uC/OS-II可以簡單地看作是一個多任務(wù)調(diào)度器,在這個任務(wù)調(diào)度器上完善地添加了與多任務(wù)操作系統(tǒng)相關(guān)的一些系統(tǒng)服務(wù),如信號量、郵箱等。其90%的代碼是用C語言寫的,可以直接移植到有C語言編譯器的處理器上。移植工作主要都集中在多任務(wù)切換的實(shí)現(xiàn)上,因?yàn)檫@部分代碼用來保存和恢復(fù)CPU現(xiàn)場(即寫/讀相關(guān)寄存器),不能用C語言,只能使用匯編語言完成。
uC/OS-II的全部源代碼量大約是6000-7000行,共15個文件。將 uC/OS-II 移植到ARM處理器上,需要修改三個與ARM體系結(jié)構(gòu)相關(guān)的文件,代碼量大約是500行。以下分別介紹這三個文件的移植工作。
OS_CPU.H 文件
圖1 ARM體系結(jié)構(gòu)的寄存器位置
圖2 任務(wù)堆棧初始化程序
·數(shù)據(jù)類型定義
數(shù)據(jù)類型的修改與所用的編譯器相關(guān),不同的編譯器使用不同的字節(jié)長度表示同一數(shù)據(jù)類型,比如int,同樣在x86平臺上,GNU的gcc編譯為4 bytes,而MS VC++則編譯為2 bytes。本文使用GNU 的 arm-elf-gcc,相關(guān)的數(shù)據(jù)類型定義如下:
·堆棧單位
在任務(wù)切換時,CPU現(xiàn)場的寄存器將保存在當(dāng)前運(yùn)行任務(wù)的堆棧中,所以O(shè)S_STK 數(shù)據(jù)類型應(yīng)該與CPU的寄存器長度一致。
typedef unsigned int os STK;
·堆棧增長方向
堆棧由高地址向低地址增長,也與編譯器有關(guān),在函數(shù)調(diào)用時,入口參數(shù)和返回地址一般保存在當(dāng)前任務(wù)的堆棧中,編譯器的編譯選項(xiàng)和由此生成的堆棧指令就會決定堆棧的增長方向。
#define OS_STK_GROWTH
·宏定義
包括開關(guān)中斷的宏定義,以及進(jìn)行任務(wù)切換的宏定義。
#define OS_ENTER_CRITICAL() ARMDisable Int()
#define OS_EXIT_CRITICAL() ARMEnable Int()
#define OS_TASK_SW() OSCtxSw()
OS_CPU_C.C 文件
·任務(wù)堆棧初始化
在此討論任務(wù)初始化時的堆棧設(shè)計,也就是在堆棧增長方向上如何定義每個需要保存的寄存器位置。在ARM體系結(jié)構(gòu)下,任務(wù)堆??臻g由高至低依次將保存著pc、lr、r12、r11、r10、... r1、r0、CPSR、SPSR,如圖1所示。
圖1 ARM體系結(jié)構(gòu)的寄存器位置
有兩點(diǎn)需要說明:一是,當(dāng)前任務(wù)堆棧初始化完成后,OSTaskStkInit 返回新的堆棧指針STK,在 OSTaskCreate()執(zhí)行時,將會調(diào)用 OSTaskStkInit 的初始化過程,然后通過OSTCBInit()函數(shù)調(diào)用,將返回的SP指針保存到該任務(wù)的TCB塊中。二是,初始狀態(tài)的堆棧是模擬了一次中斷后的堆棧結(jié)構(gòu),因?yàn)槿蝿?wù)創(chuàng)建后并不是直接就獲得執(zhí)行,而是通過OSSched()函數(shù)進(jìn)行調(diào)度分配,滿足執(zhí)行條件后才能獲得執(zhí)行。為了使這個調(diào)度簡單一致,就預(yù)先將該任務(wù)的PC指針和返回地址LR都指向函數(shù)入口,以便被調(diào)度時從堆棧中恢復(fù)剛開始運(yùn)行時的CPU現(xiàn)場。
·系統(tǒng)鉤子函數(shù)
在該文件中需要實(shí)現(xiàn)幾個操作系統(tǒng)規(guī)定的hook函數(shù),如下:
OSSTaskCreateHook( )
OSTaskDelHook( )
OSTaskSwHook( )
OSTaskStatHook( )
OSTimeTickHook( )
若無特殊需求,只需簡單地將它們都實(shí)現(xiàn)為空函數(shù)即可。
OS_CPU_A.S 文件
·OSStartHighRdy()
此函數(shù)是在OSStart()多任務(wù)啟動后,負(fù)責(zé)從最高優(yōu)先級任務(wù)的TCB控制塊中獲得該任務(wù)的堆棧指針SP,通過SP依次將CPU現(xiàn)場恢復(fù),這時系統(tǒng)就將控制權(quán)交給用戶創(chuàng)建的該任務(wù)進(jìn)程,直到該任務(wù)被阻塞或者被其他更高優(yōu)先級的任務(wù)搶占CPU。該函數(shù)僅在多任務(wù)啟動時被執(zhí)行一次,即執(zhí)行最高優(yōu)先級任務(wù),之后多任務(wù)的調(diào)度和切換由以下函數(shù)實(shí)現(xiàn)。
·OSCtxSw()
任務(wù)級的上下文切換,當(dāng)任務(wù)因?yàn)楸蛔枞鲃诱埱驝PU調(diào)度時被執(zhí)行,由于此時的任務(wù)切換在非異常模式下進(jìn)行,因此區(qū)別于中斷級別的任務(wù)切換。它的工作是先將當(dāng)前任務(wù)的CPU現(xiàn)場保存到該任務(wù)堆棧中,然后獲得最高優(yōu)先級任務(wù)的堆棧指針,從該堆棧中恢復(fù)此任務(wù)的CPU現(xiàn)場,使之繼續(xù)執(zhí)行。這樣就完成了一次任務(wù)切換。
·OSIntCtxSw()
中斷級的任務(wù)切換,在時鐘中斷ISR(中斷服務(wù)例程)中發(fā)現(xiàn)有高優(yōu)先級任務(wù)等待的時鐘信號到來,則在中斷退出后并不返回被中斷任務(wù),而是直接調(diào)度就緒的高優(yōu)先級任務(wù)執(zhí)行,從而能夠盡快地讓高優(yōu)先級的任務(wù)得到響應(yīng),保證系統(tǒng)的實(shí)時性能。其原理基本上與任務(wù)級的切換相同,但是由于進(jìn)入中斷時已經(jīng)保存了被中斷任務(wù)的CPU現(xiàn)場,因此不用再進(jìn)行類似的操作,只需對堆棧指針做相應(yīng)調(diào)整。
·OSTickISR()
時鐘中斷處理函數(shù),其主要任務(wù)是負(fù)責(zé)處理時鐘中斷,調(diào)用系統(tǒng)實(shí)現(xiàn)的OSTimeTick函數(shù),如果有等待時鐘信號的高優(yōu)先級任務(wù),則需要在中斷級別上調(diào)度其執(zhí)行。其他相關(guān)的兩個函數(shù)是OSIntEnter()和OSIntExit(),都需要在ISR中執(zhí)行。
·ARMEnableInt()& ARMDisableInt()
分別是退出臨界區(qū)和進(jìn)入臨界區(qū)的宏指令實(shí)現(xiàn)。主要用于在進(jìn)入臨界區(qū)之前關(guān)閉中斷,在退出臨界區(qū)的時候恢復(fù)原來的中斷狀態(tài)。它的實(shí)現(xiàn)比較簡單,可以直接開關(guān)中斷來實(shí)現(xiàn),也可以通過保存關(guān)閉/恢復(fù)中斷屏蔽位來實(shí)現(xiàn)。
全部移植代碼在SkyEye仿真器上調(diào)試通過,在SkyEye的主頁上可以下載獲得(http://hpclab.cs.tsinghua.edu.cn/~skyeye/)。
結(jié)語
uC/OS-II作為一個優(yōu)秀的實(shí)時操作系統(tǒng)已經(jīng)被移植到各種體系結(jié)構(gòu)的微處理器上,而ARM體系結(jié)構(gòu)在嵌入式領(lǐng)域也獲得了廣泛的應(yīng)用和支持。將uC/OS-II 移植到ARM平臺上,能夠使我們更深入地了解實(shí)時操作系統(tǒng)的構(gòu)造,加快在ARM平臺上的應(yīng)用和開發(fā),并為更高層次上的擴(kuò)展和改進(jìn)打下基礎(chǔ)。
參考文獻(xiàn)
1 ARM Architecture Reference Manual. http://www.arm.com
2 《ARM 嵌入式處理器結(jié)構(gòu)與應(yīng)用基礎(chǔ)》.馬忠梅等編著.北京航空航天大學(xué)出版社.2002年出版
3《uC/OS-II -源碼公開的實(shí)時嵌入式操作系統(tǒng)》.Jean J.Labrosse 著.劭貝貝譯.中國電力出版社.2001年出版
4 uC/OS 網(wǎng)站.http://www.ucos-ii.com
評論