基于内存共享的多道分析器与应用软件数据交换的设计
2021-11-03宋青锋赵龙于海明张伟
宋青锋 赵龙 于海明 张伟
(丹东东方测控技术股份有限公司 辽宁省丹东市 118000)
多道分析器早已在多种产品中应用,有模拟多道分析器,也有数字多道分析器。不同分析仪产品对多道分析器的需求不同,就形成了不同硬件通信接口和不同硬件通信协议的情况,应用软件就要根据使用的多道分析器情况,更改硬件接口和通信协议,导致不同产品或者同一产品不同版本的应用软件都不同。这样对于应用软件开发和软件版本管理都增加了工作量,同时硬件通信协议对于每一个软件开发人员都是开放的,也不利于多道分析器硬件技术的保密。为了将多道分析器与应用软件的数据交换过程统一化,使用共享内存技术,开发多道分析器的接口服务软件,将多道分析器与电脑之间的硬件通信封装起来。多道分析器广泛应用于中子活化多元素分析仪中[1-2],随着产品销售领域的不断拓展,硬件及软件的功能不断的改变,对多道分析器硬件与应用软件数据交互统一性的需求更加强烈。
1 数据交换的方法
由于不同多道分析器的硬件接口不同,通信协议也不同,在电脑端开发一个接口服务软件,负责与多道分析器硬件进行通信。接口服务软件将与多道分析器通信解析得到的数据按照一定的格式封装,然后与应用软件在同一台电脑的情况下进行数据的交换。实现EXE 程序间数据交换的方法有多种,比如利用剪贴板、利用消息机制、利用SOCKET 和利用内存映射等,本设计采用共享内存映射的方法。在WINDOWS 操作系统中,任何一个进程不允许访问另一个进程的数据,
包括变量、对象和内存分配等,但是在进程中创建一个内存映射对象,将文件映射到内存中,另一个进程可以访问此内存中的数据。首先调用CreateFileMapping 函数把文件映射到内存,然后调用MapViewOfFile 函数把文件映像到进程地址空间上,接着通过MapViewOfFile 函数返回的映像内存地址指针写数据或读数据,最后通过调用UnmapViewOfFile 函数释放映像内存[3]。
2 接口服务软件设计
接口服务软件基于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:硬件属性设置及状态监控界面
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()可以使接口服务软件界面显示出来。
4 结语
通过使用共享内存技术,设计了多道分析仪与应用软件之间进行数据交换的接口服务软件,将不同硬件接口和不同协议的多道分析器与应用软件之间的数据交换实现了统一的数据结构。多道分析器的改进、升级将不会影响应用软件的接口部分程序,同时访问数据提供动态链接库,应用软件不需要关心具体的硬件通信。