任修齊
(桂林電子科技大學 電子工程與自動化學院,廣西 桂林541004)
VxWorks是美國WindRiver公司于1983年設計開發(fā)的一款嵌入式實時操作系統(tǒng)(RTOS),其具有高性能的內(nèi)核(Wind Kernel)、持續(xù)發(fā)展能力以及友好的用戶開發(fā)環(huán)境,在嵌入式實時操作系統(tǒng)領域一直占據(jù)著高端位置。當前實時嵌入式開發(fā)環(huán)境的關鍵組成部分一般采用VxWorks??紤]到VxWorks的通用性,WindRiver公司將操作系統(tǒng)與硬件之間的一層獨立開來,命名為BSP(board support package)。BSP能夠使操作系統(tǒng)相對于特定的硬件平臺具有獨立性,其對上層屏蔽、封裝具體的硬件細節(jié),為系統(tǒng)調(diào)用以及應用軟件提供統(tǒng)一的接口[1]。
面對一個特定的硬件平臺,需要在其支持簡單外設時正常運行起來,這里涉及到的系統(tǒng)引導和驅動開發(fā)都是BSP的核心內(nèi)容。因此BSP開發(fā)是進行嵌入式系統(tǒng)研發(fā)時需要完成的第一個任務。BSP與特定硬件關系密切,不同架構的CPU對應的BSP絕大部分不同,即使同一款CPU,在外設細微差異的情況下,BSP也會有較大的不同,這是BSP開發(fā)的復雜性所在[2]。本文以嵌入式微處理器MPC8548硬件平臺為例,采用“整體移植,局部修改”的開發(fā)方法,利用WindRiver公司為PowePc CPU提供的BSP模板,詳細介紹了VxWorks BSP開發(fā)過程。
BSP通常是指特定的硬件平臺下的一個程序集合,包括啟動代碼和部分硬件設備驅動程序。在Vx-Works系統(tǒng)中,BSP簡單描述為介于底層硬件環(huán)境和VxWorks之間的一個軟件接口。
如圖1[2]BSP和PC機主板上的BIOS有些類似,但有一些區(qū)別。由于PC產(chǎn)業(yè)的高度成熟,BIOS的設計已經(jīng)充分標準化,BIOS主要是負責在PC機主板啟動時檢測、初始化系統(tǒng)設備,并沒有包含一些基本外設的驅動。BSP的概念只是針對嵌入式操作系統(tǒng)而提出的,其實現(xiàn)有較大的靈活性。在啟動的開始部分BSP和BIOS所做的工作類似,而后的大部分是不同的,BSP還包含和平臺有關的基本驅動(串口、網(wǎng)口等)。另外BSP是和操作系統(tǒng)“捆綁”在一起運行于主板上的。
圖1 RTOS BSP和PC BIOS的比較
以下從BSP職責、組成、執(zhí)行過程三個方面分別介紹[3~4]。
1.2.1 硬件環(huán)境的初始化
處理器和硬件環(huán)境的不同決定著VxWorks引導順序的差異,初始化硬件的步驟一般分為:
(1)在主存儲器的特定位置放置一段代碼(跳轉指令),當上電復位后處理器將立即執(zhí)行這段代碼;
(2)根據(jù)HRCW(硬件復位配置字),將處理器設置為某個具體的狀態(tài);
(3)初始化存儲器并對存儲器進行劃分;
(4)關閉中斷;
(5)將控制權轉交給鏡像的引導代碼;
(6)裝載需要的VxWorks段到RAM中;
(7)在開始初始化VxWorks內(nèi)核之前,確保以CPU為主的硬件處于狀態(tài)靜止。
1.2.2 硬件驅動程序的集成
為支持操作系統(tǒng)訪問硬件外設,BSP必須支持設備驅動程序相關的配置管理。主要指以下幾個方面:
(1)在BSP里面支持部分驅動程序,其中包括驅動程序所調(diào)用的中斷服務程序;驅動程序代碼涉及到的結構體以及宏等;
(2)BSP需支持硬件驅動程序實現(xiàn)可移植性。比如允許網(wǎng)絡設備驅動程序在不同的硬件環(huán)境之間移植;
(3)設備的管理和配置,比如:將產(chǎn)品的開發(fā)和配置分開。
1.2.3 軟件(與硬件相關)的集成
一個好的BSP不僅功能齊全,還需要考慮如下問題:
(1)提供代碼編譯時的適應性。比如:使用預處理宏,用戶可以根據(jù)自己的需要來定制BSP系統(tǒng)。例如:
#define INCLUDE_ATA/*包含ATA硬盤驅動程序*/
#define INCLUDE_FD/*包含軟盤驅動程序*/
(2)提供執(zhí)行時的可移植性。比如:提供編譯對象模塊的可移植性;使用指針訪問程序。
BSP主要由源文件、head文件、自動化編譯文件、派生文件組成,其實現(xiàn)的主干部分為源文件。以下主要介紹源文件。
1.3.1 BSP相關文件
這些文件位于.. argetconfigall目錄,它們并不是特定BSP的一部分,而是所有BSP的公共部分。該目錄主要由下面幾個文件組成:
(1)bootConfig.c。其包含完整的引導ROM外殼任務、一個網(wǎng)絡設備初始化表(NETIF),其主要對引導型ROM鏡像起初始化和控制作用。該文件定義了usrInit()函數(shù)和usrRoot()函數(shù)。
(2)bootInit.c。該文件包含引導ROM鏡像第二階段的初始化代碼,包括了函數(shù)romStart(),該函數(shù)的作用是重定位ROM鏡像和壓縮必要的代碼。
(3)usrConfig.c。其包含VxWorks鏡像的主要初始化代碼。它的初始化功能較為完整,包括了.. argetsrcconfigusrExtra.c文件以及其他提供子系統(tǒng)配置和初始化的文件。
(4)version.c。其提供了VxWorks版本號、構造鏡像時的日期和時間,這些信息會在執(zhí)行VxWorks鏡像時顯示。
(5)configAll.h。其設置了所有VxWorks鏡像的通用設置。
1.3.2 BSP實現(xiàn)文件
這些文件位于.. argetconfigspname目錄,包含了系統(tǒng)或硬件相關的BSP文件。其中的函數(shù)都需要依據(jù)硬件平臺進行編寫和調(diào)試。主要由下面幾個文件組成:
(1)rominit.s。該文件包含引導ROM和基于ROM的VxWorks鏡像的入口初始化匯編代碼。函數(shù)romInit()負責實現(xiàn)入口,該函數(shù)執(zhí)行初始化CPU、初始化內(nèi)存、初始化堆棧指針等。
(2)sysLib.c。該文件包含目標機體系結構、與系統(tǒng)有關的C程序。這些程序實現(xiàn)了上層與硬件的接口,由于這些接口,VxWorks和應用程序的構造與硬件無關。對硬件平臺所有外部器件初始化函數(shù)sysHwInit()和中斷掛載函數(shù)sysHwInit2()也在該文件中實現(xiàn)。
(3)sysSerial.c。這是一個可選文件,包含所有的SIO設備串行I/O驅動程序的安裝和初始化,包含串口初始化函數(shù)sysSerialHwInit()、sysSerialHwInit2()。
(4)systemClk.c。其包含系統(tǒng)時鐘處理函數(shù)sysClkConnect()、sysClkRateSet()和sysClkEnable()。
(5)IntrInit.c。其包含中斷控制器初始化函數(shù)IntrInit()。
(6)config.h。其包含了全部頭文件與涉及CPU的特殊宏。
(7)makefile。該文件控制使用命令行方式構造鏡像。
上一節(jié)中介紹了BSP的文件組成以及所包含的函數(shù),執(zhí)行這些函數(shù),硬件平臺實現(xiàn)了從上電到Vx-Works啟動完成。下面以ROM型VxWorks鏡像啟動為例介紹BSP函數(shù)的執(zhí)行過程。
系統(tǒng)上電啟動后,首先執(zhí)行固化在ROM中的romInit()函數(shù),其功能主要是禁止CPU中斷,配置SDRAM控制器,設置初始棧指針,然后執(zhí)行romStart()函數(shù)將ROM中VxWorks鏡像拷貝到RAM中執(zhí)行,接著在RAM中首先執(zhí)行usrInit()函數(shù)。usrInit()調(diào)用sysHwInit()函數(shù)初始化外部硬件設備,調(diào)用usrKernelInit()函數(shù)初始化并啟動內(nèi)核,調(diào)用usrRoot()函數(shù)連接系統(tǒng)時鐘、初始化并設置I/O系統(tǒng)和安裝所有外部設備驅動程序。至此系統(tǒng)啟動完成,BSP執(zhí)行結束。
圖2 BSP執(zhí)行過程中的核心函數(shù)調(diào)用
在啟動過程中,與具體硬件平臺相關的函數(shù)有romInit()、sysHwInit()以及usrRoot()調(diào)用的系統(tǒng)時鐘函數(shù)。其中,sysHwInit()函數(shù)調(diào)用所有外部硬件設備的初始化函數(shù)。例如:串口初始化函數(shù)sysSerialHwInit()、中斷控制器初始化函數(shù)IntrInit()、時鐘函數(shù)。時鐘函數(shù)包括:時鐘驅動掛載函數(shù)sysClkConnect()、時鐘速率設置函數(shù)sysClkRateSet()和時鐘使能函數(shù)sysClkEnable()。其中,sysClkConnect()函數(shù)還調(diào)用sysHwInit2()函數(shù)安裝所有外部設備的中斷處理程序,例如:串口中斷掛載程序sysSerialHwInit2()。啟動完成后所有外部設備驅動開始工作。
PowerPc處理器是Freescale、IBM和蘋果電腦的合作結晶。作為一個處理器,PowerPc在指令集、指令執(zhí)行和處理器內(nèi)核的設計方面具有很強的優(yōu)勢[5]。MPC8548是基于Freescale(飛思卡爾)的PowerPC架構的PowerQuiccⅢ處理器,其強大的處理能力特別適合于高速低時延的處理。主要參數(shù)如下[6]:
路面基層檢測合格及模板安裝完成后,進行鋼筋網(wǎng)安裝。先將橫筋按設計尺寸布置于底層,再將縱筋布置橫筋上方,在此過程中要注意鋼筋在板厚方向的高度,預留足夠的保護層厚度。鋼筋布置完成后進行鋼筋連接,縱向鋼筋接頭采用電弧單面焊接,搭接長度為16cm,焊接接頭處應錯開布置,接頭連線與路面行車方向成45°夾角,縱向鋼筋與橫向鋼筋交叉處采用鋼絲繩綁扎。采用φ16鋼筋彎拉制做成“Ω”形置于橫向鋼筋下作為鋼筋支架,并采用電焊連接,橫向布置間隔約為150cm,縱向布置間隔約為120cm。
最高頻率:1.5 GHz;支持內(nèi)存:最高2 G Byte DDR2 SDRAM;Flash:最高512 Kbyte+64 MByte×2+1 GByte;以太網(wǎng)口:前面板端2個千兆RJ45口;串口:前面板監(jiān)控串口;PCIexpress:AMC金手指端支持PCIe x4;電源:支持單板外部輸入單獨12 V/2 A電源和AMC金手指端供電。
采用的硬件平臺是圍繞MPC8548處理器設計的通信板。如圖3,硬件平臺的外設有:512 MByte的SDRAM,1 G×16 Bit NAND Flash Memory,RS-232串口,10/100 Mbit/s網(wǎng)口和JTAG調(diào)試端口。
圖3 硬件平臺結構
2.2.1 rominit()函數(shù)
該函數(shù)在romInit.s中實現(xiàn),其主要功能是:配置HRCW;配置內(nèi)存系統(tǒng);初始化堆棧指針[7]。
(1)配置HRCW。本平臺CPU使用的HRCW為0x0AA356B7,CPU讀取HRCW后將自身設置為特定狀態(tài)。MPC8548處理器使用指向FLASH的CS0,上電啟動后CS0有效且讀/寫位寬是16 bit,MPC8548從FLASH的地址0x00、0x08、0x10和0x18共計讀取32 bit的HRCW,配置其自身的工作模式。然后在執(zhí)行一段跳轉指令后MPC8548將程序計數(shù)器指向FLASH地址0x100(復位異常向量)處執(zhí)行rominit()函數(shù)。因此在rominit.s文件的開始部分通過匯編指令.fill將硬件復位字寫到0x00、0x08、0x10和0x18處,剩余空間直到0x100處寫0,具體如下:
.fill 8,1,0x0A
.fill 8,1,0xA3
.fill 8,1,0xB7
.fill 224,1,0
rominit:
(2)配置內(nèi)存系統(tǒng)。當執(zhí)行到romInit()函數(shù)時,romInit()在屏蔽外部中斷,關閉高速緩存后開始配置連接FLASH和SDRAM內(nèi)存的控制器,確定它們的內(nèi)存地址(分配給FLASH的基地址為0xF0000000)。此時將FLASH映射到地址為0xFC000000的空間,如果不執(zhí)行一段跳轉指令,CPU將按照地址0x0從FLASH中讀取指令,造成系統(tǒng)崩潰。
解決方法如下:在romInit函數(shù)內(nèi)部定義一個符號start,讓跳轉指令跳到這個符號的位置執(zhí)行,跳轉地址=0xF0000000+start-0x100。此時CPU才能以0xFC00000為基地址,從偏移地址(start-0x100)讀取指令。
接下來只需完成CS0對應的寄存器配置,以確定FLASH和SDRAM地址空間劃分。
2.2.2 sysLib.c文件
sysLib.c是BSP初始化的核心代碼,提供了Vx-Works和應用程序之間的板級聯(lián)系。動態(tài)頁表和靜態(tài)頁表是兩種主要的內(nèi)存映射模式,這里著重介紹動態(tài)頁表的配置。
為提高系統(tǒng)的實時性,硬件平臺將開啟MMU功能。BSP在sysLib.c文件中定義了一個結構體數(shù)組sysPhysMemDesc[]來配置MMU的動態(tài)頁表。sys-PhysMemDesc[]數(shù)組中的每個結構體對應著物理內(nèi)存中一個塊單元,結構體定義了物理地址、物理地址映射的虛擬地址(一般情況下與物理地址相同)、該塊內(nèi)存初始化狀態(tài)信息、掩碼信息等。其可包含的映射空間有內(nèi)存、Flash、ROM、I/O設備等,可以根據(jù)系統(tǒng)的需求自行進行配置。部分代碼如下[8]:
PHYS_MEM_DESCsysPhysMemDesc[]=
{
{(void*)(ROM_BASE_ADRS+0xF0000000),(void*)(ROM_BASE_ADRS),
ROUND_UP(ROM_SIZE_TOTAL*2,PAGE_SIZE),VM_STATE_MASK_VALID|
VM_STATE_MASK_WRITABLE|VM_STATE_MASK_CACHEABLE,VM_STATE_VALID|
VM_STATE_WRITABLE_NOT|VM_STATE_CACHEABLE_NOT},
…
…
};
上面的代碼是對ROM_BASE_ADRS的內(nèi)存映射,ROM_BASE_ADRS+0Xf0000000是要映射的虛擬地址,ROM_BASE_ADRS是硬件設計時定義的實際物理地址,ROUND_UP(ROM_SIZE_TOTAL*2,PAGE_SIZE)是映射長度,VM_STATE_MASK_VALID|VM_STATE_MASK_WRITABLE|VM_STATE_MASK_CACHEABLE是初始化的地址狀態(tài),VM_STATE_VALID|VM_STATE_WRITABLE_NOT|VM_STATE_CACHEABLE_NOT是實際初始化的地址狀態(tài)。
sysLib.c中包含了與硬件初始化密切相關的函數(shù)sysHwInit()和函數(shù)sysHwInit2()[9]。
2.2.3 sysHwInit()函數(shù)
sysHwInit()函數(shù)的功能是初始化系統(tǒng)硬件,該函數(shù)包含在sysLib.c文件中。根據(jù)本硬件平臺開發(fā)需求,需要編寫中斷控制器初始化函數(shù)IntrInit()和串口控制器初始化函數(shù)sysSerialHwInit()。
(1)IntrInit()函數(shù)。該函數(shù)位于IntrInit.c文件。根據(jù)MPC8548中斷控制器的工作原理需要實現(xiàn)以下3個功能:
一是,將中斷分離程序掛接到外部異常向量上。PowerPC處理器所有外部中斷共享同一個外部異常向量0x500,中斷分離程序的作用是識別中斷源,然后獲得中斷向量并調(diào)用中斷服務程序ISR。
二是,安裝鉤子函數(shù)。系統(tǒng)提供了3個鉤子函數(shù):中斷連接函數(shù)_func_intConnectRtn、中斷使能函數(shù)_func_intEnableRtn和中斷禁止函數(shù)_func_intDisableRtn。需根據(jù)中斷控制器工作原理編寫具有上述功能的3個函數(shù),然后指向對應的鉤子函數(shù)。
三是,禁止所有中斷。
(2)sysSerialHwInit()函數(shù)。該函數(shù)在sysSerial.c文件中實現(xiàn),負責處理器引腳配置和串口控制器配置。MPC8548處理器外部引腳是復用的,需要分為3步來執(zhí)行初始化:將串口控制器對應的引腳配置為串口使用;配置串口工作模式及速率;為串口驅動分配收/發(fā)緩沖。
2.2.4 sysHwInit2()函數(shù)
該函數(shù)位于sysLib.c文件,其負責連接系統(tǒng)中斷,初始化其它必要的配置[10]。在初步開發(fā)時,平臺外部設備只使用串口模塊,sysHwInit2()函數(shù)只需要調(diào)用串口中斷掛載函數(shù)sysSerialHwInit2(),該函數(shù)在sysSerial.c文件中實現(xiàn),實現(xiàn)方法是:根據(jù)所使用串口的中斷號,調(diào)用系統(tǒng)函數(shù)intConnect()將中斷處理程序注冊到系統(tǒng)中斷向量表中。
BSP開發(fā)過程中最常用的一種調(diào)試方法是ICE調(diào)試法,如圖4所示。其過程是仿真頭插在用戶板的CPU位置上,然后在仿真器RAM中或目標機RAM中下載好被調(diào)試的VxWorks鏡像。ICE調(diào)試法的原理為:在具體硬件平臺上運行仿真器的CPU來調(diào)試軟件。
圖4 IDE調(diào)試法
rominit.s中有少量的初始化操作,這些操作是為載入VxWorks鏡像服務的,在能夠保證正常載入鏡像的情況下要使rominit.s中的初始化操作盡量的精簡。實際上絕大部分初始化任務要由sysHwInit()函數(shù)來完成。
函數(shù)malloc()不能在調(diào)試階段調(diào)用。這是由于malloc()屬于緩沖區(qū)函數(shù),在內(nèi)存分配的初始化還未完成時調(diào)用函數(shù)malloc()將導致系統(tǒng)崩潰。前文提到的intConnect()不能夠在sysHwInit()中被調(diào)用。
文中介紹了VxWorks BSP的組成和功能,并以MPC8548為核心的硬件平臺為例詳細介紹了BSP的開發(fā)過程。雖然針對不同的硬件平臺,BSP需要根據(jù)具體的硬件細節(jié)進行具體的設計,但是各類硬件平臺之間還是有一定的共性,故對VxWorks BSP的開發(fā)者有一定的借鑒作用。同時,“整體移植,局部修改”的開發(fā)方法對開發(fā)效率有明顯提高。
[1]陳智育,溫彥軍,陳 琪.VxWorks程序開發(fā)實踐[M].北京:人民郵電出版社,2004.
[2]周啟平,張 揚.VxWorks下設備驅動程序及BSP開發(fā)指南[M].北京:中國電力出版社,2004.
[3]Wind River.VxWorks kernel programmer's guide 6.4[EB/OL].http//www-ad.fnal.gov/controls/micro_p/manuals/vx-works_kernel_programmers_guide_6.4.pdf.2012-12-15.
[4]Wind River.VxWorks architecture supplement 6.4[EB/OL].http://www-ad.fna1.gov/controls/micro~/manu-als/vxworks-architecture supplemen_6.4.pdf.2012-12-10.
[5]王 齊.Linux PowerPc詳解-核心篇[M].北京:機械工業(yè)出版社,2007.
[6]Freescale.MPC8548E PowerQUICCTMⅢIntegrated Processor Family Reference Manual[EB/OL].http://cache.freescale.com/files/32bit/doc/ref_manual/MPC8548ERM.pdf.2012-12-8.
[7]王彥剛,呂遵明,萬留進.VxWorks系統(tǒng)的BSP設計與實現(xiàn)[J].計算機系統(tǒng)應用,2011,20(12):91-94.
[8]李 丹.E500 MMU架構研究及VxWorks下的優(yōu)化方案[J].計算機工程與應用,2010,48(30):56-61.
[9]Wind River.VxWorks architecture supplement 6.4[EB/OL].http://www-ad.fna1.gov/controls/micro~/manuals/vxworks-architecture_supplement_6.4.pdf.2012-12-8.
[10]張 忠,樊留群.VxWorks在S3C2410上的BSP設計[J].微型電腦應用,2005,21(10):16-19.