沙德鵬,彭 剛
(交通運輸部 天津水運工程科學研究院,天津 300456)
所謂系統(tǒng)的移植就是通過修改系統(tǒng)內(nèi)核的原代碼,使其能夠在其它微處理器或控制器上運行。uC/OS-ⅱ是著名的源代碼公開的實時內(nèi)核,它是一個完整的、可移植、固化、裁剪的搶占式實時多任務(wù)內(nèi)核。S3C2440是三星公司推出的高性能ARM9處理器,片上資源豐富,支持NorFlash和NandFlash兩種啟動方式,具備I-Cach、D-Cach以及MMU微處理器。將uC/OS-ⅱ移植到S3C2440上,能夠有效地管理其硬件資源,縮短程序的開發(fā)周期,降低系統(tǒng)維護的難度。uC/OS-ⅱ在S3C2440上的移植主要包括初始化S3C2440、修改uC/OS-ⅱ的底層代碼兩部分。
初始化即編寫啟動代碼,啟動代碼就是處理器在啟動時要執(zhí)行的一段代碼。其主要任務(wù)是初始化處理器模式、設(shè)置堆棧、初始化變量等。由于以上操作與處理器體系結(jié)構(gòu)和系統(tǒng)模式密切相關(guān),所以啟動代碼都是由匯編語言編寫,不同的處理器,啟動代碼一般不同。S3C2440的啟動過程如圖1所示。
圖1 S3C2440啟動代碼Fig.1 S3C2440 start code
圖2 中斷響應(yīng)過程Fig.2 Interrupt the response process
正常的程序因為一些固定的原因而使CPU停止,我們稱之為異常。異常事件由CPU產(chǎn)生,不同的原因產(chǎn)生不同的異常。S3C2440共有7類異常。當異常發(fā)生時,系統(tǒng)執(zhí)行完當前的指令后,將跳轉(zhuǎn)到相應(yīng)的異常中斷處理程序處執(zhí)行,在異常中斷處理程序執(zhí)行完成后,程序返回到發(fā)生中斷指令的下一條指令處執(zhí)行[1]。
中斷向量表中指定了各異常中斷及其處理程序的對應(yīng)關(guān)系,它通常放在處理器地址的低端,在S3C2440中,異常中斷向量表的大小為32 B,其中每個異常中斷占據(jù)4 B的大小,共可容納8個異常中斷,包括一個保留中斷。在S3C2440的啟動代碼中,每個異常中斷對應(yīng)的中斷向量中存放了一個跳轉(zhuǎn)指令或者一個向PC寄存器復(fù)制的數(shù)據(jù)訪問指令。通過這條跳轉(zhuǎn)指令,系統(tǒng)將展開一個宏,引導程序跳轉(zhuǎn)到其中斷服務(wù)程序的入口處執(zhí)行中斷服務(wù)程序 (復(fù)位中斷除外)。如果發(fā)生的是復(fù)位中斷,系統(tǒng)直接跳轉(zhuǎn)到相應(yīng)的匯編代碼,其過程如圖2所示。
S3C2440 CPU默認的工作主頻為12 MHz或者16.9344 MHz,這里最常用的是12 MHz。使用PLL電路可以產(chǎn)生更高的主頻,供CPU及外圍電路使用。S3C2440有兩個PLL:MPLL和UPLL,UPLL專用于USB設(shè)備。MPLL用于CPU及其外圍設(shè)備。MPLL產(chǎn)生三部分時鐘頻率:FCLK、HCLK、PCLK。FCLK用于CPU核,HCLK用于AHB總線,PCLK用于APB總線。S3C2440鎖相環(huán)回路電路如圖3所示。
圖3 鎖相環(huán)電路Fig.3 Phase-locked loop circuit
欲使S3C2440的鎖相環(huán)電路正常工作,產(chǎn)生需要的時鐘信號,必須通過設(shè)置CLKDIVN寄存器的值來設(shè)置鎖相環(huán)P、M、S三個參數(shù)的值。同時還要通過設(shè)置LOCKTIME寄存的值確定鎖相環(huán)的鎖定時間[2]。FCLK的啟動過程:①上電幾毫秒以后晶振開始輸出穩(wěn)定信號,此時FCLK=晶振頻率,單片機復(fù)位信號恢復(fù)高電平之后,CPU開始執(zhí)行指令;②設(shè)置完CLKDIVN之后,需要經(jīng)過一段時間MPLL才能穩(wěn)定輸出,這段時間由設(shè)定的LOCKTIME值來決定,在這段時間之內(nèi)(Lock Time)FCLK停止震蕩,CPU停止工作;③Lock Time之后,MPLL輸出穩(wěn)定,F(xiàn)CLK開始震蕩,S3C2440工作在新的FCLK之下,F(xiàn)CLK 的值與 P、M、S的關(guān)系如式(1)所示:
FCLK=MPLL=((M+8)Fin)/((P+2)+2S) (1)
系統(tǒng)確定FCLK之后,通過分頻獲得HCLK和PCLK。通過設(shè)置PLLCON寄存器中FDIVN、HDIVN和 PDIVN的值可以獲得 FCLK:HCLK:PCLK不同的比例關(guān)系。從而獲得不同的HCLK和PCLK。其比例關(guān)系如表1所示。
表1 HCLK和PCLK比例關(guān)系Tab.1 HCLK and PCLK ratio relationship
S3C2440提供1 G的外存儲空間,共分為8個塊兒(bank),每個塊兒的大小為128 M。8個塊中有6個ROM,2個RAM,前7個塊兒的起始地址固定,最后一個的起始地址可以調(diào)整,最后兩個塊兒的大小可編程,支持SDRAM的自刷新和掉電模式。系統(tǒng)上電后,外存儲空間不工作,欲使用外存儲空間必須初始化外存儲空間的控制寄存器。外存儲器的控制寄存器包括 BWSCON、BANKCON[0:7]、MRSRB6、MRSRB7,S3C2440的外存儲空間分布如圖4所示。
圖4 ARM外存儲空間示意Fig.4 ARM external storage space diagram
S3C2440共有7種工作模式,分別是User模式、FIQ 模式、IRQ 模式、Supervisor模式、Abort模式、Undefined模式和System模式。除了User模式和System模式共用同一堆棧外,其它各模式都有自己的堆棧,在進入主函數(shù)前需要設(shè)置各堆棧的起始地址,設(shè)置堆棧的示意性代碼如下:
S3C2440的程序代碼經(jīng)過編譯和鏈接之后生成的bin文件稱之為鏡像文件,鏡像文件由RO段、RW段和ZI段三部分組成。鏡像文件存儲在ROM中,ROM中存儲鏡像文件的區(qū)域稱為加載域,但是加載域只存儲RO段和RW段,不存儲ZI段,因為ZI段的數(shù)據(jù)全部為0。要得到S3C2440能夠運行的程序必須將鏡像文件的RO段和RW段搬運到連接器制定的區(qū)域,同時創(chuàng)建ZI段,這個區(qū)域稱為運行域。ARM連接器在創(chuàng)建運行域的同時還創(chuàng)建了5個符號,通過這5個符號可以計算出各個段的起始地址和結(jié)束地址。連接器創(chuàng)建的符號為∣Image$$RO$$Base∣、∣Image$$RO$$Limit∣、 ∣Image$$RW$$Base∣、∣Image$$ZI$$Base∣、∣Image$$ZI$$Limit∣,與各個段起始地址與結(jié)束地址的對應(yīng)關(guān)系如下[3]:
按照上述對應(yīng)關(guān)系將加載域中的鏡像文件搬運到運行域然后創(chuàng)建ZI段即可得到可以運行的程序。
uC/OS-ⅱ的大多數(shù)代碼用C語言編寫,與CPU無關(guān),但是有3個文件與CPU有關(guān)針對不同的CPU文件的內(nèi)容部一樣。這3個文件分別是OS_CPU.H、OS_CPU_A.ASM、OS_CPU_C.C; 要使得 uC/OS-ⅱ能夠在S3C2440上運行,必須完成者3個文件的移植。
AR9體系結(jié)構(gòu)中存在虛擬地址和物理地址,虛擬地址指的是程序要訪問的地址,物理地址指的是程序代碼存放的地址,同一個虛擬地址可以訪問到不同的物理地址,經(jīng)過代碼搬運與復(fù)制之后,單片機的代碼位置發(fā)生了變化,但是中斷向量的位置是固定的,一旦有中斷發(fā)生,單片機的PC指針仍然指向原來的中斷向量地址,這樣會產(chǎn)生錯誤,導致程序不能正常運行。要避免這種問題,必須進行地址重映射,將存放中斷向量的首地址映射為0。在ARM的內(nèi)存中存有一張由4096個地址描述符組成的表,每一個地址描述符描述了1 M空間的映射關(guān)系,ARM在訪問虛擬地址的時候通過插敘與虛擬地址對應(yīng)的地址描述符來訪問,結(jié)構(gòu)如圖5所示。
圖5 地址描述Fig.5 Address description
OS_CPU.H包括了用#define語句定義的與處理器相關(guān)的常數(shù)宏以及類型。OS_CPU.H的移植主要包括三部分內(nèi)容:與編譯器相關(guān)的數(shù)據(jù)類型、臨界段代碼的保護函數(shù)(OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL())、宏定義(OS_TASK_SW())。
不同的處理器有不同的字長,所以uC/OS-ⅱ的移植包括了一系列數(shù)據(jù)類型的定義,以確保其可移植性,uC/OS-ⅱ不適用 C語言中的 short、int、 以及l(fā)ong等數(shù)據(jù)類型,因為它們是與編譯器相關(guān)的,是不可移植的。uC/OS-ⅱ在OS_CPU.H中定義了可移植的整形數(shù)據(jù)結(jié)構(gòu)。在移植的過程中用戶需查閱文檔,找出對應(yīng)于uC/OS-ⅱ的標準的數(shù)據(jù)類型。
為了避免臨界段代碼免受多任務(wù)中斷服務(wù)子程序的破壞,uC/OS-ⅱ在進入中斷之前先關(guān)中斷,然后進入臨界段代碼,臨界段代碼執(zhí)行結(jié)束之后,uC/OS-ⅱ開中斷,不同的編譯廠商開關(guān)中斷的方式不一樣,為了隱藏編譯廠商提供的不同的方法,uC/OS-ⅱ定義了兩個宏:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。在移植過程中,需根據(jù)編譯器的特點完成這兩個宏的移植[4]。
OS_TASK_SW()是OS_CPU.H中定義的宏,是uC/OS-ⅱ系統(tǒng)中定義的一個重要的宏,主要完成從低優(yōu)先級到高優(yōu)先級任務(wù)的切換,OS_TASK_SW()主要是在任務(wù)級中被調(diào)用。必須用匯編語言實現(xiàn),其流程如圖6所示。
圖6 OS_CPU.H移植流程Fig.6 Flow chart of OS_CPU.H porting
OS_CPU_C.C包含了uC/OS-ⅱ的10個簡單的函數(shù),除OSTaskInit()外,其余 9個只須聲明,但是可以不包含任何代碼。OSTaskInit用于初始化任務(wù)的棧結(jié)構(gòu),uC/OS-ⅱ的每個任務(wù)建立后都有一個棧,用于保存任務(wù)的現(xiàn)場,棧的結(jié)構(gòu)如圖7所示。
圖7 匯編地址Fig.7 Assembled address
OS_CPU_A.ASM中包含了4個匯編函數(shù):OSSrartHighRdy、OSCtxSw、OSIntCtxSw 以 及 OSTick-ISR(),這4個匯編函數(shù)與CPU硬件息息相關(guān),在移植的過程之中必須用匯編語言實現(xiàn)。如果編譯器支持插入?yún)R編代碼就可以將所有與處理器相關(guān)的代碼放到OS_CPU_C.C中,而不必再有單獨的匯編語言文件。
OSCtxSw函數(shù)即為OSCtxSw(),在OS_CPU_C.C中宏定義 #define OSCtxSw(),OSCtxSw 將 OSCtxSw()定義為宏,通過引用宏直接調(diào)用匯編函數(shù)OSCtxSw,OSIntCtxSw用于中斷級的任務(wù)調(diào)度,其作用類似于OSCtxSw,兩者的主要區(qū)別在于OSCtxSw用于任務(wù)級的任務(wù)切換,而OSIntCtxSw用于中斷級的任務(wù)切換,OSIntCtxSw的代碼實現(xiàn)比較簡單,OSIntCtxSw在中斷中調(diào)用,在中斷之后,中斷服務(wù)函數(shù)已經(jīng)保護了被中斷任務(wù)的現(xiàn)場,所以O(shè)SIntCtxSw函數(shù)無需再做保護現(xiàn)場的工作,其它功能與OSCtxSw相同。
OSStartHighRdy函數(shù)主要在OSSart中調(diào)用,其主要功能是就緒態(tài)中的任務(wù)中優(yōu)先級最高的任務(wù)開始運行。OSStartHighRdy的示意性代碼如圖8所示。
uC/OS-ⅱ要求用戶提供一個周期性的時鐘源來實現(xiàn)時間的延遲和超時的功能,時鐘的節(jié)拍應(yīng)該每秒發(fā)生10~100次,當時鐘節(jié)拍中斷發(fā)生,系統(tǒng)調(diào)用時鐘節(jié)拍中斷服務(wù)子函數(shù)OSTickISR。
圖8 示意性代碼Fig.8 Schematic code
隨著嵌入式應(yīng)用的快速發(fā)展,嵌入式系統(tǒng)的應(yīng)用領(lǐng)域涉及方方面面,不同的應(yīng)用也對系統(tǒng)提出了不同的要求,uC/OS-ⅱ作為開源的嵌入式操作系統(tǒng)其代碼短小精悍,提供了操作系統(tǒng)的基本功能,具有可移植、可固化、可裁剪、搶先調(diào)度、多任務(wù)運行的特定。但是嵌入式系統(tǒng)針對的是不同的微處理器,因此只能提供內(nèi)核,與處理器相關(guān)的底層代碼必須單獨開發(fā)。經(jīng)過上述工作之后uC/OS-ⅱ能夠在S3C2440的單片機上穩(wěn)定運行,可以在此基礎(chǔ)上進一步完成程序的開發(fā)。
參考文獻:
[1] 方華,龔?fù)?,陳昭飛.一種基于stm32+μCOS-Ⅱ+μCGUI的嵌入式控制系統(tǒng)的構(gòu)建[J].信息通信,2015(2):65-66.
[2] 劉波文,孫巖.嵌入式實時操作系統(tǒng)ΜC/OS-Ⅱ經(jīng)典實例:基于STM32處理器[M].北京:北京航空航天大學出版社,2014.
[3] 劉鯉晞,陳揚.基于S3C2410A的μC/OS-Ⅱ和μC/GUI的整合移植[J].中國高新技術(shù)企業(yè),2009(4):96-97.
[4] 袁禹,周國榮.μC/OS-Ⅱ和嵌入式圖形界面的整合移植[J].電子技術(shù),2008,45(1):130-133.