杜 影1,朱元元,劉康麗1,畢 碩1,谷 靜
(1.北京航天測控技術有限公司,北京 100041;2.北京航天長征飛行器研究所,北京 100076)
當前,鑒于軍工芯片在信息化裝備所處的核心地位,采用自主研發的國產芯片勢在必行,并且已經得到了國家政策的支持和大力發展。隨著國產核心基礎軟硬件的性能與功能逐步完善,龍芯平臺搭載中標麒麟操作系統的模式已成為國產計算開發平臺的首選,其發展、推廣和應用是國產軟硬件推廣和規?;l展的技術基礎和科學依據。
軍用PXI模塊產品一直以地面測試和系統級維修保障為主要任務。在“自主可控”的背景下,將開源軟件和PXI硬件平臺結合在一起,打造基于開源軟件的通用PXI測試平臺,建立基于國產龍芯CPU的PXI儀器生態是實現國產化替代的必經之路。如今,PXI產品國產化正面臨著發展瓶頸與挑戰。首先,在硬件平臺方面,嵌入式控制器的CPU要更換成國產龍芯CPU,其整體性能和穩定性有待提高;其次,在軟件開發環境方面,龍芯平臺下的儀器控制軟件要摒棄對NI公司LabView、CVI、VISA庫以及WindowsAPI的依賴,而自主開發“龍芯平臺+中標麒麟系統”下的PXI設備驅動程序和應用程序。
本文將詳細討論龍芯平臺下PXI設備驅動的基本架構和設計方法,并在龍芯平臺下以PXI數字多用表模塊為例進行試驗驗證。
龍芯3 A系列處理器是首款國產商用四核處理器,文中PXI龍芯平臺所使用的處理器為龍芯3A3000,其工作主頻為1.0 GHz,主要技術特征為:片內集成4個64位的高性能處理器核;8MB的分體共享三級Cache;通過目錄協議維護多核及I/O DMA訪問的Cache一致性; 2個64位帶ECC,667 MHz的DDR2/3控制器;32位33 MHz PCI; 1個LPC、2 個UART、1個SPI、16路GPIO接口[1]。龍芯3A3000處理器采用MIPS 架構,因此,目前運行在 X86 架構的操作系統與應用軟件均無法在龍芯平臺運行和使用,需要通過交叉移植與本地移植的技術實現軟件環境適配[2-3]。
國產中標麒麟是一種基于Linux內核的桌面操作系統,支持眾多處理器架構。本文使用的PXI龍芯平臺安裝的操作系統為中標麒麟桌面操作系統軟件(龍芯版)V5.0,支持龍芯3A3000(64位)平臺采用的 MIPS 架構,具有強大的網絡優勢和極為突出的安全性和穩定[4],支持主流國產軟硬件,能夠最大程度發揮中標麒麟操作系統和龍芯3A3000整機平臺的整體性能。
如圖1所示,本文所搭建的國產龍芯PXI測試平臺包含軟硬件平臺兩個部分。硬件平臺主要由PXI機箱、基于龍芯3A3000處理器的嵌入式控制器和PXI模塊產品組成。軟件平臺主要包括:中標麒麟5.0操作系統軟件、集成安裝在該操作系統的可視化軟件開發工具QT5.6、以及其他腳本語言?;诖似脚_可以完成PXI模塊產品的驅動設計、開發、調試、加載、調用,編寫可視化應用程序,并進行PXI模塊的功能性能驗證。
在Windows 操作系統下,PXI設備驅動開發人員廣泛采用行業標準的VISA(虛擬儀器系統I/O接口軟件)對PXI儀器進行配置、控制、編程和調試,也有小部分開發人員在WindowsAPI基礎上進一步實現PXI儀器驅動開發。但是在國產龍芯平臺搭載中標麒麟操作系統的環境下,以往的PXI設備驅動已無法運行和使用(如第1節所述),程序員必須面向RISC(精簡指令集計算機)體系結構的Linux系統重新開發PXI設備驅動。
考慮到PXI儀器的應用場合和測試測量對象,可將PXI設備驅動程序實現分為以下幾個部分:初始化設備模塊、設備打開模塊、數據讀寫和控制模塊、中斷處理模塊、設備釋放模塊和設備卸載模塊,如圖2所示。

圖2 Linux下PXI設備驅動組成部分
初始化設備需要完成以下工作:
(1)檢查系統(Linux內核)是否支持PCI總線;
(2)注冊硬件驅動程序,即檢查設備所占用的插槽并保存它所占用的插槽的位置等信息;
(3)啟動PCI設備,讀取所有配置好的PCI設備信息中的參數和屬性(包括廠商ID、設備ID等)以備驅動程序使用;
(4)使能DMA(直接數據存儲),以便在內存操作的時候能夠讓設備把數據通過總線主DMA傳至系統內存。
設備打開模塊主要是根據當前PXI設備號獲取其設備參數和屬性,并申請對當前PXI設備的控制權。另外,如果當前PXI設備有中斷請求,則需要在該驅動模塊里申請中斷使能,并在Linux內核注冊中斷處理程序。
數據讀寫和設備控制模塊主要通過:讀設備操作、寫設備操作、I/O控制操作、內存重映射操作等向應用程序提供對硬件進行控制的接口。面向不同的PXI設備驅動程序,需要程序員重寫該模塊各個接口函數的方法,從而實現硬件邏輯控制和數據的收發與存儲。數據讀寫和設備控制模塊是整個PXI設備驅動程序的核心部分。
中斷處理模塊即指中斷處理程序,當系統接收到中斷后,程序先要根據中斷號判斷是否為當前設備發出的中斷請求,如符合條件則立即開始執行中斷處理程序,例如:在接收到中斷后完成數據的接收與存儲或復位硬件等。而中斷使能如前文所述在設備打開模塊中完成,中斷釋放則在后面的設備釋放模塊中完成。
設備釋放模塊和設備卸載模塊比較簡單,它們與設備打開模塊和初始化設備模塊相對應,主要是在設備控制結束后釋放對設備的控制以及所占用的內存和中斷,并將設備驅動程序從內核中注銷。
類同于Linux下的PCI驅動程序,在PXI驅動程序中起核心作用的關鍵數據結構(struct)也是 pci_driver和pci_dev,它們的聲明包含文件在linux/pci.h中。其中,pci_driver這個數據結構涵蓋:設備模塊名稱、所有能夠驅動的設備列表、查找并初始化設備的函數和卸載設備的函數,而pci_dev 這個數據結構則詳細描述了一個PXI設備幾乎所有的硬件信息,包括廠商ID、設備ID、各種資源等[5],其數據格式在此不做贅述。
在2.1節的初始化設備模塊中,啟動PCI設備后,所有配置好的PCI設備信息保存在結構體pci_driver中,而在設備打開模塊中,當前PXI設備的信息保存在pci_dev中。數據讀寫和設備控制是基于pci_dev中的信息執行相關操作的。
在Linux系統下,設備驅動程序發布就是將其編譯成內核的一部分,其主要有靜態編譯和動態編譯兩種方法:第一種方法要改動內核的源文件,直接將驅動程序編譯成為內核的一部分,從而增加了內核的大小,且不利于調試;第二種方法是將驅動程序編譯成可安裝模塊,通過使用insmod 命令將驅動程序動態加載到內核中,使之成為系統內核的一部分,當不使用該設備驅動時則使用rmmod 命令將其從內核中卸載,另外,還可將加載命令放入開機自啟動選項,這樣,系統開機時就能夠自動加載驅動。比較兩種驅動發布方式,動態編譯更合理也更靈活[6-7]。
根據上節所述,我們首先要在Linux下編寫和加載驅動模塊文件,即“.ko”文件?!?ko”文件是kernel object文件,其意義在于把內核的一些功能移動到內核外,需要的時候插入內核,不需要時卸載,這樣可以縮小內核的存儲容量,而且使用方便。
“.ko”文件的源碼是“.c”文件,該文件的核心內容是構造驅動程序的基本框架,文件中含有 2.1節所述的幾個關鍵功能模塊以及2.2節所述的關鍵數據結構。需要注意的是,同加載和卸載模塊相關的函數或數據結構都要在前面加上__init、__exit等標志符,以使同普通函數區分開來。
在編譯驅動文件之前要先編寫Makefile文件,該文件可使用make工具自動完成編譯工作,其有利于程序員修改和重新編譯。Makefile文件的基本內容如下(以hello.c生成hello.o為例):
obj-m :=hello.o
KERNEL :=/usr/src/kernels/(uname -r)/
PWD :=(shell pwd)
modules :
(MAKE) -C (KERNEL) M=(PWD) modules
.PHONEY:clean
clean :
rm -f *.o *.ko
在終端執行make命令,即在指定路徑下生成了hello.o 文件。然后執行insmod命令安裝hello驅動模塊,如下所示:
insmod hello.ko 相對路徑加載
為了簡化了應用層軟件設計,我們需要進一步生成“.so”(shared object)文件。該文件是Linux下的動態鏈接庫文件,類似于windows下的.dll 文件?!?so”文件的生成需要“.h”和“.c”文件,為了方便應用層軟件的調用以及不同平臺軟件的移植,我們可以對“.c”文件的函數進行標準化封裝,函數名和參數可依照Windows下dll中的函數進行定義,例如:
某PXI儀器在Windows下的應用程序調用了visa庫函數viIn8,那么就可以在Linux下封裝函數名同為viIn8的函數,并生成相應的.so文件提供給Linux下的應用程序。這樣,那些使用跨平臺軟件開發環境(如Qt)編寫的可視化程序,既不需要更改界面源碼,也不需要更改邏輯源碼,只需要在編譯程序時鏈接“.so”文件,就實現了跨平臺軟件移植。
編譯“.so”文件同樣需要先編寫Makefile文件,其內容一般為(以生成libhelloio.so為例):
CFLAGS = -Wall -g -O -fPIC
INCLUDE = helloio.h
TARGET = libhelloio.so
SRCS = helloio.c
OBJS = (patsubst %.c,%.o, (SRCS))
all: helloio
helloio:(OBJS) (INCLUDE)
gcc -shared -fPIC (OBJS) -O3 -o (TARGET)
gcc (CFLAGS) -O3 -c < -o *.o
clean:
rm -f *.o
rm -f *.so
在終端執行make命令,即生成了libhelloio.so文件。
目前,龍芯軟件生態環境還處于初始發展階段, PXI儀器軟件的遷移和二次開發存在一定難度,需要操作系統、應用軟件以及硬件兼容的緊密配合。在中標麒麟操作系統中可使用的可視化集成開發環境是Qt Creator,選擇Qt作為開發工具不僅因為其開發功能強大,更主要是因為它有開源版本且支持跨平臺運行[8]。
在Qt Creator中創建工程后除了工程文件本身還包含:頭文件(.h)、源文件(.c)以及界面文件(.ui)。在編寫邏輯代碼調用“.so”文件時,首先添加相應的頭文件,例如helloio.h(對應libhelloio.so),然后在工程文件(.pro)中引用庫文件,代碼如下:
LIBS += -L/lib64 -l helloio
如3.1節所述,如果在驅動設計時將.so文件中的函數封裝為Windows下.dll文件的同名函數,那么在跨平臺移植的過程中,軟件人員不再需要進行二次開發,只需簡單的程序移植并配置好構建和運行環境就能夠編譯出Linux下的可執行文件。在Linux下的Qt環境配置如下圖所示。

圖3 Linux下Qt環境配置
本文使用的龍芯平臺是試驗版,其中斷服務功能并不完善,機箱上電后,PXI設備中斷號在初始化設備的過程中不能自動分配,也就是說系統不能獲知并列出機箱中所有PXI硬件設備的中斷號, PXI機箱中每個插槽所使用的硬件設備中斷號固定(如:1號插槽設備的中斷號固定為04H),且需要人工測試獲取插槽與中斷號的對應關系。因此,在設備打開程序中要根據硬件模塊所在的插槽位置來配置當前PXI設備所對應的中斷號,并使能中斷,獲取其使用權。
這個問題將導致同一型號的PXI硬件設備無法使用同一個驅動程序,不同插槽的PXI設備要根據其對應的中斷號加載不同的驅動程序,從而影響到同型號PXI模塊驅動程序的通用性,增加了驅動開發的復雜度。在新版的龍芯平臺上,該問題已解決。
本文將以北京航天測控公司的PXI儀器模塊產品AMC4311(5.5位數字多用表)為對象,基于龍芯平臺和中標麒麟5.0操作系統進行PXI儀器模塊的驅動程序和應用程序開發,以驗證上述Linux下驅動程序設計的正確性和實用性。
AMC4311的硬件結構圖如圖4所示,其具備直流電壓、交流電壓、直流電流、交流電流、2線電阻、4線電阻和頻率測量功能[9]。

圖4 數字多用表模塊硬件結構圖
在龍芯平臺的中標麒麟5.0系統下AMC4311驅動程序開發過程如下:
(1)編寫設備驅動框架函數,形成Amcdev.c源文件;
(2)編寫MakeFile文件,使用make命令生成Amcdev.o文件,生成路徑為:/usr/src/kernels/Amcdev.o;
(3)編寫標準化庫函數,形成amcIO.c源文件和amcIO.h頭文件;
(4)編寫MakeFile文件,使用make命令生成libamcIO.so文件,生成路徑為:/usr/local/lib/libamcIO.so。
可視化軟件開發環境選用跨平臺軟件Qt5.6[7],界面源碼和邏輯代碼隔離,這樣可以在不修改界面源碼的情況下,簡單地將Windows下的界面程序移植到Linux下使用;邏輯代碼調用的驅動函數是“libamcIO.so”文件封裝的自定義接口函數。在Linux下重新配置QT的構建和運行環境,編譯程序生成Linux下的可執行文件,其運行界面如下圖5所示。

圖5 龍芯平臺下數字多用表控制程序運行界面
采用自主可控軟硬件產品對于實現國產化替代、打造自主可控的IT環境有著非常重要的意義。在全球開源技術蓬勃發展,在中國政府力導掌握測量等基礎學科核心技術的大背景下,國內對包括PXI 在內的測試測量技術一定會更加重視,國產PXI軟硬件產品的市場份額也會保持一個穩定上升的增長勢態。北京航天測控公司已在國內率先建立了自主可控的PXI通用測試平臺,軍工科研院所等機構也正在通過逆向設計、自主研發等方式實現國產化替代。未來,龍芯平臺搭載中標麒麟操作系統的軟硬件組合將為我國自主軟硬件產業帶來良好的發展機遇。