宋青鋒 趙龍 于海明 張偉
(丹東東方測控技術股份有限公司 遼寧省丹東市 118000)
多道分析器早已在多種產品中應用,有模擬多道分析器,也有數字多道分析器。不同分析儀產品對多道分析器的需求不同,就形成了不同硬件通信接口和不同硬件通信協議的情況,應用軟件就要根據使用的多道分析器情況,更改硬件接口和通信協議,導致不同產品或者同一產品不同版本的應用軟件都不同。這樣對于應用軟件開發和軟件版本管理都增加了工作量,同時硬件通信協議對于每一個軟件開發人員都是開放的,也不利于多道分析器硬件技術的保密。為了將多道分析器與應用軟件的數據交換過程統一化,使用共享內存技術,開發多道分析器的接口服務軟件,將多道分析器與電腦之間的硬件通信封裝起來。多道分析器廣泛應用于中子活化多元素分析儀中[1-2],隨著產品銷售領域的不斷拓展,硬件及軟件的功能不斷的改變,對多道分析器硬件與應用軟件數據交互統一性的需求更加強烈。
由于不同多道分析器的硬件接口不同,通信協議也不同,在電腦端開發一個接口服務軟件,負責與多道分析器硬件進行通信。接口服務軟件將與多道分析器通信解析得到的數據按照一定的格式封裝,然后與應用軟件在同一臺電腦的情況下進行數據的交換。實現EXE 程序間數據交換的方法有多種,比如利用剪貼板、利用消息機制、利用SOCKET 和利用內存映射等,本設計采用共享內存映射的方法。在WINDOWS 操作系統中,任何一個進程不允許訪問另一個進程的數據,
包括變量、對象和內存分配等,但是在進程中創建一個內存映射對象,將文件映射到內存中,另一個進程可以訪問此內存中的數據。首先調用CreateFileMapping 函數把文件映射到內存,然后調用MapViewOfFile 函數把文件映像到進程地址空間上,接著通過MapViewOfFile 函數返回的映像內存地址指針寫數據或讀數據,最后通過調用UnmapViewOfFile 函數釋放映像內存[3]。
接口服務軟件基于VC++開發,各功能模塊的工作過程如圖1所示。軟件的主要功能包括:建立共享內存、數據的接收與發送、數據格式的轉換、共享內存的讀寫以及軟件退出時釋放共享內存。

圖1:接口服務軟件工作過程
軟件在初始化時建立共享內存映像并獲取句柄,供后續訪問內存使用。共享內存的屬性設置為可讀可寫,接口服務軟件對外寫數據和接收數據使用同一個內存區域,建立共享內存的主要代碼如下:

在接口服務軟件中實現USB、串口和網口通信,接收到硬件數據后,軟件對硬件數據進行解析,轉換成固定結構的數據,然后將數據寫入共享內存中。向硬件發送數據的過程與接收數據的過程相反,先讀取共享內存中的數據,然后按照硬件通信協議進行數據幀的轉換,最后將數據幀發送到硬件。讀寫共享內存的數據以結構體類型定義,主要代碼如下:


在結構體中成員變量kind 來表示這組數據的類型,比如表示數據是多道分析器的能譜數據、配置參數數據或者脈沖數據等,具體的數據內容存儲在成員變量data 數組中,數據的有效個數用成員變量dataNum 來指示。在讀取共享內存中的數據時需要知道數據是否被更新,寫入數據時也需要通知應用軟件數據是否更新,為了解決這個問題,在數據結構中加入了兩個成員變量id 和old_id。在向共享內存寫入數據時,將id 和old_id 設置不同的值,表示數據被更新。在讀取共享內存中的數據時,查詢id 和old_id 的值,若兩個變量的值不同,則數據被更新過。
接口服務軟件的界面如圖2所示,在軟件的通信接口中可以選擇USB、COM、UDP、TCP Server 和TCP Client,選擇適當的通信接口后,設置正確的接口參數就可以與多道分析器進行通信。接口服務軟件可以讀取硬件系統工作溫度和探測器高壓值,對探測器的運行狀態進行監測。在多個多道分析器同時應用的情況下,通過讀取硬件ID(身份識別碼)來區分連接的硬件。

圖2:接口服務軟件界面
應用軟件負責采集能譜數據和解譜分析,多道分析器的硬件屬性設置及工作狀態監控都在接口服務軟件中完成。為了防止接口服務軟件通信參數和硬件屬性參數被意外更改,設置了功能鎖定密碼,只有輸入正確的解鎖密碼才能使用相應功能。如圖3所示是硬件屬性設置及狀態監控界面,此功能可以讀取多道分析器的能譜數據并顯示,支持多種觸發模式的探測器信號及多道分析器內部信號的采集,用于分析信號狀態。讀取硬件的參數,修改后發送到多道分析器硬件中。

圖3:硬件屬性設置及狀態監控界面
應用軟件要訪問共享內存中的數據,首先也需要建立共享內存映像文件。多個進程要共享單個文件映像對象必須使用相同的名字來訪問該文件映像對象[4]。應用軟件建立的共享內存映像文件名稱要與接口服務軟件建立的共享內存映像文件名稱一致。應用軟件在寫入共享內存數據時要設置不同的id 和old_id 值,讀取共享內存時需要查詢id 和old_id 的值。為了便于應用軟件的開發,去掉應用軟件與訪問共享內存時的繁瑣操作,將訪問共享內存的具體操作和判斷全部封裝到Dll 動態鏈接庫[5]中。Dll 動態鏈接庫提供的接口函數主要有:
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);
首先應用軟件調用函數CreateDmcaData( )來創建共享內存映像,然后應用軟件可以調用函數WriteDmca( )向共享內存中寫入數據,調用函數ReadDmca( )讀取共享內存中的數據,使用完成后可以調用函數DeleteAllDmcaData( )釋放共享內存映像。在使用共享內存映像前可以調用函數DmcaDataValid( ),根據函數返回值判斷共享內存是否有效。應用軟件調用函數HideDmcaServer( )可以將接口服務軟件界面隱藏到后臺運行,調用函數DisplayDmcaServer()可以使接口服務軟件界面顯示出來。
通過使用共享內存技術,設計了多道分析儀與應用軟件之間進行數據交換的接口服務軟件,將不同硬件接口和不同協議的多道分析器與應用軟件之間的數據交換實現了統一的數據結構。多道分析器的改進、升級將不會影響應用軟件的接口部分程序,同時訪問數據提供動態鏈接庫,應用軟件不需要關心具體的硬件通信。