宋青鋒 趙龍 于海明 張偉
(丹東東方測(cè)控技術(shù)股份有限公司 遼寧省丹東市 118000)
多道分析器早已在多種產(chǎn)品中應(yīng)用,有模擬多道分析器,也有數(shù)字多道分析器。不同分析儀產(chǎn)品對(duì)多道分析器的需求不同,就形成了不同硬件通信接口和不同硬件通信協(xié)議的情況,應(yīng)用軟件就要根據(jù)使用的多道分析器情況,更改硬件接口和通信協(xié)議,導(dǎo)致不同產(chǎn)品或者同一產(chǎn)品不同版本的應(yīng)用軟件都不同。這樣對(duì)于應(yīng)用軟件開(kāi)發(fā)和軟件版本管理都增加了工作量,同時(shí)硬件通信協(xié)議對(duì)于每一個(gè)軟件開(kāi)發(fā)人員都是開(kāi)放的,也不利于多道分析器硬件技術(shù)的保密。為了將多道分析器與應(yīng)用軟件的數(shù)據(jù)交換過(guò)程統(tǒng)一化,使用共享內(nèi)存技術(shù),開(kāi)發(fā)多道分析器的接口服務(wù)軟件,將多道分析器與電腦之間的硬件通信封裝起來(lái)。多道分析器廣泛應(yīng)用于中子活化多元素分析儀中[1-2],隨著產(chǎn)品銷售領(lǐng)域的不斷拓展,硬件及軟件的功能不斷的改變,對(duì)多道分析器硬件與應(yīng)用軟件數(shù)據(jù)交互統(tǒng)一性的需求更加強(qiáng)烈。
由于不同多道分析器的硬件接口不同,通信協(xié)議也不同,在電腦端開(kāi)發(fā)一個(gè)接口服務(wù)軟件,負(fù)責(zé)與多道分析器硬件進(jìn)行通信。接口服務(wù)軟件將與多道分析器通信解析得到的數(shù)據(jù)按照一定的格式封裝,然后與應(yīng)用軟件在同一臺(tái)電腦的情況下進(jìn)行數(shù)據(jù)的交換。實(shí)現(xiàn)EXE 程序間數(shù)據(jù)交換的方法有多種,比如利用剪貼板、利用消息機(jī)制、利用SOCKET 和利用內(nèi)存映射等,本設(shè)計(jì)采用共享內(nèi)存映射的方法。在WINDOWS 操作系統(tǒng)中,任何一個(gè)進(jìn)程不允許訪問(wèn)另一個(gè)進(jìn)程的數(shù)據(jù),
包括變量、對(duì)象和內(nèi)存分配等,但是在進(jìn)程中創(chuàng)建一個(gè)內(nèi)存映射對(duì)象,將文件映射到內(nèi)存中,另一個(gè)進(jìn)程可以訪問(wèn)此內(nèi)存中的數(shù)據(jù)。首先調(diào)用CreateFileMapping 函數(shù)把文件映射到內(nèi)存,然后調(diào)用MapViewOfFile 函數(shù)把文件映像到進(jìn)程地址空間上,接著通過(guò)MapViewOfFile 函數(shù)返回的映像內(nèi)存地址指針寫數(shù)據(jù)或讀數(shù)據(jù),最后通過(guò)調(diào)用UnmapViewOfFile 函數(shù)釋放映像內(nèi)存[3]。
接口服務(wù)軟件基于VC++開(kāi)發(fā),各功能模塊的工作過(guò)程如圖1所示。軟件的主要功能包括:建立共享內(nèi)存、數(shù)據(jù)的接收與發(fā)送、數(shù)據(jù)格式的轉(zhuǎn)換、共享內(nèi)存的讀寫以及軟件退出時(shí)釋放共享內(nèi)存。
圖1:接口服務(wù)軟件工作過(guò)程
軟件在初始化時(shí)建立共享內(nèi)存映像并獲取句柄,供后續(xù)訪問(wèn)內(nèi)存使用。共享內(nèi)存的屬性設(shè)置為可讀可寫,接口服務(wù)軟件對(duì)外寫數(shù)據(jù)和接收數(shù)據(jù)使用同一個(gè)內(nèi)存區(qū)域,建立共享內(nèi)存的主要代碼如下:
在接口服務(wù)軟件中實(shí)現(xiàn)USB、串口和網(wǎng)口通信,接收到硬件數(shù)據(jù)后,軟件對(duì)硬件數(shù)據(jù)進(jìn)行解析,轉(zhuǎn)換成固定結(jié)構(gòu)的數(shù)據(jù),然后將數(shù)據(jù)寫入共享內(nèi)存中。向硬件發(fā)送數(shù)據(jù)的過(guò)程與接收數(shù)據(jù)的過(guò)程相反,先讀取共享內(nèi)存中的數(shù)據(jù),然后按照硬件通信協(xié)議進(jìn)行數(shù)據(jù)幀的轉(zhuǎn)換,最后將數(shù)據(jù)幀發(fā)送到硬件。讀寫共享內(nèi)存的數(shù)據(jù)以結(jié)構(gòu)體類型定義,主要代碼如下:
在結(jié)構(gòu)體中成員變量kind 來(lái)表示這組數(shù)據(jù)的類型,比如表示數(shù)據(jù)是多道分析器的能譜數(shù)據(jù)、配置參數(shù)數(shù)據(jù)或者脈沖數(shù)據(jù)等,具體的數(shù)據(jù)內(nèi)容存儲(chǔ)在成員變量data 數(shù)組中,數(shù)據(jù)的有效個(gè)數(shù)用成員變量dataNum 來(lái)指示。在讀取共享內(nèi)存中的數(shù)據(jù)時(shí)需要知道數(shù)據(jù)是否被更新,寫入數(shù)據(jù)時(shí)也需要通知應(yīng)用軟件數(shù)據(jù)是否更新,為了解決這個(gè)問(wèn)題,在數(shù)據(jù)結(jié)構(gòu)中加入了兩個(gè)成員變量id 和old_id。在向共享內(nèi)存寫入數(shù)據(jù)時(shí),將id 和old_id 設(shè)置不同的值,表示數(shù)據(jù)被更新。在讀取共享內(nèi)存中的數(shù)據(jù)時(shí),查詢id 和old_id 的值,若兩個(gè)變量的值不同,則數(shù)據(jù)被更新過(guò)。
接口服務(wù)軟件的界面如圖2所示,在軟件的通信接口中可以選擇USB、COM、UDP、TCP Server 和TCP Client,選擇適當(dāng)?shù)耐ㄐ沤涌诤?,設(shè)置正確的接口參數(shù)就可以與多道分析器進(jìn)行通信。接口服務(wù)軟件可以讀取硬件系統(tǒng)工作溫度和探測(cè)器高壓值,對(duì)探測(cè)器的運(yùn)行狀態(tài)進(jìn)行監(jiān)測(cè)。在多個(gè)多道分析器同時(shí)應(yīng)用的情況下,通過(guò)讀取硬件ID(身份識(shí)別碼)來(lái)區(qū)分連接的硬件。
圖2:接口服務(wù)軟件界面
應(yīng)用軟件負(fù)責(zé)采集能譜數(shù)據(jù)和解譜分析,多道分析器的硬件屬性設(shè)置及工作狀態(tài)監(jiān)控都在接口服務(wù)軟件中完成。為了防止接口服務(wù)軟件通信參數(shù)和硬件屬性參數(shù)被意外更改,設(shè)置了功能鎖定密碼,只有輸入正確的解鎖密碼才能使用相應(yīng)功能。如圖3所示是硬件屬性設(shè)置及狀態(tài)監(jiān)控界面,此功能可以讀取多道分析器的能譜數(shù)據(jù)并顯示,支持多種觸發(fā)模式的探測(cè)器信號(hào)及多道分析器內(nèi)部信號(hào)的采集,用于分析信號(hào)狀態(tài)。讀取硬件的參數(shù),修改后發(fā)送到多道分析器硬件中。
圖3:硬件屬性設(shè)置及狀態(tài)監(jiān)控界面
應(yīng)用軟件要訪問(wèn)共享內(nèi)存中的數(shù)據(jù),首先也需要建立共享內(nèi)存映像文件。多個(gè)進(jìn)程要共享單個(gè)文件映像對(duì)象必須使用相同的名字來(lái)訪問(wèn)該文件映像對(duì)象[4]。應(yīng)用軟件建立的共享內(nèi)存映像文件名稱要與接口服務(wù)軟件建立的共享內(nèi)存映像文件名稱一致。應(yīng)用軟件在寫入共享內(nèi)存數(shù)據(jù)時(shí)要設(shè)置不同的id 和old_id 值,讀取共享內(nèi)存時(shí)需要查詢id 和old_id 的值。為了便于應(yīng)用軟件的開(kāi)發(fā),去掉應(yīng)用軟件與訪問(wèn)共享內(nèi)存時(shí)的繁瑣操作,將訪問(wèn)共享內(nèi)存的具體操作和判斷全部封裝到Dll 動(dòng)態(tài)鏈接庫(kù)[5]中。Dll 動(dòng)態(tài)鏈接庫(kù)提供的接口函數(shù)主要有:
DMCASERVERDATA * CreateDmcaData (int DmcaNumber,char OpenDmcaServer,const char *DmcaServerFilePath);
BOOL WriteDmca(DMCASERVERDATA *m_pDmcaServerData,char *cmd);
int ReadDmca(DMCASERVERDATA *m_pDmcaServerData,BOOL bGetFlag);
BOOL DeleteAllDmcaData(DMCASERVERDATA **m_pDmcaServerData,BOOL KillDmcaServer);
BOOL DmcaDataValid(DMCASERVERDATA *m_pDmcaServer Data);
BOOL HideDmcaServer(DMCASERVERDATA *m_pDmcaServer Data);
BOOL DisplayDmcaServer(DMCASERVERDATA *m_pDmca ServerData);
首先應(yīng)用軟件調(diào)用函數(shù)CreateDmcaData( )來(lái)創(chuàng)建共享內(nèi)存映像,然后應(yīng)用軟件可以調(diào)用函數(shù)WriteDmca( )向共享內(nèi)存中寫入數(shù)據(jù),調(diào)用函數(shù)ReadDmca( )讀取共享內(nèi)存中的數(shù)據(jù),使用完成后可以調(diào)用函數(shù)DeleteAllDmcaData( )釋放共享內(nèi)存映像。在使用共享內(nèi)存映像前可以調(diào)用函數(shù)DmcaDataValid( ),根據(jù)函數(shù)返回值判斷共享內(nèi)存是否有效。應(yīng)用軟件調(diào)用函數(shù)HideDmcaServer( )可以將接口服務(wù)軟件界面隱藏到后臺(tái)運(yùn)行,調(diào)用函數(shù)DisplayDmcaServer()可以使接口服務(wù)軟件界面顯示出來(lái)。
通過(guò)使用共享內(nèi)存技術(shù),設(shè)計(jì)了多道分析儀與應(yīng)用軟件之間進(jìn)行數(shù)據(jù)交換的接口服務(wù)軟件,將不同硬件接口和不同協(xié)議的多道分析器與應(yīng)用軟件之間的數(shù)據(jù)交換實(shí)現(xiàn)了統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)。多道分析器的改進(jìn)、升級(jí)將不會(huì)影響應(yīng)用軟件的接口部分程序,同時(shí)訪問(wèn)數(shù)據(jù)提供動(dòng)態(tài)鏈接庫(kù),應(yīng)用軟件不需要關(guān)心具體的硬件通信。