蔡文齋
(中國電子科技集團(tuán)公司第三十九研究所 陜西 西安 710065)
實時監(jiān)控程序的實驗室快速調(diào)試開發(fā)
蔡文齋
(中國電子科技集團(tuán)公司第三十九研究所 陜西 西安 710065)
提出了航天測控工程中實時監(jiān)控類應(yīng)用軟件開發(fā)中的仿真調(diào)試幾種方法,該文主要展示了一種內(nèi)嵌在監(jiān)控程序本身的窗口調(diào)試法,該方法使用一個獨立的十六進(jìn)制編輯窗口發(fā)消息方式代替某接入計算機(jī)的硬件傳感器,在實驗室內(nèi)可完全仿真出硬件通訊時的環(huán)境,可靈活地按協(xié)議給出硬件傳感器發(fā)送給計算機(jī)的定長信息,從而可無硬件環(huán)境下調(diào)通整個監(jiān)控系統(tǒng),一旦硬件配件接通,協(xié)議級的通訊亦隨即完成。
復(fù)雜控制系統(tǒng) 仿真調(diào)試 測控工程 線程 事件
航空、航天和電子等領(lǐng)域內(nèi)實時監(jiān)控系統(tǒng)通常由若干計算機(jī),一大堆相關(guān)板卡構(gòu)成一個硬件環(huán)境,通常在Win32環(huán)境下編制相關(guān)的監(jiān)控軟件,假定已知了相關(guān)的硬件需求和相應(yīng)的軟件通訊協(xié)議后,可否在實驗室內(nèi)無硬件設(shè)備時完全開發(fā)出全套監(jiān)控系統(tǒng)軟件,文章提供的方法即為此目的而設(shè)計[1]。承研單位的監(jiān)控軟件在Windows xp環(huán)境下使用C++或者Delphi開發(fā)。通常的做法是,開發(fā)人員等到買到各種相關(guān)板卡后再逐個調(diào)試各端口,當(dāng)設(shè)備全聯(lián)在一起時統(tǒng)一聯(lián)調(diào),通常聯(lián)調(diào)時很費時費力,要求各設(shè)備或者分機(jī)配合一塊調(diào)。文中提出的方法是:在實驗室內(nèi),無需連接各板卡,同樣可以仿真出這些硬件設(shè)備開發(fā)出整個監(jiān)控軟件,等到各種板卡到位后,再添加這些板卡的設(shè)備初始化及I/O函數(shù)。這樣,在實驗室內(nèi),整套監(jiān)控軟件在無硬件環(huán)境下可以提前編制完成。作者在組織項目中監(jiān)控軟件開發(fā)時,工程中使用的板卡因為種種原因未能夠及時到位,但工程任務(wù)時間要求緊,如果等到各板卡到位再編制監(jiān)控軟件時,那么整個進(jìn)度將無法保障。作者使用監(jiān)控程序內(nèi)加調(diào)試支持方法巧妙解決了這類問題。
假定不考慮接入計算機(jī)的某板卡接口形式,不考慮具體的某硬件傳感器的特性,僅從抽象的角度考慮,那么可以將接入的任一硬件傳感器都視為一流設(shè)備,這些硬件設(shè)備通過相關(guān)板卡與計算機(jī)聯(lián)在一起,計算機(jī)與這些板卡的通信就是一串十六進(jìn)制碼字的交換,任一硬件的讀入形式經(jīng)抽象化后都是一樣的。比如如下的某航天測控類應(yīng)用項目:該項目是一雷達(dá)測控站,控制計算機(jī)要外接的硬件具體設(shè)備,如圖1所示,計算機(jī)經(jīng)接口板卡與硬件設(shè)備的連接示意圖如圖2所示。
圖1 工程硬件結(jié)構(gòu)圖
圖2 數(shù)字計算機(jī)接口圖
任一接入控制計算機(jī)的硬件設(shè)備與計算機(jī)通訊本質(zhì)上是一定長的十六進(jìn)制字符碼字的雙向信息交流,在程序中即為讀寫函數(shù)Read與Writ函數(shù)[2],無論硬件接口形式是什么,最終抽象的讀寫參數(shù)是一樣的:設(shè)備號、讀寫緩沖區(qū)數(shù)據(jù)內(nèi)容、讀寫長度、實際讀入或者寫出的長度及回送的狀態(tài)碼字。例:
Ret=ReadAny(HardNum:integer;設(shè)備號
Const Buffer;緩沖器
ReadLength);欲讀入的長度
Ret為實際讀入的長度,也表示回送的狀態(tài)碼字,寫出函數(shù)同理。姑且不論某一硬件傳感器是怎樣初始化及怎樣使用的,一般相關(guān)板卡均帶有驅(qū)動程序,在Win32環(huán)境下通常是通過驅(qū)動程序提供的API函數(shù)訪問硬件,雖然各硬件的訪問形式有所差異,但計算機(jī)訪問的機(jī)制卻是相同的。
該法的要點為:在監(jiān)控程序端加入用戶讀硬件消息機(jī)制,加消息調(diào)試機(jī)制;再使用某方法設(shè)計一個十六進(jìn)制編輯器作為仿真器使用,發(fā)出這些消息,并且將這個十六進(jìn)制編輯器的內(nèi)容復(fù)制為你的欲調(diào)試的某硬件讀緩沖區(qū)內(nèi)容,這樣使用該仿真器即代替了某具體硬件設(shè)備。
監(jiān)控軟件一端加接收消息機(jī)制,首先定義用戶消息,這些消息為:某硬件傳感器讀到數(shù)據(jù)的消息,例如你的系統(tǒng)共有6路接口的硬件設(shè)備,定義6個讀用戶消息,消息函數(shù)功能為:將讀到的硬件數(shù)據(jù)緩沖區(qū)解碼,抽象化這樣傳感器將其視為一組緩沖區(qū),監(jiān)控軟件本身就是對某硬件傳感器緩沖區(qū)的加工處理,假定這個緩沖區(qū)內(nèi)容已經(jīng)具備,相當(dāng)于你已經(jīng)讀到了硬件內(nèi)容,仿真的方法就是構(gòu)造這個你欲想得到的緩沖區(qū)內(nèi)容。監(jiān)控軟件一端加調(diào)試支持機(jī)制,在某個用戶讀消息中(調(diào)試接口,例如上例中6個消息之1),加如下代碼:如果調(diào)試A硬件,則復(fù)制由仿真器傳來的緩沖區(qū)內(nèi)容到A讀入緩沖區(qū),再發(fā)送A硬件讀完成消息給你的監(jiān)控程序窗口。
如果調(diào)試B硬件,則復(fù)制由仿真器傳來的緩沖區(qū)內(nèi)容到B讀入緩沖區(qū),再發(fā)送B硬件讀完成消息給監(jiān)控程序窗口等。仿真器構(gòu)造這個緩沖區(qū)內(nèi)容ComBuffer,并且發(fā)特定的消息給監(jiān)控程序窗口,這樣無需要硬件傳感器本身接入,只要知道通信協(xié)議即可開發(fā)出全套監(jiān)控軟件。
仿真器可以使用多種方法構(gòu)造:①使用串行口調(diào)試器作為仿真器[3];于使用網(wǎng)絡(luò)調(diào)試器作為仿真器[4];③使用進(jìn)程通信方法作為仿真器[5];④單進(jìn)程方法[6],在監(jiān)控程序中,內(nèi)嵌一個單獨的窗口,在該窗口內(nèi)編寫一個十六進(jìn)制編輯器作為仿真器[7]。
第①和于方法就是開發(fā)出一套仿真硬件調(diào)試器,比如串口調(diào)試器和網(wǎng)絡(luò)調(diào)試器等,這樣在實驗室內(nèi)可快速調(diào)試出整套監(jiān)控系統(tǒng)。這些調(diào)試器網(wǎng)絡(luò)上已經(jīng)有下載的程序了,或者自己寫這些調(diào)試器,無論怎樣,在監(jiān)控程序中要寫接收代碼。
第③種方法為:設(shè)計一款基于進(jìn)程通訊技術(shù)的綜合調(diào)試器,該調(diào)試器實際是一款十六進(jìn)制輸入編輯器。代表一串硬件信息流,比如com2口讀入的信息,再使用進(jìn)程通訊技術(shù)使該調(diào)試器將這一串信息傳給監(jiān)控軟件。在監(jiān)控軟件一端,程序同樣要使用進(jìn)程通訊技術(shù)接收由調(diào)試器發(fā)來的信息,達(dá)到仿真某硬件傳感器讀入信息的目的。進(jìn)程通訊方法有多種形式,作者使用多種技術(shù)手段曾寫出了這款綜合調(diào)試器,使用多種進(jìn)程通訊技術(shù)傳出數(shù)據(jù),亦使用多種內(nèi)核技術(shù)通知數(shù)據(jù)的變化,效果頗佳。該法的優(yōu)點是你可以深入到WINDOWS內(nèi)核級編程,學(xué)習(xí)到高深的進(jìn)程間通信方法[4],缺點是這一大堆內(nèi)核對象技術(shù)及進(jìn)程之間的通訊方法對初學(xué)者有一定難度。
第④種方法為:直接在監(jiān)控軟件本身內(nèi)置一個仿真器,同樣可以達(dá)到無硬件環(huán)境調(diào)試出全套軟件的目的。
其中任一款調(diào)試器都可以作為通用調(diào)試器使用,關(guān)鍵部分在改造監(jiān)控程序本身部分,你的監(jiān)控軟件需要具備調(diào)試支持功能,在任一硬件的設(shè)備讀完成語句后加讀完成消息機(jī)制。
首先將監(jiān)控軟件本身稍作改造,使其具備調(diào)試支持功能。無論具體硬件傳感器是什么形式,比如是一款GPS導(dǎo)航設(shè)備通過串行口往計算機(jī)送出位置信息,形式化的硬件訪問函數(shù)一般為幾句:①設(shè)備打開;于設(shè)備讀;③設(shè)備寫;④設(shè)備刷新;5設(shè)備關(guān)。這些函數(shù)一般由商用板卡廠家依DLL形式提供,但串行口和網(wǎng)絡(luò)通訊用的函數(shù)卻由Windows API提供。該文重點在于調(diào)試方法,在監(jiān)控程序內(nèi),設(shè)計一種通知機(jī)制,當(dāng)每種硬件傳感器讀語句執(zhí)行完成,發(fā)一用戶定制的消息給主窗口,告知該主窗口由線程或者回調(diào)函數(shù)業(yè)已完成硬件信息讀。在對應(yīng)的消息處理函數(shù)中,完成信息解碼,表示該設(shè)備讀完成并且在該消息函數(shù)中加工數(shù)據(jù)。有了這樣一種機(jī)制在后臺工作后,假定需要調(diào)試COM12串行口,只要從什么地方能夠發(fā)出COM12對應(yīng)的消息就相當(dāng)于COM12讀到了數(shù)據(jù)。如果將調(diào)試器的輸入內(nèi)容作為比如com12口的讀入內(nèi)容,而由該調(diào)試器發(fā)這一用戶消息給主窗口,主窗口分不出到底是由具體的com12口硬件設(shè)備發(fā)出或者由調(diào)試器發(fā)出,這樣就達(dá)到了以假亂真的效果。
無論監(jiān)控程序使用什么語言編寫,無論讀入時序怎樣安排,為了達(dá)到仿真調(diào)試目的,將監(jiān)控程序改造如下:設(shè)計若干讀入完成消息,在每個硬件傳感器讀入函數(shù)完成后,發(fā)一用戶特定的消息給前臺窗口,告知該設(shè)備讀已完成;讀入完成消息處理為:對讀入緩沖區(qū)解碼,將緩沖區(qū)某某位置的十六進(jìn)制碼字按照通訊協(xié)議變換為監(jiān)控程序使用的變量,提供給監(jiān)控程序使用。設(shè)監(jiān)控程序為A窗口,仿真硬件程序為B窗口。
A窗口要接收B窗口數(shù)據(jù),并且B窗口數(shù)據(jù)變化時應(yīng)立即通知給A窗口,那么問題變?yōu)椋和ㄖ蛷?fù)制變化數(shù)據(jù)。A窗口的調(diào)試方法:假定要調(diào)試串行口12,首先假定已經(jīng)編寫了com口讀寫線程(注意此時無硬件,com12打不開,無法跟蹤[6]),假定你的監(jiān)控程序已經(jīng)具備了調(diào)試支持功能(用戶消息),當(dāng)每個硬件傳感器讀完成后都會發(fā)一對應(yīng)的讀完成信息的。那么只要在什么地方發(fā)出該消息,就相當(dāng)于已經(jīng)讀入了該硬件數(shù)據(jù)。試設(shè)想一下,如果讀入緩沖區(qū)的每一位都可控制輸入,那么在實驗室內(nèi)就仿真了所有實際的通訊情況,將節(jié)約大量時間在設(shè)備聯(lián)調(diào)階段,因為在聯(lián)調(diào)時,只有對方開機(jī)運行他或者她的程序時你才能調(diào)程序。
假定開發(fā)者設(shè)計的監(jiān)控程序需要調(diào)試16個串行口,2個網(wǎng)絡(luò)設(shè)備,4個A/D設(shè)備,48路I/O設(shè)備等等,此時假定需要的多串行口卡,A/D卡等等還沒有買到,那么使用一款網(wǎng)絡(luò)調(diào)試器來調(diào)試整個監(jiān)控程序:注意只有一個輸入,網(wǎng)絡(luò)讀,監(jiān)控程序首先要完成網(wǎng)絡(luò)讀部分,下面介紹怎樣調(diào)試串行口12,在網(wǎng)絡(luò)讀函數(shù)完成后,將網(wǎng)絡(luò)讀入的緩沖區(qū)內(nèi)容復(fù)制到串行口12的讀緩沖區(qū)中,網(wǎng)絡(luò)讀中再加一句代碼,發(fā)送串行口12讀完成消息給主窗口,這樣就騙過了串行口12的讀完成語句;此時,串行口12可能還不能夠使用(設(shè)備未到位),但開發(fā)進(jìn)度并不受影響,串行口需要的數(shù)據(jù)來自于網(wǎng)絡(luò)調(diào)試器,通知來自于網(wǎng)絡(luò)讀消息,在網(wǎng)絡(luò)讀函數(shù)中,改造上2句代碼成其他設(shè)備,將順次調(diào)試完你所有連入系統(tǒng)的硬件設(shè)備。假定監(jiān)控程序已經(jīng)具備了上文中的調(diào)試支持功能,那么可以在實驗室無硬件環(huán)境下完全調(diào)試處整套監(jiān)控軟件。形式化的偽代碼為:
MemoryCopy(ComBuffer12,NetBuffer,Ret);//將網(wǎng)絡(luò)緩沖區(qū)內(nèi)容復(fù)制到串行口12的讀緩沖區(qū);PostMessage(窗口句柄,WM_COM12_READ,0,0);//發(fā)送串行口12讀完成消息給前臺窗口;},到此為止,相當(dāng)于網(wǎng)絡(luò)讀到的數(shù)據(jù)已經(jīng)復(fù)制給串行口12的緩沖區(qū),發(fā)送消息表示串行口12讀到了數(shù)據(jù),將內(nèi)存復(fù)制與發(fā)送消息語句改為其他緩沖區(qū)和其他消息則可以調(diào)試其他任一設(shè)備。}
硬件緩沖產(chǎn)生器的設(shè)計方法為:在開發(fā)控制程序時,設(shè)計一款內(nèi)置的小型調(diào)試器,該調(diào)試器實際就是一個小型的十六進(jìn)制編輯器,在加發(fā)送特定消息的功能。使用軟件開發(fā)一個十六進(jìn)制編輯器代替硬件,在這個編輯器界面上使用消息通知機(jī)制告知監(jiān)控程序硬件讀數(shù)據(jù)已經(jīng)準(zhǔn)備好。
下面使用Delphi展示這個調(diào)試器設(shè)計[7]。在監(jiān)控軟件工程文件中,設(shè)計一Form,該Form內(nèi)設(shè)計兩部分輸入:一部分允許十六進(jìn)制輸入,一部分允許浮點數(shù)輸入,十六進(jìn)制輸入使用Stringdrid組件,浮點數(shù)輸入使用Edit組件即可,下面主要介紹十六進(jìn)制編輯器及調(diào)試方法具體實現(xiàn)。
設(shè)計一StringGrid,兩行256列(0~255),調(diào)整格子大小及相應(yīng)組件屬性:重載該StringGrid的CellEdit消息,該消息用于檢查是否為十六進(jìn)制輸入,這樣就編寫了一款十六進(jìn)制輸入的簡易編輯器,
設(shè)計一按鈕組件,該按鈕方法為:(界面中需要加一組RadioButton組件用于控制發(fā)送什么消息,例如COM1,COM2,…,A/D,…),依據(jù)控制開關(guān)發(fā)送不同的消息。
將十六進(jìn)制的字符串格子內(nèi)容Copy到某具體預(yù)調(diào)試的讀入緩沖區(qū)內(nèi),發(fā)用戶定制的某具體硬件傳感器讀已完成消息。這樣監(jiān)控程序就誤以為讀到了某具體硬件傳感器數(shù)據(jù)了,而且每一位都可以編輯,按通訊協(xié)議就可以很快調(diào)試出監(jiān)控程序到底編寫正確與否,調(diào)試方法示意圖如圖3所示。
上述各仿真器給出的方法特別適合于調(diào)試通信中每一位的變化這種情況(假定從緩沖區(qū)第2子節(jié)到第12字節(jié)每一位表示不同的物理硬件設(shè)備狀態(tài),設(shè)想一下,你的程序?qū)⒂?0種判斷要處理,10 Bytes,每字節(jié)8位),實際工程中另一種情況為浮點數(shù)的表示,浮點數(shù)常使用以下幾種表示法(通信時都是一串十六進(jìn)制的數(shù)據(jù)):
A:通信雙方自己規(guī)定表示方式
B:直接使用計算機(jī)本身規(guī)定的方式放置數(shù)據(jù)
對A表示法,需要通信雙方寫置碼,解碼函數(shù);對B方法,通信雙方將這幾個字節(jié)使用內(nèi)存對齊技術(shù)引用即可,delphi語言中使用Absulute技術(shù)[8],C++語言中使用聯(lián)合Unite技術(shù)[9];這樣不用編寫轉(zhuǎn)換函數(shù);注意Windows系統(tǒng)與UNIX系統(tǒng)放置數(shù)據(jù)通常是倒置的,高低字節(jié)調(diào)整即可;
在實際工程中,通訊中經(jīng)常碰到這樣一種情況,讀入某些字段是一組動態(tài)數(shù)據(jù)(比如彈道曲線x、y和z),帶驅(qū)動的監(jiān)控軟件希望由一組動態(tài)數(shù)據(jù)支持程序運行,以便測試程序整個控制過程正常否,下面介紹這樣一種情形的仿真調(diào)試:假定彈道由基地中心的網(wǎng)絡(luò)傳送,網(wǎng)絡(luò)傳送字節(jié)長度為64,從第12字節(jié)開始,每4 Bytes代表一彈道數(shù)據(jù),分別為x、y和z,低位在前,高位在后。
在仿真Form中,設(shè)計另一按鈕,按鈕消息為:
圖3 調(diào)試方法示意圖
打開某文本文件(該文件代表彈道數(shù)據(jù),設(shè)計為文本優(yōu)點在于文本文件可以靈活改變數(shù)據(jù),便于置入異常數(shù)據(jù)測試,測試監(jiān)控軟件是否具備異常處理功能),讀入文件后將文本中的字符串轉(zhuǎn)換為浮點數(shù)分別存貯在3個數(shù)組中XA、YA和ZA中,在仿真界面上,設(shè)計一個Timer組件,間隔為100 ms,再設(shè)計一cheekbox組件,使用cheekbox設(shè)置時鐘組件Timer的開或者關(guān),重載Timer消息:當(dāng)Timer開時,從數(shù)組中取一組值,數(shù)據(jù)序號設(shè)計為全局控制量integer型,每次序號加1,這樣下一個Timer消息到來時正好達(dá)到數(shù)據(jù)下一組數(shù)據(jù),當(dāng)這一浮點數(shù)按通訊協(xié)議再轉(zhuǎn)換為DWORD放置在發(fā)送網(wǎng)絡(luò)設(shè)備緩沖區(qū)的第12字節(jié)開始處(這樣就代表了動態(tài)x、y、z),Timer消息最后一句為PostMessage()[10];向主窗口發(fā)送網(wǎng)絡(luò)讀完成消息,這樣主窗口就相當(dāng)于接收到了一組動態(tài)網(wǎng)絡(luò)數(shù)據(jù)。監(jiān)控程序運行時只要在仿真界面Form中打開Timer組件開關(guān),就完全仿真了動態(tài)數(shù)據(jù)讀入過程,其他設(shè)備調(diào)試方法同理。
航空、航天和電子類實時控制軟件因其特殊性,經(jīng)常由幾個研究單位共同開發(fā)各自的監(jiān)控系統(tǒng)再進(jìn)一步傳給上一級的監(jiān)控系統(tǒng),這種系統(tǒng)可能有多級,控制系統(tǒng)聯(lián)調(diào)是個很繁雜的工作,既費時間又要求其他分系統(tǒng)人員互相配合,該文提供的方法使得開發(fā)者在實驗室內(nèi),使用很短時間開發(fā)出全套監(jiān)控軟件,為后續(xù)聯(lián)試節(jié)約大量時間,因為按協(xié)議的通訊全提前解決了。如果將該類問題擴(kuò)展之,任一個業(yè)務(wù)邏輯都會碰到該類調(diào)試問題,開發(fā)者使用上文的機(jī)制改造應(yīng)用軟件,再設(shè)計自己的調(diào)試器在應(yīng)用軟件內(nèi),雖然在初期寫了多余的調(diào)試代碼,但在后期聯(lián)合調(diào)試時將節(jié)約大量的時間。
[1](美)溫伯格.完美軟件—對軟件測試的各種幻想[M].北京:電子工業(yè)出版社,2009:56-63.
[2]RICHTER J.Window高級編程指南[M].王書洪,劉光明,譯.北京:清華大學(xué)出版社,1999:236-243.
[3]趙蘭濤,蘇彥華.DELPHI串口通信技術(shù)與工程實踐[M]. 2004:80-87.
[4]王艷平.Windows網(wǎng)絡(luò)與通信程序設(shè)計[M].北京:人民郵電出版社,2009:153-160.
[5]JEFFREY J,CHRISTOPHE N.Windows核心編程[M].葛子昂,周靖,廖敏,譯.北京:清華大學(xué)出版社,2008:270-276
[6]吳天準(zhǔn).Delphi 7程序設(shè)計技巧與實例[M].北京:中國鐵道出版社,2003:77-82.
[7]劉山,趙輝.Delphi系統(tǒng)開發(fā)實例精粹[M].北京:人民郵電出版社,2005:172-175.
[8]梁冰,李鐘尉,呂雙.Delphi技術(shù)方案寶典[M].北京:人民郵電出版社,2008:260-264.
[9]譚浩強(qiáng).C程序設(shè)計[M].北京:清華大學(xué)出版社,2005: 153-160.
[10]范文慶,周彬彬,安靖.精通Windows API--函數(shù)接口編程實例[M].北京:人民郵電出版社,2009:223-250.
Rapid Debugging and Development of Real-time Monitoring Program in Lab
CAI Wen-zhai
(The 39th Research Institute of CETC,Xi’an Shaanxi 710065,China)
This paper proposes the several simulation and debugging methods of real-time monitoring application software development in Telemetry,Track and command(TT&C)project,and mainly introduces a window debugging method embedded in the monitoring program.This method uses an independent hexadecimal edit window message mode to replace a hardware sensor accessed to the computer,completely simulates the hardware communication environment in the lab,and flexibly gives the fixed length information send by the hardware sensor to the computer according to protocols,in order to debug the whole monitoring system without hardware. Once the hardware components are connected,the communication at the protocol level is immediately completed.
complex control system;simulation debugging;TT&C project;threading;event
TP39
A
1008-1739(2015)02-58-5
定稿日期:2014-12-26