祁 春,毛小玲,房 瑾
(中國飛行試驗研究院 陜西 西安 710089)
飛行試驗是航空技術(shù)發(fā)展與航空武器裝備研制的關(guān)鍵環(huán)節(jié),近年來隨著新型飛機(jī)的不斷涌現(xiàn),特別是多機(jī)編隊協(xié)同試飛科目的增多,給地面實時監(jiān)控的遙測資源帶來了嚴(yán)峻挑戰(zhàn)。為了解決這一突出矛盾,在多機(jī)編隊協(xié)同試飛科目中利用雷情數(shù)據(jù)是節(jié)約寶貴的遙測資源和提高整體試飛效率的一種有效途徑。針對雷情數(shù)據(jù)采用RS232串口通信的特點,本文介紹了基于MSCOMM控件實現(xiàn)雷情數(shù)據(jù)實時接收與處理的方法。同時,作為面向?qū)ο蟮目梢暬_發(fā)工具Visual C++,在PC的串口通信方面具有很強(qiáng)的功能,且代碼執(zhí)行效率高[1],是本軟件開發(fā)的首選開發(fā)平臺。同時,在數(shù)值分析等復(fù)雜計算方面實現(xiàn)了VC與Matlab的混合編程,有效提高了軟件開發(fā)效率并保證了雷情數(shù)據(jù)擬合與插值計算的正確性。目前該軟件已成功應(yīng)用于多機(jī)編隊協(xié)同試飛科目的實時監(jiān)控任務(wù),緩解了對遙測資源的需求壓力。
在多機(jī)編隊協(xié)同試飛科目中,雷情實時處理軟件根據(jù)通信協(xié)議負(fù)責(zé)對導(dǎo)航雷達(dá)綜合處理系統(tǒng)發(fā)送的雷情數(shù)據(jù)信息進(jìn)行實時解析、誤碼剔除、目標(biāo)篩選和參數(shù)計算等工作,并將結(jié)果數(shù)據(jù)通過局域網(wǎng)分發(fā)至各監(jiān)控客戶機(jī)進(jìn)行實時監(jiān)控。所以,從功能上軟件主要由配置、串口通信、實時處理、存儲和網(wǎng)絡(luò)發(fā)送等模塊組成,如圖1所示。其中,串口通信和實時處理模塊是整個軟件的核心部分,也是本文討論的重點。

圖1 雷情實時處理軟件功能組成Fig.1 Functional components of the software
目前在Windows系統(tǒng)平臺下開發(fā)串口通信應(yīng)用程序主要有兩種方式:1)利用 Windows的 API函數(shù);2)利用MSComm控件[2-3]。前者可根據(jù)實際需求對軟件進(jìn)行功能裁剪,使用靈活,但代碼實現(xiàn)較繁瑣;后者是Microsoft公司為簡化串口通信編程的復(fù)雜度而設(shè)計開發(fā)的ActiveX控件[4],具有事件驅(qū)動和查詢兩種工作模式[5],利用自身提供的屬性和方法可快速實現(xiàn)與PC機(jī)的串口通信。因此,為了簡化雷情實時處理軟件編程的復(fù)雜度,且針對實時監(jiān)控任務(wù)要求和數(shù)據(jù)信息有效長度變化的特點,采用MSComm控件及事件驅(qū)動模式更能有效保證通信數(shù)據(jù)的完整性和實時性,其應(yīng)用設(shè)置及關(guān)鍵代碼如圖2所示。

圖2 MSComm的應(yīng)用設(shè)置Fig.2 Apply setting of the MSComm
首先利用GetPortOpen函數(shù)對串口資源使用情況進(jìn)行檢測,使端口資源處于釋放狀態(tài)。然后用SetInBufferSize函數(shù)設(shè)置接收緩存的大小(以字節(jié)為單位),該大小應(yīng)大于實際通信中最大一幀數(shù)據(jù)的長度,以防止數(shù)據(jù)溢出。由于雷情數(shù)據(jù)中含有不可見字符,所以數(shù)據(jù)檢取應(yīng)采用二進(jìn)制方式,即SetInputMode(1)。協(xié)議格式的設(shè)定可通過SetSettings函數(shù)設(shè)置,如圖 2 中的字符串“115200,N,8,1”,其參數(shù)字段分別代表波特率、奇偶效驗方式、數(shù)據(jù)位和停止位。針對雷情數(shù)據(jù)的特點,SetRThreshold(1)表示當(dāng)接收緩存區(qū)有1個及以上字符時將觸發(fā)接收事件,以提高數(shù)據(jù)處理的實時性。最后,用SetPortOpen(TRUE)函數(shù)打開端口,完成串口的設(shè)置。值得注意的是,在通信之前常常需要調(diào)用SetInputLen(0)函數(shù),它將引起MSComm讀取整個接收緩存區(qū),以清空緩存中初始的隨機(jī)內(nèi)容。
雷情數(shù)據(jù)包含了特定空域內(nèi)所有飛機(jī)的信息,具有信息長度不固定和存在較多無效信息內(nèi)容的特點,為了準(zhǔn)確獲取指定目標(biāo)飛機(jī)的信息,需要完成目標(biāo)挑選、信息有效性判斷和可變數(shù)據(jù)信息的接收與處理。在MSComm事件觸發(fā)函數(shù)中可利用函數(shù)GetInput獲取緩存數(shù)據(jù),其返回值的類型為VARIANT,它是一種特殊的數(shù)據(jù)類型,直接操作較為繁瑣。為了簡化數(shù)據(jù)獲取,設(shè)計中利用GetInput的VARIANT類型返回值構(gòu)造一個COleSafeArray類對象來實現(xiàn)的。COleSafeArray類是用來處理任意類型和維數(shù)的數(shù)組的類,是從OLE VARIANT結(jié)構(gòu)派生而來的,利用其成員函數(shù)GetOneDimSize即可獲得本次緩存區(qū)字符個數(shù),然后利用GetElement將數(shù)據(jù)格式化到定義好的字節(jié)數(shù)組中以待進(jìn)一步處理。因此,靈活轉(zhuǎn)化數(shù)據(jù)類型可使數(shù)據(jù)接收簡單化。
雷情數(shù)據(jù)通信格式如圖3所示,每一幀的開始均采用了雙同步設(shè)置。由于在通信過程中每次從緩存中讀取的數(shù)據(jù)并不是一個完整的數(shù)據(jù)幀,因此在處理上并不能直接對數(shù)據(jù)緩存進(jìn)行操作,而是需要對接收的數(shù)據(jù)進(jìn)行拼接,直至找到完整的數(shù)據(jù)幀。本軟件在處理上采用了雙指針法,其處理過程如圖3所示。

圖3 雷情數(shù)據(jù)幀處理方法Fig.3 The processing method of data frames
1)當(dāng)檢取接收緩存區(qū)數(shù)據(jù)時,指針Ptr1根據(jù)函數(shù)GetOne DimSize獲取的字節(jié)數(shù),對接收緩存區(qū)中的數(shù)據(jù)逐字節(jié)進(jìn)行分析,并存入處理緩存中,當(dāng)找到SynWord1并且下一字節(jié)是SynWord2時,記錄Ptr1在處理緩存中的位置Pos1,代表數(shù)據(jù)幀起始位置;
2)利用指針Ptr2尋找下一幀的 SynWord1,如果本次沒有找到,則將下次到來的數(shù)據(jù)進(jìn)行拼接處理,利用指針Ptr2繼續(xù)尋找,當(dāng)找到下一幀的SynWord1時記錄位置Pos2,則完整的數(shù)據(jù)幀即為[Pos1,Pos2-1]區(qū)段上的數(shù)據(jù)。
3)為了提高數(shù)據(jù)處理效率,如果完整幀數(shù)據(jù)長度(Pos2-Pos1)小于最小有效數(shù)據(jù)長度則進(jìn)行拋棄處理,否則對飛機(jī)代碼進(jìn)行判別,如果是需求的目標(biāo)機(jī)數(shù)據(jù),則對數(shù)據(jù)內(nèi)容進(jìn)行分析處理。
4)為了防止處理緩存溢出,在尋找一下完整數(shù)據(jù)幀前,從標(biāo)記Pos2位置的字節(jié)開始,將剩余字節(jié)數(shù)據(jù)從處理緩存首地址開始存放,并使指針Ptr1從首地址開始尋找SynWord1,如果下一字節(jié)為SynWord2,記錄Ptr1位置Pos1;
5)重復(fù) 2)、3)、4),如此循環(huán)處理。
多線程技術(shù)的應(yīng)用使得軟件在實現(xiàn)雷情數(shù)據(jù)幀的接收、分析與處理的同時,可以顯著提高軟件的運行性能,避免界面操作出現(xiàn)假死現(xiàn)象。在實現(xiàn)上,將雷情數(shù)據(jù)的接收和雷情數(shù)據(jù)的分析處理分別置于不同的線程當(dāng)中,由主線程MSComm事件觸發(fā)函數(shù)實現(xiàn)接收緩存區(qū)中數(shù)據(jù)的讀取,在子線程中完成分析與處理工作。雷情數(shù)據(jù)多線程處理方法如圖4所示。

圖4 雷情數(shù)據(jù)多線程處理方法Fig.4 The processing method of multithreading
為了防止各線程同時對共有緩存區(qū)進(jìn)行讀寫操作而出現(xiàn)不可預(yù)知的結(jié)果,利用多線程同步技術(shù)對共有緩存區(qū)進(jìn)行保護(hù),使得在同一時刻只允許一個線程對共有緩存區(qū)進(jìn)行讀取或者寫入操作,確保數(shù)據(jù)正確解析。常用的線程同步技術(shù)主要有互斥對象、事件對象和關(guān)鍵代碼段等。但是,互斥對象和事件對象都屬于內(nèi)核對象,利用內(nèi)核對象進(jìn)行線程同步速度較慢,而關(guān)鍵代碼段工作在用戶方式下,同步速度較快且使用較為簡單[6],所以,利用關(guān)鍵代碼段能更好地滿足雷情數(shù)據(jù)實時處理要求。在接收線程和處理線程中分別在共有緩存區(qū)前調(diào)用EnterCriticalSection函數(shù),在訪問完緩存數(shù)據(jù)后,調(diào)用LeaveCriticalSection函數(shù)。需要注意關(guān)鍵代碼段這兩個函數(shù)必須是成對出現(xiàn)的,否則另一線程會因無法獲取所有權(quán)而無法執(zhí)行。
Windows通信基于消息機(jī)制的[7],采用線程的消息隊列可解決數(shù)據(jù)接收線程和數(shù)據(jù)處理線程間通信及協(xié)同運行問題。線程消息,即數(shù)據(jù)接收線程收到雷情數(shù)據(jù)后,利用PostThreadMessage函數(shù)向數(shù)據(jù)處理線程發(fā)送特定的消息,并將數(shù)據(jù)轉(zhuǎn)化為LPARAM類型傳遞出去。PostThreadMessage函數(shù)會立即返回,而不用等待投遞的消息被處理完。防止消息得不到及時處理導(dǎo)致數(shù)據(jù)接收線程無法執(zhí)行而丟失數(shù)據(jù)。數(shù)據(jù)處理線程利用GetMessage函數(shù)循環(huán)查詢指定消息,當(dāng)收到PostThreadMessage函數(shù)發(fā)送的消息后,從MSG消息結(jié)構(gòu)中取出數(shù)據(jù)進(jìn)行處理。
目標(biāo)機(jī)雷情數(shù)據(jù)更新率是1pps,為了滿足實時監(jiān)控至少4pps數(shù)據(jù)更新率的要求,本設(shè)計采用VC6.0與Matlab混合編程實現(xiàn)了數(shù)據(jù)擬合與插值計算。利用Matlab編譯工具將調(diào)有Matlab polyfit函數(shù)的M文件轉(zhuǎn)為C動態(tài)庫文件供VC使用,以利用Matlab強(qiáng)大的數(shù)據(jù)分析計算能力,減輕VC在復(fù)雜數(shù)值計算方面的編程負(fù)擔(dān),確保處理的正確性,且這種方式可以實現(xiàn)脫離Matlab運行環(huán)境。
由生成的頭文件可知,VC與動態(tài)庫函數(shù)的數(shù)據(jù)交互是通過mxArray來實現(xiàn)的,mxArray是一種復(fù)雜的數(shù)據(jù)結(jié)構(gòu),對應(yīng)于Matlab的Array類型。所以VC與Matlab混合編程的重點在于參數(shù)的傳遞與交互上,其實現(xiàn)的關(guān)鍵代碼如下:
//定義代表X/Y坐標(biāo)軸的mxArray類型變量用于參數(shù)傳遞
mxArray PointX, PointY ,mRes;
double*m_result;
//創(chuàng)建 PointNum*1的雙精度double類型數(shù)組,mxREAL代表元素為實數(shù)
PointX=mxCreateDoubleMatrix(PointNum,1,mxREAL);
PointY=mxCreateDoubleMatrix(PointNum,1,mxREAL);
mRes=mxCreateDoubleMatrix(PointNum-1,1,mxREAL);
//將接收到雷情數(shù)據(jù)存儲在mxArray類型數(shù)組
memcpy (mxGetPr (PointX),XData, PointNum*sizeof(double));
memcpy (mxGetPr (PointY),YData, PointNum*sizeof(double));
//注意:動態(tài)庫中的函數(shù)名稱加有ml前綴,形參和M函數(shù)文件定義不一樣,增加了輸出變量數(shù)和函數(shù)值的指針返回形式
mlMyNiHe(1,&mRes, PointX, PointY,3);
//獲取處理結(jié)果,使用C指針指向mxArray結(jié)果數(shù)組
m_result=mxGetPr(mRes);
…
//開辟的mxArray類型數(shù)組空間的銷毀,釋放資源
mxDestroyArray(PointX);
mxDestroyArray(PointY);
mxDestroyArray(mRes);
雷情數(shù)據(jù)實時處理軟件能夠同時接收和分析處理多架目標(biāo)機(jī)的雷情數(shù)據(jù),并將結(jié)果數(shù)據(jù)組播至各個監(jiān)控席位驅(qū)動畫面的運行。該軟件的成功研制有效緩解了現(xiàn)今緊張的遙測資源,特別是在多機(jī)編隊試飛任務(wù)中,雷情數(shù)據(jù)實時處理軟件提供的目標(biāo)機(jī)數(shù)據(jù)信息完全滿足實時監(jiān)控要求,是解決資源緊缺問題的一種有效實現(xiàn)途徑,已經(jīng)成功應(yīng)用于多機(jī)編隊試飛任務(wù)的實時監(jiān)控當(dāng)中。
軟件采用模塊化設(shè)計思想,并利用微軟MSComm控件快速實現(xiàn)與PC機(jī)的串口通信,采用多線程設(shè)計并靈活運用線程消息機(jī)制提高了數(shù)據(jù)處理效率和軟件運行性能;在數(shù)據(jù)的接收上,利用雙指針法實現(xiàn)了幀識別和拼接處理;同時,為了滿足實時監(jiān)控對數(shù)據(jù)更新率的要求,采用VC和Matlab混合編程實現(xiàn)了數(shù)據(jù)擬合和插值運算,將數(shù)值分析計算任務(wù)交由Matlab工具函數(shù)完成,彌補了VC在復(fù)雜運算方面的不足,減輕了編程負(fù)擔(dān)和提高了軟件研制效率。
[1]王正強(qiáng).VC中應(yīng)用MSComm控件實現(xiàn)串口通信[J].電子測試,2010(5):73-76.WANG Zheng-qiang,Realization serial-communication applied MSComm in VC[J].Electronic Testing,2010(5):73-76.
[2]李現(xiàn)勇.Visual C++串口通信技術(shù)與工程實踐[M].北京:人民郵電出版社,2002.
[3]高遠(yuǎn).通過MSComm控件實現(xiàn)串口的設(shè)備間數(shù)據(jù)傳輸[J].鐵道通信信號,2009(1):56-57.GAOYuan.Realization devices serial-communication applied MSComm[J].Railway Communication Signal,2009(1):56-57.
[4]田添.利用控件MSComm實現(xiàn)計算機(jī)的串口通信[J].數(shù)字通信,2012(2):95-97.TIAN Tian.Realization computer serial-communication applied MSComm[J].Digital communication,2012(2):95-97.
[5]邱育橋.基于MSCOMM的PC機(jī)與單片機(jī)串行通訊程序設(shè)計[J].科技信息,2009(15):446-458.QIU Yu-qiao.Design of serial-communication between PC and SCM based on MSCOMM[J].Scientific and Technical Information,2009(15):446-458.
[6]孫鑫,余安萍.VC++深入詳解[M].北京:電子工業(yè)出版社,2006.
[7]宋坤,劉銳寧,李偉明.Visual C++開發(fā)技術(shù)大全[M].北京:人民郵電出版社,2007.