1 三種不同的VxWorks映象比較
VxWorks是一種靈活的、可裁剪的嵌入式實時操作系統。用戶可以根據需要創建自己的VxWorks映象,由它來引導目標系統,而後下載並運行應用程序。
根據應用場合的不同,VxWorks映象可分爲三類:可加載的VxWorks映象 、基於ROM的VxWorks映象 和駐留ROM的VxWorks映象 。
1.1 可加載的VxWorks映象
這是一種運行於RAM的VxWorks映象。它不包含搬移程序,需要藉助於一些外部的程序如bootRom才能加載到RAM的低端RAM_LOW_ADRS地址處。這是缺省的開發映象。
圖1、可加載的VxWorks映象 |
在開發的初期階段,用戶可以根據需要添加或刪除一些VxWorks組件,生成自己的可加載的VxWorks映象,存放在開發主機的某個目錄下。 目標板上電後,由燒結在BOOT中的起始引導程序(BootStrap Programs)將BOOT中的ROM引導程序(ROM Boot Programs)拷貝到RAM的高端地址RAM_HIGH_ADRS處,並跳轉至該地址執行ROM引導程序,配置好所選的加載方式(缺省爲網絡方式),將指定的主機目錄下的可加載的VxWorks映象下載到目標板的RAM地址RAM_LOW_ADRS處,並跳轉到此處執行。如圖1所示。
這種映象的優點 是生成的VxWorks映象可以存放在開發主機PC機上,不用燒到BOOT中,節省了BOOT容量,也便於隨時修改不同的VxWorks映象,適用於調試的初期階段。不足之處 是需要在主機上維護一個正確的VxWorks映象,對於調試硬件無關的上層應用程序顯得不是很方便。
在Tornado工作臺的Build窗口中,選擇Rules屬性頁中的VxWorks即可生成可加載的VxWorks映象。
1.2 基於ROM的VxWorks映象
圖2 基於ROM的VxWorks映象 |
這是一種運行於RAM中,但起初存放於ROM中的VxWorks映象。即該映象需要和搬移程序一起固化在BOOT中。目標板上電後,首先運行BOOT中的引導搬移程序,將整個VxWorks映象拷貝到RAM地址RAM_LOW_ADRS處,並跳轉到此處執行。如圖2所示。
該映象根據是否被壓縮又可分爲:
1.基於ROM的未壓縮的VxWorks映象,可直接從ROM拷貝到RAM中
2.基於ROM的壓縮的VxWorks映象,這種映象主要是爲了節約BOOT空間,在從ROM拷貝到RAM的過程中需要解壓縮,因此與上述未壓縮的映象相比,它的引導過程相對較慢,但兩者在RAM中的運行速度是一樣的。
1.3 駐留ROM的VxWorks映象
這種映象起初也和搬移程序一起固化在BOOT中。目標板上電後,首先運行BOOT中的引導搬移程序,但僅將VxWorks映象的數據段和BSS段 拷貝到RAM地址RAM_LOW_ADRS處,映象的代碼段仍舊留在ROM中,從ROM中開始執行。如圖3所示。
圖3 駐留ROM的VxWorks映象 |
這種映象的優點是具有最快的引導速度,佔用最少的RAM空間,適用於RAM空間有限的目標板。但是由於該映象在ROM中運行,運行速度在三種映象中是最慢的。
2 幾種不同的BOOTROM的比較
針對上述三種不同的VxWorks映象,可以生成以下幾種不同的BOOTROM,主要體現在執行搬移程序romStart( )( 位於bootInit.c文件中)時不同:
2.1 用於可加載VxWorks映象的BOOTROM
由圖1所示可知,用於可加載VxWorks映象的BOOTROM包含兩部分:起始引導程序(BootStrap Programs)和ROM引導程序(ROM Boot Programs)。
起始引導程序 駐留在ROM中,主要包含:
1.彙編級的硬件初始化程序romInit.s,用於系統的基本初始化,設置一些重要寄存器的初始值,進行存儲器的映射
2.搬移程序bootInit.c,將ROM引導程序拷貝至RAM的高端地址RAM_HIGH_ADRS,然後跳轉到此處執行ROM引導程序。
ROM引導程序 起初存放在ROM中,初始化時被拷貝到RAM中,主要用於系統的進一步初始化,並配置加載方式,將VxWorks映象加載至RAM。可分爲三種不同的類型:
1.壓縮的ROM引導程序,在拷貝的過程中需要解壓縮,在RAM中執行
2.未壓縮的ROM引導程序,可直接拷貝,在RAM中執行
3.駐留ROM的ROM引導程序,僅拷貝ROM引導程序的數據段,代碼段仍舊在ROM中執行
在Tornado開發環境中,通過在主窗口點擊Build|Build Boot ROM…可以選擇生成以上三種BOOTROM,分別爲:bootrom_uncmp.hex(未壓縮的BOOTROM),bootrom.hex(壓縮的BOOTROM),bootrom_res.hex(駐留的BOOTROM)。
靜態連接到可加載的VxWorks映象的系統初始化代碼執行並完成整個初始化過程。
引導過程成功以後,RAM中ROM引導程序佔用的空間(從RAM_HIGH_ADRS開始)可以重新被系統利用。
圖1中所示的各地址含義爲:
1.LOCAL_MEM_LOCAL_ADRS 是RAM的起始地址
2.RAM_LOW_ADRS 是VxWorks的加載點,也是VxWorks代碼段的起始位置
3.FREE_RAM_ADRS 是VxWorks映象的結束點。通常也是系統內存池和目標服務器內存池的起始地址
4.RAM_HIGH_ADRS 是ROM引導程序的加載點。它也是ROM引導程序(除駐留ROM引導程序之外)的代碼段的起始位置,或駐留ROM引導程序數據段的起始位置。
2.2 用於基於ROM的VxWorks映象的BOOTROM
由圖2所示可知,用於該映象的BOOTROM包含兩部分:起始引導程序(BootStrap Programs)和基於ROM的VxWorks映象。搬移程序bootInit.c負責將VxWorks映象的文本段和數據段搬移到用戶定義的低端內存地址RAM_LOW_ADRS,如果需要進行必要的解壓縮,然後直接啓動VxWorks映像。
因此BOOTROM的容量相對於2.1中描述的BOOTROM要大一些,但無需在主機目錄下維護一個可用的VxWorks映象。
基於ROM的VxWorks BOOTROM有壓縮和未壓縮之分。在Tornado工作臺的Build窗口中,選擇VxWorks映象Rules屬性頁中的VxWorks_rom即可生成基於ROM的未壓縮的VxWorks BOOTROM,選中VxWorks_romCompress即可生成基於ROM的壓縮的VxWorks BOOTROM。
2.3 用於駐留ROM的VxWorks映象的BOOTROM
由圖3所示可知,用於該映象的BOOTROM包含兩部分:起始引導程序(BootStrap Programs)和駐留ROM的VxWorks映象,VxWorks系統文本段駐留在ROM,搬移程序bootInit.c負責將數據段和bss段搬移到用戶定義的低端內存地址RAM_LOW_ADRS,直接啓動VxWorks映像(含符號表)。此時,RAM_LOW_ADRS是VxWorks映象的加載點,它也是VxWorks數據段的起始點。
在Tornado工作臺的Build窗口中,選擇VxWorks映象Rules屬性頁中的VxWorks_romResident即可生成駐留ROM的VxWorks BOOTROM。
3 VxWorks 的啓動過程
根據上述所採用的BOOTROM的不同,VxWorks的啓動過程會有所不同。
3.1 使用可加載VxWorks映象的啓動過程
此時,從目標板上電覆位到啓動用戶定義的任務的整個流程如下:
sysALib.s : sysInit( ) 鎖住中斷,關閉cache(如果使用了話),初始化處理器的寄存器(包括C堆棧指針)至缺省值 |
開始在RAM中運行VxWorks |
usrConfig.c : usrInit( ) 設置cache的工作模式,板級硬件初始化,初始化Win內核,啓動usrRoot( )
|
usrConfig.c : usrRoot( ) 初始化內存,系統時鐘,I/O系統,標準輸入輸出錯,異常處理,添加用戶應用程序
|
romInit.s : romInit 設置機器狀態字及其它硬件相關寄存器,關閉中斷,禁止程序和數據CACHE,初始化內存,並設置堆棧指針 |
bootInit.c : romStart( ) 將ROM中的程序搬移至RAM中 |
bootConfig.c : usrInit( ) 設置cache的工作模式,板級硬件初始化,調用sysHwInit( ),usrKernelInit( ),KernelInit( ),初始化Win內核,產生根任務usrRoot( ) |
bootConfig.c : usrRoot( ) 初始化內存,系統時鐘,I/O系統,標準輸入輸出錯,異常處理,產生任務bootCmdLoop |
bootConfig.c : bootCmdLoop( ) 調用自動引導程序autoboot( ),此函數若成功則不返回 |
bootConfig.c : autoboot( ) 延時7s,以默認參數啓動 |
用戶按鍵中斷 |
bootConfig.c :bootCmdLoop( ) 啓動命令行用於配置VxWorks啓動參數 |
bootConfig.c : bootLoad( ) 加載VxWorks映象,並轉向它進行重啓 |
等待超時 |
用戶輸入‘@ ’ |
BootStrap程序 在ROM中執行 |
ROM Boot程序 被搬移到RAM中執行 |
3.1.1 BOOTROM 的啓動過程
1、目標板加電之後,程序指針指向RESET中斷程序入口處,開始執行初始化程序romInit.s,設置機器狀態字及其它硬件相關寄存器,關閉中斷,禁止程序和數據CACHE,初始化內存,並設置堆棧指針,保存啓動類型,調用romStart( )。
2、 程序跳到第一個C程序bootInit.c的函數romStart( )入口地址,根據堆棧中的參數決定是否清零內存RAM(如是冷啓動(cold start)則清零),根據不同的bootrom文件,把ROM中數據段和文本段拷貝到RAM(如果ROM代碼是壓縮的,還要解壓);
3、 程序跳到RAM入口地址(文件bootConfig.c中函數usrInit( ) ),根據用戶配置來設置cache的工作模式,清零bss段,初始化異常處理程序,進行板級硬件初始化sysHwInit( )。
4、 啓動多任務內核KernelInit( ),執行usrRoot任務。在該任務中初始化串口,創建console終端設備。創建bootCmdLoop任務,根據單板設計選擇不同方式加載VxWorks映像文件,如通過串口、網口、硬盤等方式。
3.1.2 VxWorks 映象的啓動過程
VxWorks 進入點sysInit()
啓動VxWorks系統的第一步就是將系統映象加載到主內存。這通常是在VxWorks boot Rom 的控制下,從開發主機上下載。接着,boot Rom將控制權交給VxWorks的起始進入點:sysInit()。在makefile和 config.h文件裏,已將這個進入點設置成位於地址RAM_LOW_ADRS。
函數sysInit()位於系統特定的彙編語言模塊sysALib.s中。它可以鎖住中斷,關閉cache(如果使用了話),初始化處理器的寄存器(包括C堆棧指針)至缺省值。它還會關閉跟蹤,清除所有未決的中斷,並調用一個位於usrConfig.c 模塊的C語言子程序:usrInit() 。對於某些目標板,sysInit()還執行一些必要的與系統有關的硬件初始化,以便在usrInit()中執行完剩餘的初始化內容。僅供usrInit()使用的初始堆棧指針,被設置成位於系統映象(RAM_LOW_ADRS)以下,向量表以上的位置。
初始化代碼usrInit()
函數usrInit()(位於usrConfig.c中),儲存有關引導類型的信息,處理在內核啓動之前必須執行的初始化,而後啓動內核執行。它是運行於VxWorks內的第一個C函數。此時,所有的中斷都已被鎖住。
許多VxWorks工具在usrInit( )中都不能使用。這是因爲此時還沒有任務的上下文(沒有TCB和任務堆棧),那些需要任務上下文的工具無法被調用。函數usrInit( )僅做一些創建初始化任務usrRoot( )所必須的工作。然後由usrRoot( )完成啓動過程。
usrInit( ) 中的初始化過程如下所述:
Cache初始化
usrInit( ) 的起始代碼初始化cache,設置cache 模式,並將cache放置在一個安全的位置。在usrInit( )結束時,缺省情況下,指令cache和數據cache被使能。
對系統的BSS段清零
C 和C++語言規定所有未初始化的變量缺省的初始值爲零。這些未初始化的變量被放置在一個稱爲bss的段內。由於usrInit( )是系統執行的第一個C代碼,在它的一開始對包含bss段的內存清零。VxWorks的boot ROM 也會清內存,但VxWorks映象假設沒有采用boot ROM,仍然執行清內存的操作。
初始化中斷向量
異常向量必須在使能中斷和啓動內核之前建立。首先,調用intVecBaseSet( ) 建立向量表基地址。而後,調用excVecInit( ) 初始化所有的異常向量至缺省句柄,以便安全地捕獲和報告由程序錯誤或意外的硬件中斷導致的異常。
初始化硬件至靜止狀態
通過調用系統相關函數sysHwInit( )初始化系統硬件。該函數復位並關閉那些在中斷使能(內核啓動時)以後可能產生中斷的硬件設備。這一點很重要,因爲VxWorks ISRs(用於I/O設備,系統時鐘等)直到在任務usrRoot( )中完成系統初始化以後,才被連接到它們的中斷向量上。不要在sysHwInit( ) 調用中試圖爲一箇中斷連接一箇中斷句柄(也就是不能使用intConnect( )),因爲此時內存池還沒有初始化。
初始化內核
函數usrInit( )結束時調用了兩個內核初始化函數:
usrKernelInit( ) (在usrKernel.c中定義)爲每個指定的可選內核組件調用合適的初始化代碼。詳見表1。
kernelInit( ) (kernelLib.c的一部分)初始化多任務環境,不用返回。函數參數包括:
l 用以產生作爲根任務的應用程序,典型的爲usrRoot( )
l 使用的堆棧大小
l 可用的起始內存地址,一般位於VxWorks映象的代碼段,數據段和bss 段之後,如果包含可選的主機內存池,則還要加上WDB_POOL_SIZE。
l 由sysMemTop( )定義的內存頂部
l 中斷堆棧的大小
l 中斷封鎖級別
kernelInit( ) 調用intLockLevelSet( ),關閉循環模式,創建一箇中斷堆棧(如果結構支
持的話)。然後從內存池的頂部創建一個根堆棧和TCB,創建一個根任務,usrRoot,並終止usrInit( )線程的執行。此時使能中斷,所有的中斷源已被關閉,未決中斷已被清除。
初始化內存池
內存池的初始化是由kernelInit( )來完成的。kernelInit( ) 的參數指定了初始內存池的起始和終止地址。在缺省的usrInit( )中,將內存池設置在緊接於引導的系統映象之後,幷包含所有剩餘的可用內存。
可用內存的大小由sysMemTop( )決定。如果你的系統有其它的不連續的內存片,你可以在usrRoot( )任務中通過調用memAddToPool( )將它們包含進通用的內存池。
VxWorks包含了一個位於memPartLib模塊中的內存分配工具,它管理一個可用內存池。用戶可以調用malloc( )函數從內存池中獲得可變大小的內存塊。VxWorks也利用malloc( )函數來動態分配內存。許多VxWorks工具在初始化過程中需要分配數據結構。因此,內存池必須在任何其他的VxWorks工具初始化之前初始化。
Tornado目標服務器也管理一部分目標內存以支持目標模塊的下載和其他開發功能。VxWorks使用malloc( )函數爲已下載的模塊分配空間,爲已產生的任務分配堆棧,在初始化時分配數據結構。用戶也可以使用malloc( )函數爲自己的應用程序分配所需的內存空間。因此,推薦將所有的未用內存分配給VxWorks內存池,除非必須爲一個特殊的應用保留一片固定的絕對內存。
初始任務usrRoot( )
當多任務內核啓動執行以後,所有的VxWorks多任務工具就可以用了。控制權被傳送至usrRoot( )任務,並完成初始化系統。
usrRoot( ) 執行以下操作:
l 初始化系統時鐘
l 初始化I/O系統和驅動
l 創建控制檯設備
l 設置標準輸入和標準輸出
l 安裝異常處理和登陸
l 初始化管道驅動器
l 初始化標準I/O
l 創建文件系統設備並安裝磁盤驅動器
l 初始化浮點支持
l 初始化性能監視工具
l 初始化網絡
l 初始化可選的工具
l 初始化WindView
l 初始化目標代理
l 執行一個用戶提供的啓動腳本
l 初始化VxWorks Shell
下面對各個步驟進行詳盡的描述:
初始化系統時鐘
usrRoot( ) 任務執行的第一個操作就是初始化VxWorks時鐘。通過調用sysClkConnect( )
將系統時鐘的中斷向量連接到usrClock( )函數上。調用sysClkRateSet( )將系統時鐘率設置爲60Hz。
sysClkConnect( ) 函數調用sysHwInit2( )。風河的BSP採用sysHwInit2( )執行在sysHwInit( )中未完成的進一步的板級初始化。例如,可以利用intConnect( )連接ISR,因爲此時已經分配了內存,系統處於多任務環境。
初始化I/O系統
如果在configAll.h中定義了INCLUDE_IO_SYSTEM,就可以調用iosInit( )函數初始化VxWorks的I/O系統。該函數的參數指定了可被順序安裝的最大驅動器的數目,可以在系統中同時打開的最大文件數目,和VxWorks的I/O系統包含的“空”設備的名字。
包含或去除INCLUDE_IO_SYSTEM還會影響是否創建控制檯設備,是否設置標準的輸入、輸出和標準的出錯信息。
創建控制檯設備
如果包含了板上串口驅動器(定義了INCLUDE_TTY_DEV),就可以通過調用驅動器的初始化函數(典型的是ttyDrv( ))將它安裝進I/O系統。實際的設備是通過調用驅動器的設備創建函數(典型的是ttyDevCreate())來創建和命名的。這個函數的參數包括設備名稱,一個串行I/O通道描述字(從BSP獲得),和輸入輸出緩存大小。
宏NUM_TTY定義了tty口的數量(缺省是2)。宏CONSOLE_TTY指定了哪個口作爲控制檯口(缺省是0),宏CONSOLE_BAUD_RATE指定了其比特率(缺省是9600 bps)。這些宏都在configAll.h中定義,但對於那些具有非標口數的單板可以在config.h中對它們進行重新定義。
設置標準輸入、標準輸出和標準出錯信息
系統級的標準輸入、標準輸出和標準錯誤信息的配置是通過打開控制檯設備並調用ioGlobalStdSet( )來建立的。這些配置作爲VxWorks的缺省設備用於與應用開發人員通訊。爲了使控制檯設備成爲一個交互式的終端,調用ioctl( )將設備選項設爲OPT_TERMINAL。
安裝異常處理和登錄
初始化VxWorks的異常處理工具(由excLib模塊提供)和登錄工具(由logLib庫提供)。這些工具檢查在根任務內部或者初始化各種工具時產生的程序錯誤。
當定義了宏INCLUDE_EXC_HANDLING和INCLUDE_EXC_TASK後,調用excInit( )初始化異常處理工具。excInit( ) 函數產生一個異常支持任務excTask( )。初始化以後,可以安全地捕獲和報告導致硬件異常的程序錯誤,報告並解除沒有初始化向量的中斷。當定義了INCLUDE_SIGNALS後,調用sigInit( )初始化VxWorks的信號工具,該工具用於任務的異常處理。
當定義了INCLUDE_LOGGING宏以後,調用logInit( )初始化登錄工具。其參數定義了顯示登錄信息的設備的文件描述字,和分配的登錄信息緩存數。登錄初始化還創建了一個登錄任務logTask( )。
初始化管道驅動
如果需要所謂的管道,在configAll.h中定義INCLUDE_PIPE,就會自動地調用pipeDrv( )初始化管道。而後任務就可以利用管道通過標準的I/O接口互相通訊了。管道必須由pipeDevCreate( ) 函數創建。
初始化標準I/O
當定義了宏INCLUDE_STDIO以後,VxWorks 就會包含一個可選的標準I/O包。
創建文件系統設備並初始化設備驅動
許多VxWorks配置至少包含一個磁盤驅動器,或帶有dosFs/rt11Fs/rawFs文件系統的RAM磁盤。首先,通過調用驅動器的初始化代碼安裝一個磁盤驅動器。而後,驅動器的設備創建代碼會定義一個設備。這個調用會返回一個指向描述設備的BLK_DEV結構的指針。
然後就可以調用文件系統的設備初始化代碼-dosFsDevInit( ), rt11FsDevInit( ), or rawFsDevInit( )(如果定義了宏INCLUDE_DOSFS, INCLUDE_RT11FS和INCLUDE_RAWFS)初始化和命名設備。在初始化一個設備之前,必須用dosFsInit( ), rt11FsInit( )或 rawFsInit( )初始化文件系統模塊。文件系統的設備初始化函數的參數取決於特定的文件系統,但典型的包括設備名稱,由驅動器的設備創建代碼產生的一個指向BLK_DEV結構的指針,可能還有一些文件系統特定的配置參數。
初始化浮點支持
如果在configAll.h中包含了INCLUDE_FLOATING_POINT宏定義,則調用floatInit( )函數初始化浮點I/O支持。當定義了INCLUDE_HW_FP,調用mathHardInit( )初始化對浮點協處理器的支持。當定義了INCLUDE_SW_FP,調用mathSoftInit( )初始化對軟件浮點仿真的支持。
包含性能仿真
VxWorks具有兩個內嵌的性能監視工具。一個由spyLib提供的任務活動綜述,一個由timexLib提供的子程序執行定時器。如果在configAll.h中定義了宏INCLUDE_SPY 和INCLUDE_TIMEX,就會包含這些工具。
初始化網絡
如果配置頭文件中定義了INCLUDE_NET_INIT,usrRoot( )就會調用usrNetInit( )函數初始化網絡(usrNetInit( )的源代碼位於installDir/target/src/config/usrNetwork.c)。usrNetInit( )函數使用了一個配置字符串作爲它的參數。這個配置字符串通常是一條“引導行”,用於VxWorks的boot ROM引導系統。根據這個字符串,usrNetInit( )函數執行以下操作:
l 調用netLibInit( )初始化網絡子系統
l 連接並配置合適的網絡驅動器
l 添加網關路由
l 初始化遠程文件存取驅動器netDrv,並添加一個遠程文件存取設備
l 初始化遠程登錄工具
l 可選地初始化遠端程序調用(RPC)
l 可選地初始化網絡文件系統(NFS)工具
如前所述,是否包含這些網絡工具由configAll.h中的宏定義決定。
初始化可選產品和其它組件
可選產品VxMP可提供共享內存目標。如果定義了宏INCLUDE_SM_OBJ,usrRoot( )
就會調用usrSmObjInit( )函數(源代碼位於installDir/target/src/config/usrSmObj.c),初始化共享內存目標。
共享內存目標庫需要VxWorks引導行中的域值。這些函數包含在usrNetwork.c文件中。如果不包含網絡服務,usrNetwork.c就不會被包含,共享內存初始化就會失敗。工程工具計算所有的依存關係,但如果使用手工配置,可以將INCLUDE_NETWORK添加進configAll.h,或是從usrNetwork.c文件中將引導行代碼提取出來放置到其他地方。
如果定義了INCLUDE_MMU_BASIC,就可以提供基本的MMU支持。如果定義了INCLUDE_MMU_FULL,可選產品VxVMI就可以提供代碼保護,向量表保護和一個虛擬內存接口。MMU由函數usrMmuInit( )初始化,該函數位於installDir/target/src/config/usrMmuInit.c文件中。如果還定義了宏INCLUDE_PROTECT_TEXT 和INCLUDE_PROTECT_VEC_TABLE,就會初始化代碼保護和向量表保護。
初始化WindView
可選產品WindView可提供內核測試工具。如果在configAll.h中定義了宏INCLUDE_WINDVIEW,就可以在usrRoot( )中調用windviewConfig ( )初始化WindView。其它的WindView常量控制特定的初始化步驟。
初始化目標代理
如果定義了INCLUDE_WDB,調用函數wdbConfig( )(位於installDir/target/src/config/usrWdb.c)。這個函數初始化通訊接口,然後啓動代理。
執行一個啓動腳本
如果VxWorks配置了目標駐留的shell,定義了INCLUDE_STARTUP_SCRIPT,並且在boot引導過程中在啓動腳本參數中輸入了腳本文件的名稱,usrRoot( )函數就可以執行一個用戶提供的啓動腳本。如果在引導過程中忽略了啓動腳本參數,就不會執行啓動腳本。
表1、可加載VxWorks映象的初始化過程
函 數 |
函 數 功 能 |
所 在 文 件 |
sysInit() |
(a)鎖住中斷;(b)禁用緩衝; (c)用缺省值初始化系統中斷表(僅i960); (d)用缺省值初始化系統錯誤表(僅i960); (e)初始化處理器寄存器到一缺省值; (f)使回溯失效;(g)清除所有懸置中斷; (h)激活usrInit(),指明啓動類型。 |
sysALib.s |
usrInit() |
a)對bss清零; (b)保存bootType於sysStartType; (c)調用excVecInit(),初始化所有系統和缺省中斷向量; (d)依次調用sysHwInit(), usrKernelInit(),kernelInit(). |
usrConfig.c |
usrKernelInit() |
依次調用classLibInit(),taskLibInit(),taskHookInit(),semBLibInit(),semMLibInit(), semCLibInit(),semOLibInit(),wdLibInit() msgQLibInit(),qInit(),workQInit() |
usrKernel.c |
kernelInit() |
初始化並啓動內核。 (a)激活intLockLevelSet(); (b)從內存池頂部創建根堆棧和TCB;(c)調用taskInit(), taskActivate(),用於usrRoot(); (d)調用usrRoot(). |
kernelLib.h |
usrRoot() |
初始化I/O系統,驅動器,設備(在configAll.h和config.h中指定) (a)調用sysClkConnect(),sysClkRateSet(), iosInit(),[ttyDrv()]; (b)初始化excInit(),logInit(),sigInit(). (c)初始化管道,pipeDrv(); (d)stdioInit(),mathSoftInit()或mathHardInit() (e)wdbConfig():配置並初始化目標代理機 |
usrConfig.c |
3.2 使用基於ROM的VxWorks映象的啓動過程
此時BOOTROM中包含了引導程序和VxWorks映象。VxWorks的入口點由兩個函數
romInit()和romStart()來完成,而非sysInit()。具體過程如表2所示。
表2、基於ROM的VxWorks映象的啓動過程
函 數 |
函 數 功 能 |
所 在 文 件 |
1.romInit() |
(a)禁止中斷; (b)保存啓動類型; (c)硬件初始化; (d)調用romStart(); |
romInit.s |
2.romStart() |
(a)將數據段從ROM拷貝到RAM,清內存; (b)將代碼段從ROM拷貝到RAM,有必要的話解壓縮; (c)依據引導類型調用usrInit(); |
bootInit.c |
3.usrInit() |
初始化程序 |
usrConfig.c |
4.usrKernelInit() |
如果相應的配置文件被定義,對應函數被調用 |
usrKernel.c |
5.kernelInit() |
初始化並啓動內核 |
kernelLib.h |
6.usrRoot() |
初始化I/O系統,驅動器,創建設備 |
usrConfig.c |
7.Application routine |
應用程序代碼 |
應用程序源文件 |
使用駐留ROM的VxWorks映象的啓動過程與此類似,只是在執行搬移程序romStart( )有所不同。
4 主要文件及宏開關介紹
以est8260評估板爲例,說明編制BSP軟件所涉及的主要文件及宏開關。
4.1 Makefile 文件
位於BSP文件目錄下的編譯文件Makefile,定義了啓動文件bootrom首地址及大小,以及編譯時調用的函數庫,VxWorks映像文件的加載地址,用戶需增加的目標模塊。
該文件中的主要宏定義:
CPU = PPCEC603 目標板的CPU類型,MPC750爲PPC604,MPC8260爲PPCEC603
TOOL = gnu 主機工具爲基於GNU的工具,用戶不必修改
TGT_DIR = $(WIND_BASE)/target
target所在目錄(WIND_BASE)已在torVars.bat中指定,爲Tornado的安裝目錄
include $(TGT_DIR)/h/make/defs.bsp 定義編譯選項
include $(TGT_DIR)/h/make/make.$(CPU)$(TOOL) 即文件make.ppc860gnu
include $(TGT_DIR)/h/make/defs.$(WIND_HOST_TYPE)
即defs.x86-win32,定義和主機操作平臺相關的工具
注意: 只能在這個位置之後重新定義make的定義。
TARGET_DIR = est8260 目標板BSP目錄名,用戶需指定爲目標板BSP文件所在目錄
VENDOR = EST 目標板製造商,和BSP程序無關,作註釋用
BOARD = est8260 Evaluation SBC 目標板名,和BSP程序無關,作註釋用
BOOTINIT = bootInit.c
USRCONFIG = usrConfig.c
系統編譯bootrom時會自動編譯用戶BSP文件目錄下的usrConfig.c和bootInit.c,缺省文件位於All目錄下。
以下地址值都爲十六進制值,無需加入0x前綴。在config.h和Makefile中都定義了ROM_TEXT_ADRS, ROM_SIZE, RAM_HIGH_ADRS等常量,在2個文件中的對常量的定義要求一致。
ROM_BASE_ADRS = fff00000 ROM的物理起始點
ROM_TEXT_ADRS = fff00100 根啓動設備Boot ROM首地址
ROM_SIZE = 00080000 BOOTROM大小(512K)
LOCAL_MEM_LOCAL_ADRS = 00000000 RAM的物理起始點
LOCAL_MEM_SIZE = 01000000 RAM大小(16M)
RAM_LOW_ADRS = 00100000 加載VxWorks的目標地址
RAM_HIGH_ADRS = 00a00000 拷貝boot ROM文本段和數據段的目標地址
HEX_FLAGS = -a $(ROM_TEXT_ADRS) Hex文件轉化爲bin文件的執行程序參數
MACH_EXTRA = m8260CpmEnd.obj 用戶加入的目標模塊名,後綴爲obj
LDFLAGS = -X -N -Map est8260.map 在連接標識中增加-M est8260.map可以在BSP目錄下生成包含編譯信息的est8260.map文件。
注意:只能在這個位置之前重新定義make的定義。
include $(TGT_DIR)/h/make/rules.bsp
include $(TGT_DIR)/h/make/rules.$(WIND_HOST_TYPE)
定義編譯各種BSP文件的生成規則
4.2 all/ConfigAll.h 文件
此文件包含了適用於所有目標板的缺省定義。主要定義了以下選項和參數:
內核配置參數
I/O系統參數
NFS 參數
選擇可選的軟件模塊
選擇可選的設備控制器
cache模式
最大數量的不同共享內存目標
設備控制器I/O地址,中斷向量和中斷級別
4.3 config.h 文件
此文件位於BSP目錄下,包含僅適用於特定目標板的定義,還可以對configAll.h中的缺省定義進行重定義。其主要內容爲:
1、BSP版本號
#define BSP_VER_1_1 1
#define BSP_VERSION "1.2"
#define BSP_REV "/4"
2、configAll.h 包含文件,應放在BSP_VERSION和BSP_REV定義之後
#include "configAll.h"
3、定義缺省的BOOT引導設備
#define DEFAULT_BOOT_DEVICE CPM_END
4、定義網絡控制器
#define INCLUDE_CPM ;使用SCC以太網控制器
5、定義缺省的BOOT引導參數
#define DEFAULT_BOOT_LINE /
"$dev(0,procnum)host:dir//file h=# e=# b=# g=# u=usr pw=passwd f=# tn=targetname s=script o=other"
$dev -- boot device,啓動的設備類型,必須是已包含的設備。
procnum -- 處理器序號,一般從零開始。
host -- 主機名
dir://file -- 被加載的VxWorks文件所在的完整路徑
h -- 主機IP
e -- 目標板IP
b -- 背板IP,用戶可不定義
g -- 網關,用戶可不定義
u -- 用戶名
pw -- 登錄口令
f -- 定義網絡加載方式。無此項時缺省值爲零,爲FTP
tn -- 目標板名
s -- 啓動描述字符串,用戶可不定義
o -- 從SCSI啓動時指明網絡接口
依據不同的啓動設備類型,其中某些項可無。例如:
#define DEFAULT_BOOT_LINE /
"motec(0,0)diags:c://vxWorks h=172.96.36.88 e=172.96.78.23 g=172.16.0.1 u=anonymous pw=user f=0x00 tn=est8260"
6、 緩衝和MMU工作方式
#define INCLUDE_CACHE_SUPPORT
#define USER_I_CACHE_ENABLE
#define USER_D_CACHE_ENABLE
#define INCLUDE_MMU_BASIC
#define USER_I_MMU_ENABLE
#define USER_D_MMU_ENABLE
7、包含必要的網絡驅動
#define INCLUDE_NETWORK
#define INCLUDE_END
8、 定義內存地址和大小
應與Makefile中的定義一致
#define USER_RESERVED_MEM 0x00000000 目標板用戶保留內存大小
#define ROM_WARM_ADRS (ROM_TEXT_ADRS+8)
熱啓動地址,爲ROM_TEXT_ADRS的一個偏移量,由啓動文件romInit.s中跳轉語句 bl start相對第一條執行語句的偏移量 。
4.4 target.h 文件
本文件定義和目標板硬件相關的宏。用戶應根據目標板硬件對時鐘頻率、內存空間分配、串口數目等進行設置。
4.5 romInit.s 文件
此文件是系統上電運行的第一個程序,也是製作BOOTROM時需要重點修改的程序,與硬件配置緊密相關。
可能需要修改:
機器狀態寄存器MSR
內部存儲器映像寄存器IMMR
總線配置寄存器BCR
60x總線總裁配置寄存器PPC_ACR
系統保護控制寄存器SYPCR
SIU模式配置寄存器SIUMCR
選項寄存器ORx,基址寄存器BRx
60x總線分配SDRAM 刷新時間PSRT
60x總線SDRAM模式寄存器PSDMR
4.6 all/bootConfig.c 和SysALib.s
一般用戶不需修改,也可根據需要修改。
4.7 sysSerial.c
提供串口初始化的系統接口函數,定義串行通道參數和中斷號等。串口設備驅動程序位於目錄/tornado/target/src/drv/sio。根據用戶所採用的串口及硬件連接作相應修改。
4.8 sysNet.c
一般只需修改網絡設備初始化部分,如MPC8260中爲函數sysFccEnetEnable()或sysCpmEnetEnable( )。
網口和串口的驅動設計可參見相關的專題。
5 使用Tornado工程工具編譯VxWorks映象
以上所述都是在行編譯環境下生成BOOTROM或是VxWorks的情況,此時需要手工編譯Makefile文件。使用Tornado開發環境提供的工程工具編譯VxWorks映象時,可以由工程工具根據用戶在工程中的操作自動生成Makefile文件。
使用工程工具編譯的VxWorks映象與使用行命令編譯時有所不同:
1、當使用Tornado生成可引導的VxWorks映象時,它會自動分析config.h,得到prjComps.h,這個文件在工程中根據用戶對組件的刪除和添加會自動更新。如果在行命令下編譯VxWorks,prjComps.h是不起作用的。
2、 usrConfig.c是在行命令下編譯VxWorks使用的文件,與configAll.h一一對應,prjConfig.c是建立工程時自動生成的,prjComps.h對應。
3、使用了Tornado的工程工具以後,生成VxWorks映象只使用prjConfig.c,而不用usrConfig.c了。
4、 Tornado產生一個工程時,是以BSP爲依據的,最初是完全一致的,之後會根據用戶的配置而改變。