mC/OS-II操作系統(tǒng)向ARM7開發(fā)平臺的移植
在ARM工程開發(fā)中,為了實(shí)現(xiàn)功能復(fù)雜的資源復(fù)用,提高軟件功能設(shè)計(jì)效率,簡化開發(fā)難度,需要采用高性能的實(shí)時(shí)嵌入式操作系統(tǒng)mC/OS-II作為軟件設(shè)計(jì)平臺。因此,將mC/OS-II移植到ARM開發(fā)平臺是一項(xiàng)難度極高但十分必要的工作。通常移植工作對開發(fā)人員有非常高的要求,開發(fā)人員不僅要熟練掌握嵌入式系統(tǒng)的開發(fā)模式和方法,而且還要對操作系統(tǒng)、處理器和硬件系統(tǒng)的特性有深入的認(rèn)識和研究。mC/OS-II移植工作已由作者獨(dú)立完成,在實(shí)際應(yīng)用后,證明mC/OS-II工作十分穩(wěn)定。
移植的硬件平臺采用高性能ARM7TDMI內(nèi)核的AT91m40800嵌入式處理器,開發(fā)調(diào)試平臺采用ARM SDT2.51,軟件平臺采用實(shí)時(shí)嵌入式操作系統(tǒng)mC/OS-II。
mC/OS-II實(shí)時(shí)操作系統(tǒng)的結(jié)構(gòu)及可移植性分析
mC/OS-II操作系統(tǒng)特點(diǎn)
mC/OS-II是一個(gè)高性能的嵌入式實(shí)時(shí)操作系統(tǒng),是由多任務(wù)、多中斷和高效實(shí)時(shí)內(nèi)核組成的一個(gè)有機(jī)整體。應(yīng)用系統(tǒng)在實(shí)時(shí)內(nèi)核的統(tǒng)一管理下協(xié)調(diào)工作,能夠高效地實(shí)現(xiàn)任務(wù)切換、任務(wù)調(diào)度、任務(wù)間通信、同步、互斥、實(shí)時(shí)時(shí)鐘管理、中斷管理等功能。
為了提高系統(tǒng)的實(shí)時(shí)能力,mC/OS-II可以將一個(gè)復(fù)雜的應(yīng)用劃分為多個(gè)相互獨(dú)立的任務(wù),并根據(jù)任務(wù)的重要性來分配優(yōu)先級。每個(gè)任務(wù)擁有自己的堆??臻g,并且當(dāng)前任務(wù)運(yùn)行時(shí)獨(dú)占CPU資源。任務(wù)的調(diào)度完全由mC/OS-II的實(shí)時(shí)內(nèi)核完成,主要包括任務(wù)的狀態(tài)管理、選擇最高優(yōu)先權(quán)的任務(wù)、執(zhí)行任務(wù)和撤消任務(wù)等。mC/OS-II內(nèi)核還負(fù)責(zé)CPU時(shí)間分配,CPU時(shí)間總是優(yōu)先分配給中斷事件,其次是任務(wù)隊(duì)列中當(dāng)前優(yōu)先級最高的任務(wù)。不同任務(wù)間的通信可以通過mC/OS-II提供的信號量、郵箱、消息隊(duì)列等機(jī)制完成。
作為一個(gè)優(yōu)秀的實(shí)時(shí)操作系統(tǒng),mC/OS-II具有如下優(yōu)點(diǎn):
?可移植—絕大部分的mC/OS-II代碼由ANSI C編寫,只有和處理器相關(guān)的部分才使用匯編,這使得mC/OS-II便于移植;
?可裁減—如果只使用部分功能,可以通過條件編譯來裁減mC/OS-II的代碼;
?多任務(wù)—mC/OS-II可以管理64個(gè)任務(wù),目前系統(tǒng)保留了8個(gè),用戶的應(yīng)用程序最多可以有56個(gè)任務(wù)。每個(gè)任務(wù)的優(yōu)先級不同,這意味著mC/OS-II不支持時(shí)間片輪轉(zhuǎn)調(diào)度法;
?占先式—mC/OS-II是占先式的實(shí)時(shí)內(nèi)核,它總是運(yùn)行就緒條件下優(yōu)先級最高的任務(wù);
?可確定性—mC/OS-II的全部函數(shù)調(diào)用與服務(wù)的時(shí)間是可知的,mC/OS-II系統(tǒng)服務(wù)的時(shí)間不依賴于應(yīng)用程序任務(wù)的多少;
?任務(wù)?!總€(gè)任務(wù)有自己單獨(dú)的堆棧;
?系統(tǒng)服務(wù)—mC/OS-II提供郵箱、消息隊(duì)列、信號量、塊大小固定的內(nèi)存申請與釋放、時(shí)間相關(guān)函數(shù)等;
?中斷管理— 中斷可以使正在執(zhí)行的任務(wù)掛起,可能會在中斷結(jié)束的時(shí)候發(fā)生任務(wù)切換,中斷嵌套層數(shù)可達(dá)255層;
?穩(wěn)定性與可靠性—mC/OS -II和mC/OS自1992年以來已經(jīng)有幾百個(gè)商業(yè)應(yīng)用;
?公開源代碼—使得系統(tǒng)在商業(yè)應(yīng)用中具有明顯的價(jià)格優(yōu)勢。
mC/OS-II的硬件和軟件體系結(jié)構(gòu)及可移植性分析
圖1說明了mC/OS-II的結(jié)構(gòu)及其與硬件的關(guān)系。
由圖1可以看出,mC/OS-II的移植的主要工作是修改與處理器相關(guān)部分的代碼,它們集中在三個(gè)文件中。其中,OS_CPU.H包含與處理器相關(guān)的常量、宏和結(jié)構(gòu)體的定義;OS_CPU_C.C和 OS_CPU_ASM中定義了用于底層的任務(wù)切換,退出中斷服務(wù)程序,在CPU級屏蔽中斷、打開中斷,對任務(wù)棧初始化以及時(shí)鐘的中斷服務(wù)程序的函數(shù)。
為了使應(yīng)用程序運(yùn)行于mC/OS-II上,還要相應(yīng)地修改應(yīng)用中使用的硬件設(shè)備驅(qū)動(dòng)。
要使mC/OS-II正常運(yùn)行,處理器必須滿足以下要求:
1. 處理器的C編譯器能夠產(chǎn)生可重入代碼。
2. 用C語言就可以打開和關(guān)閉中斷。
3. 處理器支持中斷,且能產(chǎn)生定時(shí)中斷(通常在10~100Hz之間)。
4. 處理器支撐能夠容納一定容量數(shù)據(jù)(可能是幾千字節(jié))的硬件堆棧。
5. 處理器有將堆棧指針和其他CPU寄存器讀出,并存儲到堆?;騼?nèi)存中的指令。
ARM7處理器及開發(fā)環(huán)境ARM SDT2.51所使用的編譯器armcc可以滿足上述要求。但是根據(jù)對mC/OS-II工作原理的分析,上述第3點(diǎn)并不是運(yùn)行mC/OS-II所必需的。如果應(yīng)用中不需要定時(shí)器,就沒有必要在系統(tǒng)中加入時(shí)鐘節(jié)拍功能。在某些系統(tǒng)中沒有使用時(shí)鐘節(jié)拍,應(yīng)用中任務(wù)的切換完全依靠任務(wù)間的消息機(jī)制來完成,這大大提高了系統(tǒng)的實(shí)時(shí)性。上述要求是能夠移植mC/OS-II全部代碼的條件。
下面將結(jié)合mC/OS-II中與操作系統(tǒng)有關(guān)部分的功能分析、ARM7處理器體系結(jié)構(gòu)說明mC/OS-II向ARM SDT開發(fā)環(huán)境的移植。
mC/OS-II向ARM SDT2.51開發(fā)環(huán)境的移植
將mC/OS-II向ARM移植,需要修改與處理器相關(guān)的數(shù)據(jù)類型和函數(shù)。修改數(shù)據(jù)類型的聲明,需要對ARM處理器的字長及開發(fā)平臺編譯器使用的數(shù)據(jù)類型進(jìn)行綜合分析。修改與處理器相關(guān)的函數(shù),需要對ARM處理器體系結(jié)構(gòu),ARM匯編程序的編寫,操作系統(tǒng)在任務(wù)或中斷切換時(shí)對被中斷的任務(wù)的現(xiàn)場保護(hù)和恢復(fù)機(jī)制進(jìn)行綜合分析。下文將結(jié)合ARM處理器說明數(shù)據(jù)類型及相關(guān)函數(shù)的修改。
數(shù)據(jù)類型及宏的聲明
移植中對OS_CPU.H的修改主要是,改變了與處理器有關(guān)的數(shù)據(jù)類型和宏定義。
由于不同處理器有不同字長,mC/OS-II的移植需要重新定義一系列的數(shù)據(jù)類型。使用armcc編譯器,Char類型長度8位,Short類型長度16位,Int和Long類型長度32位。ARM寄存器都是32位的,所以將堆棧數(shù)據(jù)類型OS_STK聲明為32位。所有的堆棧都必須使用OS_STK聲明。
在該文件中,還將開關(guān)中斷的宏OS_ENTER_CRITICAL和OS_EXIT_CRITCAL定義為OS_CPU_ASM.S中的函數(shù)ARMDisableINT和ARMEnableINT。
mC/OS-II任務(wù)堆棧及任務(wù)切換
ARM處理器模式及寄存器
ARM處理器共有7種運(yùn)行模式,如表1所示。
mC/OS-II作為操作系統(tǒng)可以工作在sys模式和svc模式下。
ARM處理器共有31個(gè)通用寄存器(包括程序計(jì)數(shù)器PC)和6個(gè)狀態(tài)寄存器(PSR),具體組成為:
?未備份寄存器R0~R7。在所有的處理器模式下指的都是同一個(gè)物理寄存器。
?備份寄存器R8~R12。每個(gè)寄存器對應(yīng)兩個(gè)不同的物理寄存器。
?R13和R4,每個(gè)寄存器對應(yīng)6個(gè)不同的物理地址,usr模式和sys模式公用一個(gè)物理寄存器,其余每個(gè)模式有各自的R13和R14。寄存器R13常用做棧指針(sp),R14存放函數(shù)或異常模式的返回地址。
?程序計(jì)數(shù)器R15。
?當(dāng)前程序狀態(tài)寄存器(CPSR)和5個(gè)備份程序狀態(tài)寄存器(SPSR)。
mC/OS-II任務(wù)堆棧
mC/OS-II為每個(gè)任務(wù)建立堆棧,用于保存處理器的寄存器。其結(jié)構(gòu)體定義為OS_STK[16],保存處理器工作模式(svc模式)的R0~R12、R14、CPSR和SPSR。
mC/OS-II在OS_CPU_C.C中由任務(wù)堆棧初始化函數(shù)OSTaskStkInit,需要將任務(wù)棧內(nèi)的CPSR和SPSR設(shè)為svc模式。
mC/OS-II的任務(wù)切換
mC/OS-II的任務(wù)調(diào)度函數(shù)OSShed()獲得當(dāng)前就緒的優(yōu)先級最高任務(wù)的TCB(任務(wù)控制塊)指針,存入全局變量OSTCBHighRdy,將當(dāng)前任務(wù)的TCB指針存入OSTCBCur。然后調(diào)用函數(shù)OS_TASK_SW()進(jìn)行最底層的任務(wù)切換。
OS_CPU_ASM.S內(nèi)的任務(wù)切換函數(shù)OS_TASK_SW()完成的工作有兩步:將被掛起任務(wù)的微處理器寄存器推入任務(wù)堆棧(OSTCBCur->OSTCBSTK),然后將較高優(yōu)先級的任務(wù)的寄存器從棧(OSTCBHighRdy->OSTCBSTK)恢復(fù)到寄存器。
屏蔽中斷與開中斷
PSR寄存器格式說明
程序寄存器構(gòu)造如下:
位 31 30 29 28 27-----
N Z C V
-----7 6 5 4 3 2 1 0
I F T 工作模式
I位為1屏蔽處理器的外部中斷,為0允許外部中斷。
F位為1屏蔽處理器的快速中斷,為0允許快速中斷。
屏蔽中斷與開中斷
OS_CPU_ASM.S中的屏蔽中斷函數(shù)ArmDisableInt()將CPSR的I位置1實(shí)現(xiàn)在處理器級將中斷屏蔽;開中斷函數(shù)ArmEnableInt()將CPSR的I位置0允許處理器響應(yīng)中斷。
進(jìn)入中斷程序和中斷返回程序
ARM處理器的中斷處理程序
處理器響應(yīng)IRQ異常中斷時(shí)的處理過程是,在irq模式的R14保存程序返回的地址;在irq模式的SPSR保存CPSR;切換到irq模式,將CPSR中斷位(I位)置1,跳轉(zhuǎn)到中斷向量的地址。
mC/OS-II的中斷服務(wù)程序
在OS_CPU_ASM.S中的時(shí)鐘中斷服務(wù)程序OSTickISR是標(biāo)準(zhǔn)的中斷服務(wù)程序,函數(shù)的入口寫入AIC的中斷向量表,其實(shí)現(xiàn)的過程是:向m40800的AIC_IVR寫入任意的數(shù),讀取m40800的狀態(tài)寄存器清除中斷,保護(hù)CPU寄存器入棧,調(diào)用OSIntEnter對中斷嵌套標(biāo)志加1。調(diào)用中斷服務(wù)程序OSTimeTick,調(diào)用OSIntExit判斷是否需要任務(wù)切換,如果需要會調(diào)用OSIntCtxSW來進(jìn)行任務(wù)切換。此處沒有調(diào)用任務(wù)切換函數(shù)OS_TASK_SW()是因?yàn)镃PU寄存器入棧的工作已經(jīng)在進(jìn)入中斷時(shí)完成。
OSIntCtxSW是OS_CPU_ASM內(nèi)的函數(shù),完成的工作如下:向m40800的AIC_EOICR寄存器寫入值,將IRQ棧內(nèi)保存的中斷CPU寄存器的值寫入被中斷的任務(wù)棧,將就緒的高優(yōu)先級的任務(wù)棧內(nèi)容寫入對應(yīng)的CPU寄存器。
OSTickISR是標(biāo)準(zhǔn)的中斷服務(wù)程序,其他設(shè)備的中斷服務(wù)程序可以仿照這一程序的結(jié)構(gòu)編寫,只是對應(yīng)的設(shè)備寄存器地址不同。
測試mC/OS-II內(nèi)核
基于上述分析,對與處理器有關(guān)的4個(gè)匯編函數(shù)(ArmIntEnter,ArmIntExit,OSIntCtxSw,OS_Task_Sw),一個(gè)C函數(shù)(OSTaskStkInit)及相關(guān)的數(shù)據(jù)類型和宏定義進(jìn)行分析修改就是mC/OS-II移植需要做的工作。
一旦代碼移植結(jié)束,下一步工作就是測試。測試一個(gè)mC/OS-II的多任務(wù)實(shí)時(shí)內(nèi)核需要細(xì)致地考慮測試步驟。調(diào)試的過程應(yīng)該由簡到繁,可以從一些最簡單的任務(wù),甚至在沒有應(yīng)用程序的情況下開始測試。這樣做有兩個(gè)好處:第一,避免使原本復(fù)雜的事情更加復(fù)雜;第二,如果出現(xiàn)問題,可以知道問題出現(xiàn)在內(nèi)核代碼上而不是應(yīng)用程序。剛開始的時(shí)候,可以添加一些簡單的任務(wù)和時(shí)鐘節(jié)拍的中斷服務(wù)例程。一旦多任務(wù)調(diào)度成功運(yùn)行了,再添加應(yīng)用程序就非常簡單了。
在實(shí)際測試中,按照由簡到繁的過程不斷使測試變得復(fù)雜,如下所述:
1. 添加三個(gè)任務(wù),每個(gè)任務(wù)通過m40800的一個(gè)PIO口控制一個(gè)LED,在三個(gè)任務(wù)間互拋信號量。測試mC/OS-II系統(tǒng)內(nèi)任務(wù)調(diào)度,任務(wù)間通信機(jī)制是否工作正確;測試移植的任務(wù)棧結(jié)構(gòu)和任務(wù)切換函數(shù)OS_Task_SW是否正確(見圖2)。
2. 在上一步的基礎(chǔ)上,打開時(shí)鐘中斷,但沒有任務(wù)調(diào)用OSTimeDly等與時(shí)鐘中斷有關(guān)的操作。在時(shí)鐘中斷的OSTimeTickHook中通過一個(gè)PIO控制一個(gè)LED的亮滅。測試時(shí)鐘中斷的中斷服務(wù)程序OSTimeTickISR和中斷后沒有任務(wù)切換的情況系統(tǒng)運(yùn)行是否正確(見圖3)。
3. 在上一步的基礎(chǔ)上,三個(gè)基本任務(wù)中的延時(shí)使用OSTimeDly實(shí)現(xiàn),即在時(shí)鐘中斷的中斷服務(wù)程序完成后需要任務(wù)切換。測試移植的OSIntCtxSW是否正確(見圖4)。
4. 在上一步的基礎(chǔ)上,加入第四個(gè)任務(wù)Task4和串口收數(shù)中斷,在中斷服務(wù)程序中將收到字節(jié)放入郵箱,在Task4等待郵箱,被喚醒后從串口發(fā)出收到的字節(jié)。這種情況接近一般工程設(shè)計(jì)的應(yīng)用情況(見圖5)。
mC/OS-II向其他基于ARM7內(nèi)核芯片的移植
以上所述的移植工作大部分針對ARM7內(nèi)核,但其中涉及到中斷控制器及時(shí)鐘控制器的代碼是針對Atmel公司的AT91m40800芯片的專用外設(shè)編寫的,在向其他基于ARM7內(nèi)核的芯片移植mC/OS-II時(shí),只需修改相關(guān)外設(shè)的驅(qū)動(dòng)程序或系統(tǒng)中OS_CPU文件的相關(guān)代碼即可。在使用中,還完成了將mC/OS-II向三星公司的S3C44B0芯片移植的工作?!?/P>
評論