徐 帥,林寶軍,劉迎春,趙 帥
(1.中國科學院空天信息創新研究院,北京 100094;2.中國科學院大學,北京 100094;3.中國科學院微小衛星創新研究院,上海201203;4.上海科技大學信息科學與技術學院,上海 201203)
2018年,北斗三號導航衛星系統完成19顆衛星發射、組網基本系統的建成,可以向全球提供服務[1]。至2020年底,北斗導航系統將全面建成,30顆衛星在軌組網運行,向全球提供定時、測速、授時的導航功能。北斗三號衛星配備了Ka頻段星間鏈路,1顆衛星可與多顆衛星建鏈[2],未來可能還會搭載通信速率更快的激光星間鏈路,使得星間通信速率從幾百Kb/s提升至1 Gb/s。隨著星間鏈路的廣泛應用,大量的遙控、遙測、導航和測量等數據由星間鏈路傳輸至每一顆衛星的星載計算機內進行處理,衛星網絡也需要傳輸和處理網絡管理信息,這些都對星上計算機系統的性能提出了更高要求。文獻[3]中提出了基于星間鏈路的集中式自主導航算法,配合星間鏈路的高速率數據傳輸,在同等周期下,星載計算機需要處理和存儲更多的數據,配備更快的通信接口。這些都對現有CPU的頻率、存儲、數據接口提出了挑戰,軟件方面也需要設計復雜算法,搭建高速數據存儲交互的基礎環境。
2018年中國科協年會中楊長風總設計師提出了北斗導航系統未來瞄準PNT(Positioning Navigation Timing)體系[4],實現更高精度的導航,信息更多元化,空天地一體化。可以預見,北斗衛星的星載計算機處理能力仍將不斷提升。
國產星載計算機的發展比國外起步晚,最早多采用運行能力只有幾MIPS的處理器,目前中國科學院研制的北斗衛星在軌星載計算機,采用一種基于核心部件全部自主可控的高運算性能和高數據傳輸性能的方案,即以龍芯中科公司生產的龍芯1E高性能宇航級處理器芯片為主構建硬件環境,采用32位龍芯2號處理器,2 MB Flash和128 MB SDRAM存儲架構,以1553B總線為通信接口。
星載操作系統經過了由簡單順序執行的無系統模式到功能強大的實時操作系統VxWorks的發展過程,其優越的實時性和可裁剪內核等優勢使其在星載操作系統中成為標桿。目前,星載操作系統多運行在較低頻率和小存儲空間的星載計算機中[5],在設備驅動方面,外設驅動采用由應用程序直接調用的管理方式,需要設計更多面向高頻高速多接口的星載計算機操作系統管理方案。
為適應類似新需求,星載計算機將采用升級的新型龍芯1E高性能處理器芯片,通信峰值速率提升100倍,處理峰值速度提升2倍[6]。在軟件方面,對星上軟件和操作系統VxWorks 6.8進行移植,同時為配合衛星網絡通信需求,并保證其可靠性、獨立性,將外設驅動修改為由內核管理,為多線程多任務運行創建軟件基礎。
本文將對VxWorks 6.8進行板級支持包BSP(Board Support Package)開發[7]、移植操作系統到新型1E芯片,在設備驅動開發中采用新型VxBus型架構[8],并配置操作系統組件。
新型龍芯1E芯片具有頻率更高、處理速度更快等優點,處理器核采用64位雙發射龍芯2號GS232,峰值頻率由以前的100 MHz提升到200 MHz,定點峰值性能從200 MIPS提升到400 MIPS,較上一代芯片處理速度有成倍的提升;SDRAM空間提升至256 MB;通信接口方面除傳統的1553B外,還配備了SpaceWire高速通信接口,峰值速度從1 Mb/s提升到200 Mb/s。SpaceWire和DMA相結合,可實現遠程訪問內存的功能。
軟件需采用一個較好的解決方案實現相應的移植開發:
(1)軟件開發環境、編譯方法。
星上軟件目前開發環境為代碼閱讀器+命令行編譯。該方式有以下缺點:對復雜工程管理不足,對應用程序開發和調試不友好,對VxWorks內核和驅動等組件添加、刪除不方便等。并且未來星載計算機發展到多核CPU后,該編譯方式不能支持VxWorks對稱多處理器SMP(Symmetrical Multi-Processing)編譯。對于VxWorks 6.8的編譯,風河公司推出WorkBench編譯器作為開發工具,該編譯器界面友好,方便對BSP[8]、內核、驅動、應用程序實現相互獨立開發,適合管理復雜的星載軟件工程。在系統組件方面可以實現一鍵添加和刪除,大大提升了開發效率。
(2)驅動程序管理方式。
星載計算機驅動程序管理方式分為3類:應用程序直接管理、通過內核調用驅動、通過系統擴展模塊調用驅動程序(例如網絡)。文獻[9]中指出由應用程序直接管理代碼效率高,實時性較高,但面向多核多線程運算時這種驅動模式可能會造成緩存數據沖突,產生死鎖等問題。本文采用風河公司推出的VxBus型驅動架構管理驅動程序,該架構對設備管理結構更清晰,開發更簡便,可在WorkBench編譯器中配置,在層次上VxBus型驅動和內核、應用程序獨立,為其他層次提供統一接口,具有更好的可靠性、可移植性等優點,為應用層開發提供便利。
(3)對新型1E芯片硬件環境適配。
本文硬件平臺選用新型芯片,在操作系統移植過程中,對硬件環境做相應的適配:配合更大數據存儲和計算需求,內存管理增加VxWorks 任務棧、中斷棧空間等VxWorks系統管理空間,并采用VxBus型驅動管理中斷驅動,在系統啟動時對相應組件和中斷向量表進行配置。為支持自主導航算法中大量浮點等復雜計算和C++編譯環境,在VxWorks啟動階段配置協處理器開啟浮點計算,在操作系統初始化階段添加C++組件。
板級支持包BSP,顧名思義,它是應用于操作系統和硬件資源之間的相關軟件集合。其主要功能是配置硬件,為操作系統屏蔽硬件,使得上層軟件開發不需配置底層,并且在此基礎上,BSP要完成操作系統的引導和啟動,外設驅動和內核初始化等任務,使得操作系統可以運行在不同的硬件環境中。從層次上分,BSP也屬于操作系統的一部分,如圖1所示。

Figure 1 VxWorks operating system structure圖1 VxWorks操作系統結構圖
考慮到本文開發的BSP應用在星載系統中,在保證安全有效存儲操作系統鏡像前提下,對開發做出以下前提聲明:
如圖2所示,BootLoad存放在NandFlash中,通過BootLoad下載并引導操作系統,引導過程中,將操作系統拷貝到RAM_LOW_ADRS的位置運行。引導結束后,將執行權交給VxWorks操作系統,開始進行系統初始化[10]。

Figure 2 Storage structure of VxWorks圖2 VxWorks存儲結構
圖3所示為從函數級描述操作系統啟動過程,BootLoad將程序指針跳轉到RAM_LOW_ADRS后執行sysInit(),對CPU進行基礎初始化,進而在usrInit()中通過接口sysHwInit()和KernelInit()對硬件設備和操作系統內核進行初始化,之后運行usrRoot()完成內核組件創建并跳到應用層,執行應用程序[11]。

Figure 3 VxWorks startup process圖3 VxWorks啟動流程
本文采用風河公司推出的VxWorks 6.8操作系統,編譯環境采用適用于復雜項目管理、具有良好調試功能的WorkBench 3.2,滿足星載系統軟件開發需求。在系統啟動階段,啟動新型龍芯1E芯片的協處理器1,以增強浮點運算能力,并添加C++、VxBus等系統組件,為復雜算法搭建軟件基礎。采用VxBus型驅動架構管理串口等外部設備。在中斷管理方面,利用VxBus型架構分層管理中斷驅動。將內存分配為VxWorks管理和靜態管理2部分,并增加VxWorks管理區域,充分利用新型1E龍芯芯片的存儲空間。
在VxWorks BSP開發中,從文件角度需要編寫以下組件:
(1)Config.h。
Config.h是缺省配置文件,在操作系統啟動和初始化過程中,將會根據Config.h的參數來對操作系統進行配置。開發人員在該文件中對BSP基本配置選項進行設置,例如系統時鐘頻率、內存起始地址、Cache模式等,通過#define、#undef的宏命令來對BSP的組件進行添加和裁剪。必須的組件配置需要寫入該文件中,其他的可選組件可以在WorkBench開發中進行添加。
在Config.h中更改RAM_LOW_ADRS鏡像起始地址,通過設置LOCAL_MEM_SIZE規定VxWorks操作系統管理內存區域大小,并添加對VxBus型驅動架構的支持,添加編寫的驅動模塊,例如串口、中斷、時鐘。配置操作系統對浮點操作和C、C++的支持。
(2)Makefile。
Makefile是BSP的編譯文件,在該文件中指定編譯VxWorks鏡像時所要使用的編譯器和函數庫。另外需要指定根啟動設備ROM大小和地址、增加的目標模塊、編譯應用層軟件所需要的源碼文件。
(3)sysAlib.s。
在sysAlib.s中改寫sysInit(),該程序為VxWorks啟動的入口程序,其主要功能是初始化協處理器,建立環境啟動usrInit()。下面以偽代碼形式介紹本文方案:
sysInit(){
使能協處理器0,1;
清空中斷;
清空協處理器0的CAUSE、WIRED寄存器;
啟動向量入口地址控制,置協處理器0 ERL為1;
清空TLB,建立堆棧;
建立全局偏移量表指針;
初始化處理器時鐘計數器、計時器中斷控制器;
將usrInit()入棧并執行;
}
(4)sysLib.c。
該文件主要提供目標板硬件資源的初始化接口。通過編寫sysHwInit()、sysHwInit2()函數,實現對目標板的硬件初始化。操作系統對VxBus驅動的支持也是在這2個函數中完成。在sysHwInit()對VxBus架構進行第1次初始化,調用hardWareInterFaceInit()接口,初始化硬件設備表的數據結構,對VxBus型設備掛接的虛擬總線PLB進行初始化,注冊VxBus型設備。在sysHwInit2()中,調用vxbDevInit()進行設備第2次初始化,包括設置設備的寄存器和內存緩存區等,并向應用層提供接口。最后在vxbDevConnect()中完成中斷掛接,至此硬件設備驅動初始化完成。
(5)hwconf.c。
VxWorks在該文件中定義hcfDeviceList[]列表來描述VxBus驅動架構的所有硬件設備。hcfDeviceList[]列表是由一個個設備結構體構成的,所有與硬件相關的設置都在設備結構體中完成,進而在注冊設備驅動時被寫入驅動程序中。在設備結構體中需要定義設備寄存器基地址、中斷號、設備引腳號等。本文中ns16550串口、MIPS中斷、R4K時鐘在hwconf.c中注冊。
本文中硬件環境是MIPS架構的龍芯1E芯片,對于中斷采用VxBus驅動的方式管理。在硬件結構上,MIPS的芯片采取分層次管理。第1層為MIPS中斷控制,共有8個類型,第2層為龍芯1E中斷控制,共有32個中斷[12],本文中涉及時鐘中斷和串口中斷。在編寫軟件時,本文采用分層次的方式管理中斷。
第1層MIPS中斷控制,可利用自帶的VxBus型中斷控制驅動。在hwconf.c中添加所需要控制的中斷設備引腳說明,將引腳2設置為龍芯1E中斷,將引腳7設置為時鐘中斷。第2層的中斷為板級中斷,將引腳11、12設置為串口0、1中斷并更新向量表。然后在hwconf.c中添加龍芯1E的中斷:
Const Struct intrCtlrInputsmipsLSIntCtlrInputs[]{
{11,”ns16550”,0,0},
{12,”ns16550”,1,0}
}
const struct hcfResourcemipsLSResources[]={
{“regBase”,HCF_RES_INT,(void *)TRUE},
{“input”,HCF_RES_ADDR,((void *)mipsLSIntCtlrInputs[0])},
{“inputTableSize”,HCF_RES_INT,{(void *)
NELEMENTS(mipsLSIntCtlrInputs)}}
}
#definecpuNumNELEMENTS(mipsLSResources)
在設備列表中添加中斷設備:
{“mipsLSIntCtlr”,0,VXB_BUSID_PLB,0,cpu0Num,mipsLSResources}
從硬件角度看,在32位MIPS存儲器架構中,對程序空間地址映射分為4大區域:kuseg,kseg0~kseg2。本文將地址空間的kseg0和kseg1直接映射到物理地址空間的最低0.5 GB。考慮到星載軟件對實時性和安全性的要求,將內存分為靜態管理和動態管理2部分。本文將操作系統映射到kseg0區域,將200 MB分配給操作系統作為動態內存使用,即:0x80000000~0x8C800000用于系統運行、局部變量存儲等。剩下的地址空間作為靜態內存使用,重啟不刷新,用于存儲遙測數據等。
圖4為用于動態存儲的內存空間分配圖。在本文中,低端內存區域存放中斷向量表、bootline、exception message等信息。RAM_LOW_ADRS=0x801000000,VxWorks區域存放操作系統映像的代碼段、數據段和BSS(Block Started Symbol)段。WDB(Wind deBug)內存池在前期開發時使用,主要用于動態下載目標模塊、傳遞參數等。VxWorks可用內存區域主要用于動態內存分配(malloc等)、任務和中斷堆棧等。

Figure 4 Dynamic memory allocation圖4 動態內存分配圖
靜態存儲起始地址為0x8C800000,至SDRAM結束。在操作系統運行時,可由應用程序直接向這段區域寫入數據,省去了系統調度等過程,提供了很好的實時性和可靠性。具體的分配策略可根據應用層程序的需要進行分配,以達到最好的內存利用狀態。
時鐘管理關系著操作系統任務調度、超時處理、時鐘計時、時鐘中斷等。本文中新型龍芯芯片通過配置PLL分倍頻參數將系統時鐘設置為180 MHz,其高頻PLL結構圖如圖5所示,輸入的時鐘Fin經過輸入分頻后得到Fref時鐘,該時鐘送到倍頻器,得到Fvco,然后在輸出前除以1個分頻系數,得到 PLL 輸出時鐘Fout。轉換方式如式(1)和式(5)所示:
Fout=Fin/ref*ldf/odf
(1)

Figure 5 Clock PLL structure圖5 高頻PLL結構圖
在操作系統中采用VxWorks所提供的MIPS R4K的VxBus型驅動管理時鐘。在Config.h中包含#define DRV_TIMER_MISR4K驅動組件并將系統時鐘設置為180 MHz。在hwconf.h中設置時鐘參數:最小時鐘、最大時鐘、CPU頻率等。關鍵代碼如下所示:
Const Struct hcfResourcer4KTimerDevResources[]{
{“regBase”,HCF_RES_INT,(void *)0},
{“minClkRate”,HCF_RES_INT,(void *)SYS_CLK_RATE_MIN},
{“maxClkRate”,HCF_RES_INT,(void *)SYS_CLK_RATE_MIN},
{“cpuClkRate”,HCF_RES_INT,(void *)180000000},
};
#definer4TimerDevNumNELEMENTS(r4KTimerDevResources)
在設備列表中添加時鐘設備:
{“r4KTimerDev”,0,VXB_BUSID_PLB,0,r4TimerDevNum,r4KTimerDevResources}
VxWorks系統提供了VxBus型驅動來管理I/O設備,本文以常用的ns16550串口為基礎,編寫驅動軟件。
編寫VXBNS165550.h文件,定義串口寄存器地址、中斷類型等變量并構建結構體NS16550VXB_CHAN,把串口抽象成1個組件,以方便對設備的操作設置和管理。
在hwconf.c中,對串口設備進行基礎的初始化定義,并把串口設備添加到VxBus設備表中,定義串口寄存器基地址、波特率、時鐘頻率、寄存器間隔空間,關鍵代碼如下所示:
Struct hcfResourceNS16550Dev0Resources[]={
{“regBase”,HCF_RES_INT,0xbf004080},
{“baudRate”,HCF_RES_INT,152100},
{“clkFreq”,HCF_RES_INT,(void *)BAUD_CLK_FREQ},
{“regInterval”,HCF_RES_INT,(void *)UART_DELTA},
};
#defineNS16550Dev0NumNELEMENTS(NS16550Dev0Resources)
Const StructhcfDevice_hcfDeviceList[]={
{“NS16550”,0,VXB_BUSID_PLB,0,NS16550Dev0Num,NS16550Dev0Resources}}
創建VXBNS16550.c驅動源碼文件,實現串口設備的初始化、中斷以及各種操作,如圖6所示。

Figure 6 Method of serial port driver圖6 串口驅動方法圖
串口NSvxbRegister()、NSvxbInstInit()2個函數在內核初始化過程中完成。NSvxbRegister()創建串口設備,并將串口設備掛接到虛擬總線PLB。
NSvxbInstInit()初始化NS16550VXB_CHAN數據結構,將串口的波特率、通道號、時鐘頻率、串口基地址、寄存器間隔空間參數從hwconf.h中加載到驅動中,并聲明以下2個方法:
LOCALdevice_method_tNS16550VXB_methods[] =
{
DEVMETHOD(sioChanGet,NS16550SioChanGet);
DEVMETHOD(sioChanConnect,NS16550SioChan-Connect)};
NS16550SioChanGet()方法為上層提供通過通道號找到串口設備的接口,NS16550SioChanConnect()用于串口中斷的掛接和使能。
NSvxbDevInit()實現2部分初始化,第1部分配置UART通道,包括LCR線路控制寄存器,配置端口8字節,1個停止位無校驗,波特率115 200,設置Modem控制寄存器為回環模式中連到RI輸入。第2部分聲明串口操作方法,包括NSvxbIoctl()、NSvxbTxstartup()、NSvxbCallbackInstall()。
NSvxbIoctl()為串口控制函數,包括設定串口波特率、停止位奇偶校驗、打開串口、Modem控制寄存器。NSvxbTxstartup()使能發送的中斷。NSvxbCallbackInstall()完成中斷后接受和發送的函數連接安裝。
在sysHwInit2中調用vxbDevConnect()連接和使能串口中斷,將串口中斷處理程序NSvxInt()掛接到中斷向量中。在本文中串口工作模式為中斷觸發,在中斷處理程序中使用NSIntWr()和NSIntRd()對串口循環緩存區進行讀寫操作。至此,串口初始化完成,設備以相應的結構體掛接到VxBus設備樹中,并開啟中斷。
如圖7所示,操作系統通過中間層TTY管理串口設備:虛擬設備TTY作為I/O設備向I/O系統注冊。在usrRoot()中將TTY設備加入IO系統:
ttyDevCreate(tyName,sysSerialChanGet(channelNo),512,512);
consoleFd=open(tyName,O_RDWR,0);

Figure 7 I/O device management圖7 I/O設備管理
在ttyDevCreate函數中,iosDrvinstall()和iosDevAdd()將串口以TTY設備添加進系統驅動表和系統設備表中。用open()申請consoleFd為設備文件描述符。至此,串口設備被掛接到I/O系統中,驅動開發完成。
本文采用新型龍芯1E系列開發板作為驗證和測試的目標機,采用研華工控機作為宿主機。龍芯1E串口0和工控機相連,將串口信息發送到工控機中。操作程序鏡像通過串口1從工控機下載到開發板中。
測試分為3部分:第1部分,通過系統運行,在VxWorks shell中輸入VxBusShow檢驗VxBus驅動啟動是否成功。第2部分,在應用層編寫串口收發測試程序,通過串口收發數據各1 500次驗證VxBus型串口驅動在實際應用中的可靠性。第3部分,分別在新型龍芯1E芯片和在軌星載計算機上創建相同應用程序,檢驗在復雜運算過程中,BSP的表現情況和BSP性能對比。

Figure 8 Diagram of drive device hook up圖8 驅動設備掛接圖

Figure 9 Operation diagram of serial port receiving data圖9 串口接收數據運行圖
(1)在WorkBench開發環境中創建1個VxWorks Image型工程,選擇編輯本文實現的BSP。編譯鏡像生成可執行文件VxWorks。通過串口將鏡像下載到開發板中運行。在shell中輸入VxBusShow顯示當前系統的驅動和設備,可看到當前VxBus串口驅動、中斷驅動、時鐘驅動成功注冊。如圖8所示。
(2)創建VxWorks Image型工程,在usrAppInit()中創建任務:①通過串口接收數據1 500次,并將數據進行比對,輸出接收總次數、接收數據成功次數、接收數據錯誤次數。②通過串口發送數據到宿主機1 500次,宿主機接收后在SSCOM串口中輸出。圖9為串口接收數據運行結果圖。
由圖9結果得出,分別接收和發送1 500次數據,均未出現誤碼等情況,實踐證明VxBus型驅動具有很好的可靠性。
(3)創建VxWorks Image型工程,在usrAppInit()中創建1個任務:
voidusrAppInit(void){
logMsg(“----usrAppInit,---- ”,0,0,0,0,0,0);
taskSpawn(“test”,100,0x01000000,2000000,(FUNCTPTR)main,0,0,0,0,0,0,0,0,0,0);
}

Figure 10 Results of the program running on the on-board computer圖10 在軌星載計算機中程序運行結果圖

Figure 11 Results of the program running on the new Godson 1E圖11 新型龍芯1E中程序運行結果圖
并將任務分別運行在移植成功的新型龍芯1E芯片和在軌星載計算機中,將2款計算機設置為相同CPU頻率,通過運行時間對比驗證其性能提升。該任務為武漢大學編寫的導航衛星自主定軌的模擬程序,用C++語言編寫,并用到大量的浮點運算,包括協方差計算,讀取存儲12*12的矩陣,算法復雜度高,可以很好地檢測BSP的運行狀態和進行性能對比。如圖10所示為模擬程序在目前在軌星載衛星系統中運行截圖,如圖11所示為模擬程序在新型龍芯1E中運行截圖。
由運行結果可知操作系統已啟動且運行狀態良好。運行1次模擬程序在軌星載計算機系統的時間為38 s,在新型1E芯片中的時間為21 s。以運行時間為衡量標準,移植后程序運行速度提升了81%,性能提升明顯,可以滿足執行復雜應用的需求。
本文在新型龍芯1E開發平臺上,針對硬件升級所提出的需求,完整開發了VxWorks操作系統的BSP包,包括內存分配、中斷管理、時鐘管理、串口VxBus型驅動設計,并基于工程實踐的星載計算機,設計了可靠合理的測試方案,測試結果說明操作系統移植成功,計算性能得到了提升,具備承擔未來多樣化星載軟件任務的可行性,同時為未來SpaceWire高速通信接口應用開發奠定了技術基礎。