滕艷平, 賈思禹, 金 梅, 李麗麗
(齊齊哈爾大學(xué) 計(jì)算機(jī)與控制工程學(xué)院, 黑龍江 齊齊哈爾 161006)
?
基于ARM11的μC/OS-II操作系統(tǒng)內(nèi)核移植實(shí)驗(yàn)的設(shè)計(jì)
滕艷平, 賈思禹, 金梅, 李麗麗
(齊齊哈爾大學(xué) 計(jì)算機(jī)與控制工程學(xué)院, 黑龍江 齊齊哈爾161006)
在分析嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-II內(nèi)核結(jié)構(gòu)的基礎(chǔ)上,針對(duì)ARM11微處理器,提出了μC/OS-II移植的方案,并在所移植的操作系統(tǒng)上進(jìn)行了多任務(wù)同步設(shè)計(jì)。通過(guò)RVDS集成開(kāi)發(fā)環(huán)境的測(cè)試結(jié)果表明,移植后的操作系統(tǒng)運(yùn)行正常,實(shí)現(xiàn)了多個(gè)任務(wù)之間的切換,并滿(mǎn)足系統(tǒng)對(duì)實(shí)時(shí)性、穩(wěn)定性的需求。
操作系統(tǒng); 內(nèi)核移植; ARM11; μC/OS-II; RVDS
ARM11系列微處理器是ARM公司近年推出的新一代RISC處理器,它具有ARM新指令架構(gòu),提供高性能處理能力,使其在嵌入式系統(tǒng)開(kāi)發(fā)中得到廣泛的應(yīng)用。嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-II以其實(shí)時(shí)性強(qiáng)、內(nèi)核公開(kāi)、易于學(xué)習(xí)和開(kāi)發(fā)等特點(diǎn)受到廣大技術(shù)人員和嵌入式愛(ài)好者的青睞[1-3]。本文以μC/OS-II為系統(tǒng)設(shè)計(jì)平臺(tái),給出其內(nèi)核代碼在ARM11系列微處理器上移植的實(shí)驗(yàn)步驟,并在所移植的操作系統(tǒng)上進(jìn)行多任務(wù)的同步設(shè)計(jì),完成多任務(wù)之間的切換。
在μC/OS-II內(nèi)核的移植時(shí),需要考慮編譯器的選取和ARM11工作模式的選取、移植中需要修改的文件以及利用ARM11軟中斷實(shí)現(xiàn)系統(tǒng)調(diào)用等相關(guān)問(wèn)題。移植框架見(jiàn)圖1所示。
圖1 μC/OS-II操作系統(tǒng)移植框架
在移植工作中,需要對(duì)μC/OS-II內(nèi)核中的OS_CPU.H、OS_CPU_A.S和OS_CPU_C.C等3個(gè)文件進(jìn)行重新編寫(xiě),以下面給出具體的實(shí)現(xiàn)步驟。
2.1文件OS_CPU.H的實(shí)驗(yàn)設(shè)計(jì)
在編寫(xiě)文件OS_CPU.H時(shí),主要包括聲明10個(gè)數(shù)據(jù)類(lèi)型、聲明3個(gè)宏以及定義堆棧的增長(zhǎng)方向。
2.1.1數(shù)據(jù)類(lèi)型的定義
在定義數(shù)據(jù)類(lèi)型時(shí)使用了typedef關(guān)鍵字,這樣做的目的,一方面是為了創(chuàng)建與平臺(tái)無(wú)關(guān)的數(shù)據(jù)類(lèi)型,另一方面也為移植提供了便利。由于在移植代碼中大量使用隱含著不可移植性的數(shù)據(jù)類(lèi)型,例如short、int、long等,當(dāng)移植失敗后需要修改數(shù)據(jù)類(lèi)型時(shí),卻需要多處修改,浪費(fèi)時(shí)間。而使用typedef關(guān)鍵字創(chuàng)建與平臺(tái)無(wú)關(guān)的數(shù)據(jù)類(lèi)型后,當(dāng)移植失敗后需要修改數(shù)據(jù)類(lèi)型時(shí),只需要修改typedef定義即可實(shí)現(xiàn)批量修改。在文件OS_CPU.H中,這些數(shù)據(jù)類(lèi)型的定義如下:
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;
typedef float FP32;
typedef double FP64;
typedef INT32U OS_STK;
2.1.2宏定義
在OS_CPU.H文件中,還需定義OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()兩個(gè)宏。OS_ENTER_CRITICAL()用于關(guān)中斷;而OS_EXIT_CRITICAL()用于開(kāi)中斷。這兩個(gè)宏直接調(diào)用OS_CPU_A.ASM文件中的匯編語(yǔ)言函數(shù)OSCPUSaveSR()、OSCPURestoreSR()來(lái)實(shí)現(xiàn)關(guān)中斷和開(kāi)中斷操作。之所以采用匯編語(yǔ)言來(lái)實(shí)現(xiàn)關(guān)中斷和開(kāi)中斷操作,主要是從實(shí)時(shí)性的角度來(lái)考慮的。
C語(yǔ)言與匯編語(yǔ)言的混合編程為嵌入式操作系統(tǒng)的開(kāi)發(fā)提供了極大的便利,例如:對(duì)ARM11的CPSR寄存器無(wú)法使用C語(yǔ)言直接訪問(wèn),但是只要嵌入一小段簡(jiǎn)單的匯編代碼就可以實(shí)現(xiàn)這一功能。需要注意的是,在C語(yǔ)言與匯編語(yǔ)言混合編程的程序中,參數(shù)是通過(guò)通用寄存器進(jìn)行傳遞的,在OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()的宏定義中,cpu_sr的值正是通過(guò)通用寄存器R0進(jìn)行傳遞的。
在OS_CPU.H文件中定義OS_TASK_SW()宏,用于實(shí)現(xiàn)任務(wù)的切換,這個(gè)宏定義同樣是直接調(diào)用OS_CPU_A.ASM文件中的匯編語(yǔ)言函數(shù)OSCtxSw()來(lái)實(shí)現(xiàn)任務(wù)的切換。
2.1.3堆棧的生長(zhǎng)方向的定義
存儲(chǔ)器堆棧可分為兩種:升棧,是向高地址方向生長(zhǎng),全稱(chēng)為遞增堆棧;降棧,是向低地址方向生長(zhǎng),全稱(chēng)為遞減堆棧。堆棧指針指向最后壓入的堆棧的有效數(shù)據(jù)項(xiàng),稱(chēng)為滿(mǎn)堆棧;堆棧指針指向下一個(gè)要放入的空位置,稱(chēng)為空堆棧[4]。這樣就有4種類(lèi)型的堆棧表示遞增和遞減的滿(mǎn)堆棧和空堆棧的各種組合:
(1) 滿(mǎn)升棧:堆棧通過(guò)增大存儲(chǔ)器的地址向上增長(zhǎng),堆棧指針指向內(nèi)含有效數(shù)據(jù)項(xiàng)的最高地址;
(2) 空升棧:堆棧通過(guò)增大存儲(chǔ)器地址向上增長(zhǎng),堆棧指針指向堆棧上的第;
(3) 滿(mǎn)降棧:堆棧通過(guò)減小存儲(chǔ)器的地址向下增長(zhǎng),堆棧指針指向內(nèi)含有效數(shù)據(jù)項(xiàng)的最低地址;
(4) 空降棧:堆棧通過(guò)減小存儲(chǔ)器地址向下增長(zhǎng),堆棧指針指向堆棧下的第一個(gè)空位置。
ARM11處理器對(duì)于4種類(lèi)型的堆棧均給予支持,但考慮到本文所用的RVDS編譯器僅支持一種增長(zhǎng)方式,即從上往下增長(zhǎng),并且必須是滿(mǎn)遞減堆棧。因此將OS_STK_GROWTH的值設(shè)為1,即使用滿(mǎn)降棧。其定義如下:
#define OS_STK_GROWTH1
2.2文件OS_CPU_A.S的實(shí)驗(yàn)設(shè)計(jì)
在OS_CPU_A.S文件的修改中,涉及匯編函數(shù)OSStartHighRdy()、OSCtxSw()、OSTickISR()、OSIntCtxSw()、OSCPUSaveSR()以及OSCPURestoreSR()等的重新編寫(xiě)。
2.2.1編寫(xiě)OSStartHighRdy()函數(shù)
使就緒狀態(tài)的任務(wù)開(kāi)始運(yùn)行的函數(shù)是OSStart(),也就是說(shuō)當(dāng)程序運(yùn)行到OSStart()之后就進(jìn)入μC/OS-II多任務(wù)環(huán)境了;而高優(yōu)先級(jí)就緒任務(wù)啟動(dòng)函數(shù)OSStartHighRdy()用于運(yùn)行多任務(wù)啟動(dòng)前優(yōu)先級(jí)最高的任務(wù),該函數(shù)僅僅在多任務(wù)啟動(dòng)時(shí)被執(zhí)行一次,用來(lái)啟動(dòng)第一個(gè)——也就是最高優(yōu)先級(jí)的任務(wù)執(zhí)行。其實(shí)現(xiàn)代碼如下:
OSStartHighRdy
MSRCPSR_cxsf,#SVCMODE|NOINT
BLOSTaskSwHook
LDRR0, =OSRunning
MOVR1, #1
STRBR1, [R0]
LDRR0, =OSTCBHighRdy
LDRR0, [R0]
LDRSP, [R0]
LDMFDSP!, {R0}
MSRSPSR_cxsf, R0
LDMFDSP!, {R0-R12, LR, PC}^
分析:在上述代碼的第一部分,首先對(duì)ARM11處理器的程序狀態(tài)字寄存器CPSR進(jìn)行賦值,SVCMODE、NOINT是使用ARM匯編指令EQU將它們分別賦值為0x13、0xc0,對(duì)這兩個(gè)值進(jìn)行按位或操作后得出的值,可以將ARM11處理器運(yùn)行在SVC模式,并且屏蔽普通中斷及快速中斷。
SVC模式是ARM11處理器一種保護(hù)模式,可以將其理解為一種特權(quán)模式,在此模式下具有更高的執(zhí)行權(quán)限。此后將OSRunning的值置為1,此時(shí)的LDR指令是偽指令,并不是普通的寄存器加載指令。然后將最高優(yōu)先級(jí)任務(wù)的堆棧指針賦值給SP,并且將最高優(yōu)先級(jí)任務(wù)的堆棧中保存的數(shù)據(jù)恢復(fù)到寄存器中,從而實(shí)現(xiàn)了最高優(yōu)先級(jí)就緒任務(wù)的啟動(dòng)。ARM11的CPSR寄存器如圖2所示。
圖2 ARM11的CPSR寄存器
2.2.2編寫(xiě)OSIntCtxSw()函數(shù)
μC/OS-II在每個(gè)時(shí)間片都要進(jìn)行任務(wù)的調(diào)度。調(diào)度的結(jié)果或者是返回原來(lái)的任務(wù)繼續(xù)執(zhí)行,或者是因?yàn)檎业搅司途w的更高優(yōu)先級(jí)的任務(wù)而讓該任務(wù)運(yùn)行。用戶(hù)時(shí)鐘中斷服務(wù)程序OSTickISR,也就是時(shí)鐘節(jié)拍服務(wù)程序,是操作系統(tǒng)的核心內(nèi)容。OSIntCtxSw()是一個(gè)中斷級(jí)的任務(wù)切換函數(shù),它是在中斷程序中調(diào)用的。在μC/OS-II中,由于中斷的產(chǎn)生可能會(huì)引起任務(wù)切換,在中斷服務(wù)程序的最后會(huì)調(diào)用OSIntExit()函數(shù)檢查任務(wù)就緒狀態(tài),如果需要進(jìn)行任務(wù)切換,將調(diào)用OSIntCtxSw()。其中OSIntCtxSw()的實(shí)現(xiàn)代碼如下:
OSIntCtxSw:
OSTaskSwHook();
OSTCBCur = OSTCBHighRdy;
OSPrioCur = OSPrioHighRdy;
SP =OSTCBHighRdy->OSTCBStkPtr;
RestoreNew task context
分析:OSCtxSw()和OSIntCtxSw()都是用于任務(wù)切換的函數(shù),其區(qū)別在于:在OSIntCtxSw()中無(wú)需再保存處理器寄存器,因?yàn)樵贠SIntCtxSw()之前已發(fā)生中斷,所以可以保證所有的處理器寄存器都被正確地保存到了被中斷的任務(wù)的堆棧之中。
2.3文件OS_CPU_C.C的實(shí)驗(yàn)設(shè)計(jì)
在編寫(xiě)文件OS_CPU_C.C時(shí),用C語(yǔ)言編寫(xiě)get_x()、get_int_vect()、OSTaskStkInit()等函數(shù)[5-6]。以下重點(diǎn)給出了中斷檢測(cè)函數(shù)get_x()的代碼設(shè)計(jì)過(guò)程。
ARM1176JZF-S處理器支持2組共64種中斷源,中斷處理對(duì)于μC/OS-II的移植是必不可少的。這里2組中斷源VICO和VIC1的寄存器基地址分別為0x71200000和0x71300000,狀態(tài)寄存器的偏移地址為0x000,通過(guò)訪問(wèn)這一只讀寄存器即可知道當(dāng)前中斷源的屏蔽狀態(tài)。其實(shí)現(xiàn)關(guān)鍵代碼如下:
unsigned int get_x(unsigned long x)
{int i;
for(i=0;i<32;i++)//該循環(huán)語(yǔ)句用于測(cè)試x的每一位是否為1
{if(x&(1<
return i;
}
return 0;
}
unsigned int get_int_vect()
{unsigned int ret;
unsigned long status;
status = * ((unsigned long*)0x71200000); //將VIC0的地址保存到STATUS變量if(status)
{ret = get_x(status);
return ret; }//在STATUS不為0的情況下檢測(cè)其中為1的位的位號(hào)
else
{status = * ((unsigned long*)0x71300000); //將VIC1的地址保存到STATUS變量if(status)
{ret = get_x(status)+32;//一個(gè)寄存器占32位
return ret;
}
}
}
分析:根據(jù)S3C6410處理器的結(jié)構(gòu)和特點(diǎn)來(lái)確定任務(wù)的堆棧結(jié)構(gòu),特別在OSTaskStkInit()函數(shù)代碼的編寫(xiě)中,其初始化參數(shù)由R0來(lái)傳遞,而數(shù)值0x00000013L將會(huì)使處理器設(shè)置為SVC模式,即特權(quán)模式,擁有更高的權(quán)限。
3.1多任務(wù)同步的設(shè)計(jì)
在多任務(wù)同步的設(shè)計(jì)中,任務(wù)創(chuàng)建與任務(wù)切換的流程圖如圖3所示。
圖3 任務(wù)創(chuàng)建和切換流程圖
任務(wù)的設(shè)計(jì)選擇了RVDS集成開(kāi)發(fā)環(huán)境,創(chuàng)建一個(gè)新的工程,并向工程添加一個(gè)新的文件,可為所添加文件進(jìn)行分組,其實(shí)現(xiàn)的關(guān)鍵代碼如下:
void Task0(void *pdata)
{#if OS_CRITICAL_METHOD == 3
OS_CPU_SRcpu_sr;
#endif
OS_ENTER_CRITICAL();
ISRInit();
OS_EXIT_CRITICAL();
OSPrintfInit();
OSStatInit();
OSTaskCreate (Task1,(void *)0, &Task1Stk[Task1StkLengh -1], Task1Prio);
while(1)
{OSPrintf(″this is from task0 ″);
OSTimeDly(OS_TICKS_PER_SEC*3); } }
分析:在上述代碼中,實(shí)現(xiàn)了Task0、Task1、Task2等3個(gè)任務(wù)的創(chuàng)建,并完成任務(wù)之間的切換。首先由Task0創(chuàng)建了任務(wù)Task1、在窗口控制臺(tái)上打印了語(yǔ)句this is from task0,并延時(shí)了3個(gè)時(shí)間片;隨后Task1創(chuàng)建了任務(wù)Task2、在窗口控制臺(tái)上打印了語(yǔ)句this is from task1,并延時(shí)了2個(gè)時(shí)間片;最后Task2在窗口控制臺(tái)上打印了語(yǔ)句this is from task2,并延時(shí)了1個(gè)時(shí)間片。
另外,本實(shí)驗(yàn)中,為了實(shí)現(xiàn)3個(gè)任務(wù)Task0、Task1、Task2的切換,并在串口控制臺(tái)輸出結(jié)果,還需移植printf()函數(shù),該函數(shù)的主要功能是將要顯示的字符串信息發(fā)送到串口消息隊(duì)列中。OSPrintf函數(shù)實(shí)現(xiàn)代碼如下:
void OSPrintf(const char *fmt,...)//控制臺(tái)打印函數(shù)
{INT8U *pUartBuf; // 定義一個(gè)串口消息緩沖區(qū)
INT8U err; //定義錯(cuò)誤信息變量
va_list ap;//定義緩沖區(qū)鏈表
pUartBuf=OSMemGet(pUartMem,&err);//將要發(fā)送的內(nèi)容傳送到串口
va_start(ap,fmt);//開(kāi)始遍歷鏈表
vsprintf(pUartBuf,fmt,ap);//打印控制臺(tái)內(nèi)容
va_end(ap);//結(jié)束遍歷鏈表
OSQPost(pUart_Q,pUartBuf);//發(fā)送消息
}
3.2移植系統(tǒng)的測(cè)試
在CodeWarrior for RVDS的Edit選單中的Debug Settings項(xiàng)中修改測(cè)試選項(xiàng),將Language Settings項(xiàng)中的RealView Assembler、RealView Compiler中的架構(gòu)均修改為ARM1176JZF-S[7-9],還可以將Linker項(xiàng)中的RealView FromELF項(xiàng)修改生成的BIN文件名稱(chēng)。代碼測(cè)試界面如圖4所示。
圖4 代碼測(cè)試界面
在CodeWarrior for RVDS的Project選項(xiàng)下選擇Debug,將自動(dòng)啟動(dòng)RVDS集成開(kāi)發(fā)環(huán)境中的AXD Debugger v1.3.1,燒寫(xiě)二進(jìn)制文件到ARM11開(kāi)發(fā)板中并運(yùn)行BOOTLOADER引導(dǎo)程序,對(duì)部分硬件進(jìn)行初始化工作。之后,內(nèi)核正常啟動(dòng),并對(duì)中斷模塊進(jìn)行了初始化。移植后的內(nèi)核運(yùn)行情況如圖5所示。3個(gè)任務(wù)同步的測(cè)試可利用JLink V8仿真器[10-12]來(lái)實(shí)現(xiàn),將編寫(xiě)的代碼下載到內(nèi)存即可進(jìn)行仿真調(diào)試。測(cè)試結(jié)果見(jiàn)串口控制臺(tái)的輸出,3個(gè)任務(wù)同步實(shí)現(xiàn)如圖6所示。
圖5 移植內(nèi)核的初始化
圖6 3個(gè)任務(wù)同步實(shí)現(xiàn)
圖6表明3個(gè)任務(wù)在新移植的操作系統(tǒng)中完成了任務(wù)的切換,實(shí)現(xiàn)任務(wù)的調(diào)度,并達(dá)到了預(yù)期的目的。
本文在充分了解ARM11指令系統(tǒng)的基礎(chǔ)上,分析了μC/OS-II內(nèi)核結(jié)構(gòu),提出了μC/OS-II在ARM11上的移植思想和方法,并實(shí)現(xiàn)了多個(gè)任務(wù)的同步設(shè)計(jì),選擇了RVDS集成開(kāi)發(fā)環(huán)境進(jìn)行了系統(tǒng)測(cè)試。結(jié)果表明,新移植的操作系統(tǒng)運(yùn)行穩(wěn)定,實(shí)現(xiàn)了多任務(wù)的切換,完成了多任務(wù)的調(diào)度,滿(mǎn)足系統(tǒng)對(duì)實(shí)時(shí)性的要求。下一步工作將對(duì)所移植的操作系統(tǒng)內(nèi)核進(jìn)一步優(yōu)化,并實(shí)現(xiàn)更多的應(yīng)用。
References)
[1] 徐海龍,邱建,王曉娜,等.μC/OS-Ⅱ的優(yōu)化移植和設(shè)備驅(qū)動(dòng)框架設(shè)計(jì)[J].計(jì)算機(jī)測(cè)量與控制,2012,20(9):2501-2506.
[2] 馬濤,白瑞林,石堅(jiān).Cortex-A8平臺(tái)的μC/OS-Ⅱ及LwIP協(xié)議棧的移植與實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2014,31(1):242-245.
[3] 孫彥景,王夢(mèng)龍,王迎.基于μC/OS-Ⅱ智能公交系統(tǒng)終端設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2012,33(12):4509-4513.
[4] 郭德源,何虎,楊旭.面向嵌入式實(shí)時(shí)操作系統(tǒng)的MPI實(shí)現(xiàn)[J].微電子學(xué)與計(jì)算機(jī),2011,28(3):35-42.
[5] 李祁,王鳳芹,張燕紅.嵌入式實(shí)時(shí)操作系統(tǒng)μC/OS-Ⅱ在STM32開(kāi)發(fā)板上的應(yīng)用[J].計(jì)算機(jī)與數(shù)字工程,2014,42(1):164-168.
[6] 鄧昀,程小輝,王新政.微內(nèi)核結(jié)構(gòu)嵌入式實(shí)時(shí)操作系統(tǒng)的研究與設(shè)計(jì)[J].微電子學(xué)與計(jì)算機(jī),2012,29(10):133-139.
[7] 葛強(qiáng),王宜懷,曹振華.一種基于ARM核的嵌入式操作系統(tǒng)的設(shè)計(jì)實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2010,27(3):268-271.
[8] 蔣建春,汪同慶.一種異構(gòu)多核處理器嵌入式實(shí)時(shí)操作系統(tǒng)構(gòu)架設(shè)計(jì)[J].計(jì)算機(jī)科學(xué),2011,38(6):298-303.
[9] 李昌剛,黃敏江,張昕,等.μC/OS-Ⅱ在XC164CS上的移植方法[J].計(jì)算機(jī)工程,2010,36(12):242-244.
[10] 李山山,李耀鏘,劉敬晗,等.μC/OS-Ⅱ內(nèi)核在基于FPGA的CPU上的移植[J].實(shí)驗(yàn)技術(shù)與管理,2010,27(4):87-90.
[11] 楊云,張勇.基于ARM7的μC/OS-Ⅱ移植分析與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與設(shè)計(jì),2009,30(3):539-541.
[12] 孫順遠(yuǎn),秦會(huì)斌,崔佳冬,等.μC/OS-Ⅱ在Cortex-M3內(nèi)核上的移植及優(yōu)化[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2010,19(4):208-211.
Design of kernel transplantation experiment μC/OS-II operating system based on ARM11
Teng Yanping, Jia Siyu, Jin Mei, Li Lili
(College of Computer and Control Engineering,Qiqihar University,Qiqihar 161006, China)
Based on the analysis of the kernel of embedded real-time μC/OS-II operating system and aiming at the ARM11 Micro-Processor, a migration scheme of μC/OS-II is put forward, and its multi-tasking synchronous demo is performed. The testing results by the RealView Development Suite(RVDS)Integrated Development Environment show that the migrated-operating system can run steadily and the goals of the switch between many tasks are realized, which meets the demands for real-time quality and stability.
operating system; kernet transplantation; ARM11; μC/OS-II; RVDS
10.16791/j.cnki.sjg.2016.03.036
2015- 08- 05
黑龍江省自然科學(xué)基金項(xiàng)目(F201218);黑龍江省教育廳科學(xué)技術(shù)研究項(xiàng)目(12541880)
滕艷平(1965—),女,黑龍江齊齊哈爾,碩士,副教授,主要研究方向?yàn)榍度胧讲僮飨到y(tǒng).
E-mail:typ2732996@163.com
TP316.2
A
1002-4956(2016)3- 0142- 05