uC/OS II在S3C2410上的移植
隨著(zhù)信息化技術(shù)的發(fā)展和數字化產(chǎn)品的普及,以計算機技術(shù)、芯片技術(shù)和軟件技術(shù)為核心的嵌入式系統再度成為當前研究和應用的熱點(diǎn)。對功能、可靠性、成本、體積和功耗嚴格要求的嵌入式系統一般由嵌入式微處理器、外圍硬件設備、嵌入式操作系統以及用戶(hù)的應用程序等四個(gè)部分組成,其中嵌入式微處理器和嵌入式操作系統分別是其硬件和軟件的核心。
本文引用地址:http://dyxdggzs.com/article/104871.htmARM處理器由于其具有小體積、低功耗、低成本、高性能等特點(diǎn),廣泛應用在16/32位嵌入式RISC解決方案中,幾乎占有嵌入式微處理器市場(chǎng)分額的75% ,本文選定三星公司生產(chǎn)的一款基于A(yíng)RM920T核的高性能低功耗SOC芯片S3C2410作為移植方案的硬件平臺。市場(chǎng)上主流的嵌入式實(shí)時(shí)操作系統有Vxworks、pSos、WinCE、Linux等,基于實(shí)時(shí)性、成本以及開(kāi)發(fā)難度方面的考慮,我們選擇uC/OS II――開(kāi)放源代碼的嵌入式實(shí)時(shí)操作系統。
1 uC/OS II介紹
uC/OS II(Micro Control Operation System Two)是一個(gè)可以基于ROM運行的、可裁減的、搶占式(見(jiàn)圖1)實(shí)時(shí)多任務(wù)內核,具有高度可移植性,特別適合于微處理器和控制器,是和很多商業(yè)操作系統性能相當的實(shí)時(shí)操作系統(RTOS)。為了提供最好的移植性能,uC/OS II最大程度上使用ANSI C語(yǔ)言進(jìn)行開(kāi)發(fā),并且已經(jīng)移植到近40多種處理器體系上,涵蓋了從8位到64位各種CPU(包括DSP)。

uC/OS II可以簡(jiǎn)單的視為一個(gè)多任務(wù)調度器,在這個(gè)任務(wù)調度器之上完善并添加了和多任務(wù)操作系統相關(guān)的系統服務(wù),如信號量、郵箱等。其主要特點(diǎn)有公開(kāi)源代碼,代碼結構清晰、明了,注釋詳盡,組織有條理,可移植性好,可裁剪,可固化。內核屬于搶占式,最多可以管理60個(gè)任務(wù)。從1992年開(kāi)始,由于高度可靠性、魯棒性和安全性,uC/OS II已經(jīng)廣泛使用在從照相機到航空電子產(chǎn)品的各種應用中。
2 uC/OS II在S3C2410上的可移植性
所謂移植,就是使這個(gè)實(shí)時(shí)內核能在某個(gè)微處理器上運行。為了方便移植,大部分的uC/OS II代碼是用c語(yǔ)言寫(xiě)的,但仍需要用c和匯編語(yǔ)言寫(xiě)一些與處理器相關(guān)的代碼,這是因為uC/OS II在讀寫(xiě)處理器寄存器時(shí)只能通過(guò)匯編語(yǔ)言來(lái)實(shí)現。由于uC/OS II在設計時(shí)就已經(jīng)充分考慮了可移植性,所以uC/OS II的移植相對來(lái)說(shuō)是比較容易的。uC/OS II的框架結構如圖2。

uC/OSII的正常運行需要處理器平臺滿(mǎn)足以下要求:
a)處理器的C編譯器能產(chǎn)生可重入代碼。
b)用C語(yǔ)言就可以打開(kāi)和關(guān)閉中斷。
c)處理器支持中斷,并且能產(chǎn)生定時(shí)中斷(通常在10至100Hz之間)。
d)處理器支持能夠容納一定量數據(可能是幾千字節)的硬件堆棧。
e)處理器有將堆棧指針和其它CPU寄存器讀出和存儲到堆?;騼却嬷械闹噶?。
S3C2410處理器采用ARM920T內核,內部共有37個(gè)寄存器,其中R13通常用作堆棧指針,只要系統RAM空間允許,堆??臻g理論上沒(méi)有限制。ARM處理器提供ARM指令和Thumb指令兩種指令集,每種指令集都包含有豐富的指令對堆棧進(jìn)行操作,可以隨意的對處理器中的寄存器進(jìn)行堆棧操作。根據堆棧生長(cháng)方向的不同,可以生成4種不同的堆棧,分別是滿(mǎn)遞增、空遞增、滿(mǎn)遞減(此移植中使用的是滿(mǎn)遞減方式)、空遞減。芯片內集成5個(gè)定時(shí)時(shí)鐘,任何一個(gè)都可以產(chǎn)生定時(shí)中斷,滿(mǎn)足第三條要求。ADS集成開(kāi)發(fā)環(huán)境的內置編譯器可以產(chǎn)生可重入代碼,并且支持內嵌匯編,C環(huán)境中可任意的進(jìn)行開(kāi)關(guān)中斷操作。綜上所述uC/OS II完全可以移植到S3C2410上運行。
3 主體移植過(guò)程
3.1 設置與處理器及編譯器相關(guān)的代碼[OS_CPU.H]
不同的編譯器會(huì )使用不同的字節長(cháng)度來(lái)表示同一數據類(lèi)型,所以要定義一系列數據類(lèi)型以確保移植的正確性。下面是uC/OS II定義的一部分數據類(lèi)型。
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;/*無(wú)符號8位*/
typedef signed char INT16S;/*帶符號8位*/
typedef unsigned int INT16U;/*無(wú)符號16位*/
typedef signed int INT16S;/*帶符號16位*/
typedef unsigned long INT32U;/*無(wú)符號32位數*/
typedef signed long INT32S;/*帶符號32位數*/
typedef float FP32;/*單精度浮點(diǎn)數*/
typedef double FP64;/*雙精度浮點(diǎn)數*/
typedef unsigned int OS_STK;/*堆棧入口寬度*/
typedef unsigned int OS_CPU_SR;/*寄存器寬度*/
uC/OS II需要先關(guān)中斷再訪(fǎng)問(wèn)臨界區的代碼,并且在訪(fǎng)問(wèn)完后重新允許中斷。uC/OS II定義了兩個(gè)宏來(lái)禁止和允許中斷:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),本移植實(shí)現這兩個(gè)宏的匯編代碼。
#define OS_ENTER_CRITICAL()(cpu_sr=OSCPUSaveSR())/*Disable interrupts*/
#define OS_EXIT_CRITICAL()(OSCPURestoreSR(cpu_sr))/*Enable interrupts*/
EXPORT OSCPUSaveSR
OSCPUSaveSR
mrs r1,cpsr
mov r0,r1
orr r1,r1,#0xc0
msr cpsr_cxsf,r1
mov pc,lr
EXPORT OSCPURestoreSR
OSCPURestoreSR
msr cpsr_cxsf,r0
mov pc,lr
3.2 用C語(yǔ)言實(shí)現與處理器任務(wù)相關(guān)的函數[OS_CPU_C.C]
OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()
實(shí)際需要修改的只有OSTaskStkInit()函數,其他五個(gè)函數需要聲明,但不一定有實(shí)際內容。這五個(gè)函數都是用戶(hù)定義的,所以OS_CPU_C.C中沒(méi)有給出代碼。如果需要使用這些函數,可以將文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN設為1,設為0表示不使用這些函數。
OSTaskStkInit()函數由OSTaskCreate()或OSTaskCreateExt()調用,需要傳遞的參數是任務(wù)代碼的起始地址、參數指針(pdata)、任務(wù)堆棧頂端的地址和任務(wù)的優(yōu)先級,用來(lái)初始化任務(wù)的堆棧,初始狀態(tài)的堆棧模擬發(fā)生一次中斷后的堆棧結構。堆棧初始化工作結束后,OSTaskStkInit()返回新的堆棧棧頂指針,OSTaskCreate()或OSTaskCreateExt()將指針保存在任務(wù)的OS_TCB中。調用OSTaskStkInit()給任務(wù)做一個(gè)初始的任務(wù)上下文堆棧,形狀如圖3。

3.3 處理器相關(guān)部分匯編實(shí)現
整個(gè)uC/OS II移植實(shí)現中,只需要提供一個(gè)匯編語(yǔ)言文件,提供幾個(gè)必須由匯編才能實(shí)現的函數。
a)OSStartHighRdy()
該函數在OSStart()多任務(wù)啟動(dòng)之后,負責從最高優(yōu)先級任務(wù)的TCB控制塊中獲得該任務(wù)的堆棧指針sp,通過(guò)sp依次將CPU現場(chǎng)恢復,此時(shí)系統就將控制權交給用戶(hù)創(chuàng )建的該任務(wù)的進(jìn)程,直到該任務(wù)被阻塞或者被其他更高優(yōu)先級的任務(wù)搶占了CPU。該函數僅僅在多任務(wù)啟動(dòng)時(shí)被執行一次,用來(lái)啟動(dòng)第一個(gè),也就是最高優(yōu)先級的任務(wù)執行。
b)OSCtxSw()
該函數是任務(wù)級的上下文切換函數,在任務(wù)因為被阻塞而主動(dòng)請求與CPU調度時(shí)執行,主要工作是先將當前任務(wù)的CPU現場(chǎng)保存到該任務(wù)堆棧中,然后獲得最高優(yōu)先級任務(wù)的堆棧指針,從該堆棧中恢復此任務(wù)的CPU現場(chǎng),使之繼續執行,從而完成一次任務(wù)切換。
C)OSIntExit()
該函數是中斷級的任務(wù)切換函數,在時(shí)鐘中斷ISR中發(fā)現有高優(yōu)先級任務(wù)在等待時(shí),需要在中斷退出后不返回被中斷的任務(wù),而是直接調度就緒的高優(yōu)先級任務(wù)執行。其目的在于能夠盡快讓高優(yōu)先級的任務(wù)得到響應,保證系統的實(shí)時(shí)性能。
d)OSTickISR()
該函數是時(shí)鐘中斷處理函數,主要任務(wù)是負責處理時(shí)鐘中斷,調用系統實(shí)現的OSTimeTick函數,如果有等待時(shí)鐘信號的高優(yōu)先級任務(wù),則需要在中斷級別上調度其執行。另外兩個(gè)相關(guān)函數是OSIntEnter()和OSIntExit(),都需要在ISR中執行。
4 測試
至此代碼移植過(guò)程已經(jīng)完成,下一步工作就是測試。測試一個(gè)象uC/OS II一樣的多任務(wù)實(shí)時(shí)內核并不復雜,甚至可以在沒(méi)有應用程序的情況下測試。換句話(huà)說(shuō),就是讓這個(gè)實(shí)時(shí)內核在目標板上跑起來(lái),讓內核自己測試自己。這樣做有兩個(gè)好處:第一,避免使本來(lái)就復雜的事情更加復雜;第二,如果出現問(wèn)題,可以知道問(wèn)題出在內核代碼上而不是應用程序。剛開(kāi)始的時(shí)候可以運行一些簡(jiǎn)單的任務(wù)和時(shí)鐘節拍中斷服務(wù)例程。一旦多任務(wù)調度成功地運行了,再添加應用程序的任務(wù)就是非常簡(jiǎn)單的工作了。
5 結束語(yǔ)
采用基于A(yíng)RM9的S3C2410嵌入式微處理器,可以使系統具備高性能的運算能力的同時(shí)便于與各種外設連接擴展,簡(jiǎn)化了硬件設計,維持小型化的同時(shí)降低了系統成本。uC/OS II作為一個(gè)源代碼公開(kāi)的操作系統,在具體應用中穩定可靠,并且支持uIP TCP/IP協(xié)議棧、ucGUI等,可擴展性強,功能強大。本系統采ARM9+uC/OS II開(kāi)發(fā)設計,具有精度高、運行穩定、實(shí)時(shí)性好、抗干擾能力強、性?xún)r(jià)比高的特點(diǎn),可以在各種工業(yè)場(chǎng)合中廣泛應用,達到了設計的初衷。
tcp/ip相關(guān)文章:tcp/ip是什么
評論