0 引 言
为适应工控测试领域多样化、差异化及快速响应的市场需求,针对通信信号种类多样以及非标准输出的特点,本文以共享内存(share memory)技术为基础,设计了一套具有高可靠性,高兼容性,低耦合性的通用测试平台,该平台可简化和加速测试系统的开发,提高代码和测试功能的复用性,提升系统的可靠性[1]。
文中介绍了系统的总体方案及软硬件实现,对软件设计中的共享内存的实现,互斥机制、柔性化定制等关键问题及其解决方案进行了详细阐述。
1 系统总体方案
测试平台由逻辑控制系统和信号测试系统两部分组成,二者通过现场总线进行通信,交互实现产品的全自动测试。逻辑控制系统通过对设备执行机构的逻辑和步进链操作,比如气缸的动作,伺服电机的位置速度指令,实现对被测产品状态和动作的精准控制,以达到如产品的定位,上电,转动一个固定的角度,施加一个期望的力矩等其他预期状态。同时,信号测试系统根据产品特性,输入或输出所需各种电气信号,同时检测被测产品的数据响应,计算测试结果。
系统框图如图1所示。
逻辑控制系统的中央处理单元为可编程序控制器PLC,为实现高兼容性和可扩展性,本平台支持接入西门
子、倍福、力士乐等多种主流PLC,支持主流的现场总线如PROFIBUS DP,EtherCAT,CAN, PROFINET 等,并支持其他扩展。
测试系统是本平台的关键部分,为了尽可能通用化,测试系统硬件由工控机和PCI/PCIe 板卡组成。一方面,在工控机的PCI/PCIe 插槽接入NI 公司的数据采集或信号发生卡,通过LabWindows /CVI 软件编程信号发生器输出所需信号给被测产品,同时采集被测产品的响应数据;或者通过指令控制被测产品输出信号,数据采集卡进行信号采集。最后由软件完成数据分析和处理,并通过图表或虚拟示波器等形式显示测试结果。另一方面,工控机接入响应的PCI 现场总线通讯卡(与通讯协议相关,非必须项),实现与控制系统PLC 的通讯,间接控制被测产品到达预期的状态。
基于共享内存的多进程通用工控测试平台的设计
Design of Multi Process General Industrial Control Test Platform
Based on Shared Memory
摘 要:设计并实现了一种基于共享内存进行数据通信的多进程通用测试平台解决方案,硬件平台基于工控机和NI 公司的PCI/PCIe 接口数据采集卡,软件采用基于共享内存技术的多进程架构,该方案的工程应用可提高测试系统的开发效率,具有高可靠性,兼容性和可扩展性的特点。关键词:共享内存;多进程;测试平台中图分类号:TP319  文献标识码:A
夏梦芝  成永泉
(博世汽车部件
(长沙)有限公司,湖南 长沙 410100)
图1  通用测试平台系统框图
被测产品信号种类种类多样,有模拟输入、开关输入、脉冲输入、模拟输出。针对这些需求,本平台中,硬件系统采用NI 公司PCI/PCIe 接口的数据采集卡DAQ(Data Acquisition),选用M Series 系列高性价比产品PCI-6621卡,功能齐全,可同时满足AI/AO/DIO 的测量需求;选
用PXI-6601的计数器/定时器板卡,基于20MHZ的时钟信号的4通道Counter,能够实现脉冲输入输出。
与控制系统的现场总线通讯分为两种方式,一种是基于以太网技术的EtherCAT,PROFINET等,不需要增加额外的板卡,直接使用双绞线连接RJ45网口即可。另外一类如PROFIBUS DP,CAN等,需要在测试工控机的PCI/PCIe插槽接入额外的板卡来支持实现,在本系统中,选择德国赫优讯Hilscher公司的CIFX50-DP板卡实现PROFIBUS DP通讯,3.3V/typ650mA,可配置为主站或从站。选用NI公司的XNET系列板卡PCI-8512实现CAN数据的收发,PCI-8512是一款单端口高速CAN接口 (高达1 Mbit/s), 配有板载TJA1041收发器 NI-XNET 驱动,用于在LabVIEW、LabWindows/CVI和C/C++中开发帧和信号应用程序。作为NI-XNET平台的一部分,PCI-8512适合需要对数百个CAN帧和信号进行高速实时操作的应用,能很好地满足本平台的需求。
2 软件平台设计
2.1 软件架构
为降低模块间的耦合性,提高软件可重用性,采用模块化的软件设计方法,对任务系统软件进行功能分解,按功能域划分不同进程,形成多进程的软件架构,由于各进程的地址空间不同,当某个进程出现异常时,操作系统会将该进程内的异常限制在单进程内,从而避免对其他进程产生影响,很好地起到了隔离作用,有效地提高软件可靠性[2]。进程间采用通信效率很高的共享内存的方式进行数据和任务的交互。系统软件框如图2所示。软件中引入了反射和依赖注入这样的特性给程序提供了很多的灵活性。
其他子进程负责与各功能的底层外设通信,完成数据的原始采集和写入。设计采用了LabWindows作为编程语言,因为LabWindows/CVI作为NI公司推出的基于ANSI C 的高效开发环境,它提供了丰富的函数库。利用这些库函数除可实现常规的程序设计外,还可实现更加复杂的数据采集和仪器控制系统的开发。仪器库是LabWindows/CVI的特殊资源。采用LabWindows/CVI可用于快速构建可靠的测试与测量解决方案,对NI硬件板卡的支持有着天然的优势。
NIDAQ/NIDIO子进程通过PCI-6621和PCI-6601板卡,实现电压信号采集,PWM采样,频率和速度测量,角度和位置编码,波形发生的功能;NIXNET实现基于PCI-8512板卡的CAN帧和信号解析,收发。CIFX-DP子进程实现赫优讯的PROFIBUS DP卡的通讯,通过此子进程,无需修改代码,就可轻松接入其他支持DP协议的各种外设包括PLC,伺服电机,变频器等。SimPLC子进程基于PROFINET以及西门子的libNodave.lib,不需要安装西门子通讯软件,就能实现对西门子PLC的DB数据块的数据读写。
2.3 共享内存的设计实现
本文采用的是命名共享内存机制,命名共享内存是通过文件映射(file mapping)实现的,文件映射是两个及多个进程间共享数据的一种高效的方法[3]。为了便于使用,系统设计中使用C++ 将命名共享内存操作封装成了一个动态链接库DLL。所有的进程调用这个该DLL,实现共享内存的管理,创建和使用。
下面是关键功能的核心代码。
(1) MemCreateM()函数:提供给主进程调用,调用CreateFileMapping函数来创建一个文件映射对象, 并返回文件映射对象的句柄。过调用MapViewOfFile函数在进程地址空间中就建立了一个与文件映射对象相关联的文件视,返回指向此文件视的指针。
D L L_
E X P O R T v o i d*__s t d c a l l MemCreateM(PStMemInfo pMemStrc)
{
pMemStrc->hMap = CreateFileMapping(INVALID_ HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(StMemory),
(LPCSTR)Name);
图2 测试平台多进程软件框架
2.2 各进程功能介绍
主进程负责测试平台的主要功能,包括各子进程的管理及数据交互,底层数据到功能信号的映射,测试过程的控制,测试曲线和结果的展示,测试数据的保存和查询,报表生成,人机交互等功能。主进程采用C#编程,C#面向对象编程和封装使得组织代码更容易,以提供最大的重用性。
p M e m S t r c->p V i e w=(P S t M e m o r y) MapViewOfFile(pMemStrc->hMap,
FILE_MAP_READ | FILE_MAP_ WRITE,
0,
VIEW_OFFSET,
VIEW_SIZE);
if (pMemStrc->pView == NULL)
{
printf("Master MapViewOfFile failed! - memId: %d\n", pMemStrc->memId);
goto Error;
}
}
进程间通信 共享内存
(2)MemCreateS()函数:提供给子进程调用,依次通过调用OpenFileMapping,MapViewOfFile函数打开并映射主进程已创建并命名好的文件映射对象,从而与主进程指向了同一地址空间的文件对象关联。
需要注意必须是主进程先调用MemCreateM(),然后子进程调用MemCreateS(),否则会子进程因为的文件映射对象不存在而出错。
D L L_
E X P O R T v o i d*__s t d c a l l MemCreateS(PStMemInfo pMemStrc, int crtSem) {
pMemStrc->hMap = OpenFileMapping(FILE_ MAP_ALL_ACCESS,
FALSE,
(LPCSTR)Name);
if (pMemStrc->hMap == NULL)
{
goto Error;
}
p M e m S t r c->p V i e w=(P S t M e m o r y) MapViewOfFile(pMemStrc->hMap,
FILE_MAP_READ | FILE_MAP_ WRITE,
0,
VIEW_OFFSET,
VIEW_SIZE);
if (pMemStrc->pView == NULL)
{
goto Error;
}
}
(3)MemClose():每个进程退出前都需要使用UnmapViewOfFile函数来删除指向映射内存的指针。它将销毁进程地址空间的文件视,并调用CloseHandle函数来关闭文件映射对象的句柄。
D L L_
E X P O R T v o i d__s t d c a l l MemCloseM(PStMemInfo pMemStrc)
{
UnmapViewOfFile(pMemStrc->pView);
pMemStrc->pView = NULL;
CloseHandle(pMemStrc->hMap);
pMemStrc->hMap = NULL;
}
最终实现的共享内存结构如图3所示,由主进程为每
一个子进程建立一块共享内存,每一个子进程的共享内存大小不一样,由主进程根据各子进程的功能需求来确定。
图3 测试平台软件共享内存结构图
(4)程序的启动流程如下:
a.C#主进程作为程序的启动入口,首先启动主进程;
b.主进程为每个子进程创建一个共享内存对象,设置该共享内存对象的键值,并通过System.Diagnostics. Process.Start()启动子进程,同时将对应的键值作为main 入口参数传递给子进程;
c.LabWindows/CVI子进程启动,通过指定键值连接到共享内存;
d.主进程和客户端进程通过共享内存进行数据和命令的交互。
2.4 使用和访问控制
当有两个或更多进程访问同一个文件映射时。每个进程都将在它自己的地址内获得一个内存指针以用来读取或修改文件内容。为了防止在多任务环境中发生数据操作上的错误,进程必须使用同步对象,本系统通过信号量机制来实现了对共享内存的互斥访问[4]。
使用流程和关键代码示例如下。
(1)主进程调用CreateSemaphore创建信号量,子进程调用OpenSemaphore打开信号量。
//create Semaphore for the process
sprintf_s(Name, NAME_MAX_LEN, "%s%d", SEM_NAME_M2S, pMemStrc->memId);
p M e m S t r c->p V i e w->S e m M2S4M= CreateSemaphore(NULL, 0, 1, (LPCSTR)Name);
//create Semaphore for the process
sprintf_s(Name, NAME_MAX_LEN, "%s%d", SEM_NAME_M2S, pMemStrc->memId);
p M e m S t r c->p V i e w->S e m M2S4S= OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, (LPCSTR)Name);
(2)主进程和子进程通过WaitForSingleObject( ) 函数一直等待直到信号量为有信号状态。
if (WaitForSingleObject(pMem->SemS2M4M, INFINITE) == WAIT_OBJECT_0)
{
//add you code here
}
(3)主进程或子进程释放信号量,至此,进程间就可通过自己内部协商的数据格式来访问共享内存,并进行相互通信了。
R e l e a s e S e m a p h o r e(p M e m S t r c->p V i e w->SemM2S4M, 1, NULL);
2.5 柔性化设计实现
为实现软件功能的柔性化定制,本系统采用可扩展标记语言. XML文件进行功能配置,如图所示,DevTypes 标签为平台目前支持的功能列表,因为设计时对每个功能开发了1个子进程,针对每一个特定的测试需求,只需要将对应的功能罗列到Devices标签中。主进程会根据Devices标签节点为本系统启动需要的子进程。只需要修改XML文件,不需修改任何代码,就可实现硬件和功能的快速配置。
每一个子进程也有各自的XML文件,来对更底层的通信接口进行配置。未来如果增加新的功能支持,也只需修改DevTypes标签中即可,从而真正实现了快速柔性化,高兼容性和可扩展性的软件设计。
3 结束语
通用测试平台方案投入使用已近两年,在公司的数个汽车电气部件测试系统开发项目中得到了应用,被测产品覆盖从汽车转向机,电机到液压泵等。应用结果表明,该平台可以极大地提高新产品的测试系统开发效率,具有非常好的可扩展性。共享内存的设计方案可以满足多进程软件的通信速率及实时性要求,多进程软件架构增强了软件的可靠性。
参考文献
[1] 都军民,戴宗妙.软件可靠性定量方法研究[J].舰船科
学技术,2003,25(2):58-61.
[2] 武庆钊,吕林森,周未东.基于共享内存的多进程任务
系统软件设计[J].航空电子技术,2021,52(4):44-49. [3] 刘晓达,张志祥,刘霞. 基于共享内存的IPC的应用
研究 [J]. 舰船电子工程,2003(1):25-28.
[4] 谢永刚,范琳,王忠民. 基于共享内存的进程间通信
在嵌入式软件测试中的应用 [J]. 计算机应用与软件,2011,28(2):106-108.
收稿日期:2022-05-12
作者简介:夏梦芝,硕士,工程师,从事电气、测试技术方
面的工作。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。