- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
labview编程技巧-----如何实现内存空间共享
录入:edatop.com 点击:
在C语言中,可以采用文件映射的方法,开辟一段内存空间,各个进程和线程可以利用这段共享内存空间进行数据交换,也就是写读操作,这里涉及到一个控制权限的问题,任何时刻,只能允许一个线程或者进程对内存空间进行操作,看一段代码,是通过API实现的内存空间共享.
#defineFILE_SIZE1024
staticHANDLEhMapFile;
staticLPVOIDlpMapAddress;
staticLPCTSTRg_szEventName="EventName";
voidWrite(char*data){
if(lpMapAddress!=NULL){
memset(lpMapAddress,0,FILE_SIZE);
sprintf((char*)lpMapAddress,"%s",data);
}
}
voidRead(){
if(lpMapAddress!=NULL){
printf("%sn",lpMapAddress);
}
}
voidProcess1(){//写数据
hMapFile=CreateFileMapping(
INVALID_HANDLE_VALUE,//Currentfilehandle.
NULL,//Defaultsecurity.
PAGE_READWRITE,//Read/writepermission.
0,//Max.objectsize.
FILE_SIZE,//SizeofhFile.
"MyFileMappingObject");//Nameofmappingobject.
if(hMapFile==NULL)
{
printf("Couldnotcreatefile-mappingobject.");
return;
}
//
lpMapAddress=MapViewOfFile(hMapFile,//Handletomappingobject.
FILE_MAP_ALL_ACCESS,//Read/writepermission
0,//Max.objectsize.
0,//SizeofhFile.
FILE_SIZE);//Mapentirefile.
if(lpMapAddress==NULL)
{
printf("Couldnotmapviewoffile.");
return;
}
::Sleep(10000);
//Writedata
ANDLEhEvent=::OpenEvent(
EVENT_MODIFY_STATE,
FALSE,
g_szEventName);
while(hEvent!=NULL){
scanf("%s",lpMapAddress);
::SetEvent(hEvent);
}
::CloseHandle(hEvent);
hEvent=INVALID_HANDLE_VALUE;
}
在LABVIEW如果想动态申请内存只能通过DLL或者CIN来实现,LABVIEW本身又不支持指针操作,实现非常困难,不过我们可以通过数组来实现内存的分配.
共享内存同全局变量一样,同样存在数据竞争的问题,我们可以把共享内存看成是内存数据块全局变量.
LABVIEW中防止数据竞争的最好办法是把读写操作在一个VI里,LABVIEW本身就会保证任意时刻只能有一个读写操作.
对于全局可读写变量,LABVIEW可以用内置全局变量也可以用FUNCTION GLOBAL(我前面的文章中专门谈到了FUNCTION GLOBAL 和AE的概念,可以参照一下)
在自动化控制领域,内存共享应用非常广泛,对CAN总线控制卡,有双口RAM的概念,对PLC有输入输出映射区,实际上指的都是固定的RAM 空间,相对于计算机来说,就是一段内存空间.
熟悉PLC的朋友都非常清楚,PLC是采用循环扫描的方式来运行程序的,扫描开始前,一次性地读入外部开关的状态,存入输入映射区中,在一次扫描程序运行期间,它的状态是不变的.
我们在LABVIEW设计控制程序时,也完全可以借用这个方法,实际上很多DSC和外部设备通过OPC通讯都是采用固定间隔更新的方法.
输入更新(开关,模拟量)--->写入共享内存------>程序处理------>输出更新(读共享内存,继电器,模拟量输出,写入硬件设备)
LABVIEW的共享内存是通过AE结合FUNCTIN GLOBAL实现的.
我们看一下它的实现过程.
首先定义了AE的四个动作,INIT READ WRITE READALL
然后定义的四个选择项,分别对应离散输入,线圈,输入寄存器,保持寄存器(MODBUS定义)
对应四中数据,分别在INIT的CASE中定义了长度为65536的数组,实际上定义了四个共享内存区 [p]
上图是读离散性输入的CASE,其他分别是读COILS,INPUT REG,HOLDING REG
其它写的CASE类似.
这样,我们在LABVIEW中任何位置,包括子VI,对这四个共享内存空间进行读写操作,实现的数据交换的功能.
#defineFILE_SIZE1024
staticHANDLEhMapFile;
staticLPVOIDlpMapAddress;
staticLPCTSTRg_szEventName="EventName";
voidWrite(char*data){
if(lpMapAddress!=NULL){
memset(lpMapAddress,0,FILE_SIZE);
sprintf((char*)lpMapAddress,"%s",data);
}
}
voidRead(){
if(lpMapAddress!=NULL){
printf("%sn",lpMapAddress);
}
}
voidProcess1(){//写数据
hMapFile=CreateFileMapping(
INVALID_HANDLE_VALUE,//Currentfilehandle.
NULL,//Defaultsecurity.
PAGE_READWRITE,//Read/writepermission.
0,//Max.objectsize.
FILE_SIZE,//SizeofhFile.
"MyFileMappingObject");//Nameofmappingobject.
if(hMapFile==NULL)
{
printf("Couldnotcreatefile-mappingobject.");
return;
}
//
lpMapAddress=MapViewOfFile(hMapFile,//Handletomappingobject.
FILE_MAP_ALL_ACCESS,//Read/writepermission
0,//Max.objectsize.
0,//SizeofhFile.
FILE_SIZE);//Mapentirefile.
if(lpMapAddress==NULL)
{
printf("Couldnotmapviewoffile.");
return;
}
::Sleep(10000);
//Writedata
ANDLEhEvent=::OpenEvent(
EVENT_MODIFY_STATE,
FALSE,
g_szEventName);
while(hEvent!=NULL){
scanf("%s",lpMapAddress);
::SetEvent(hEvent);
}
::CloseHandle(hEvent);
hEvent=INVALID_HANDLE_VALUE;
}
在LABVIEW如果想动态申请内存只能通过DLL或者CIN来实现,LABVIEW本身又不支持指针操作,实现非常困难,不过我们可以通过数组来实现内存的分配.
共享内存同全局变量一样,同样存在数据竞争的问题,我们可以把共享内存看成是内存数据块全局变量.
LABVIEW中防止数据竞争的最好办法是把读写操作在一个VI里,LABVIEW本身就会保证任意时刻只能有一个读写操作.
对于全局可读写变量,LABVIEW可以用内置全局变量也可以用FUNCTION GLOBAL(我前面的文章中专门谈到了FUNCTION GLOBAL 和AE的概念,可以参照一下)
在自动化控制领域,内存共享应用非常广泛,对CAN总线控制卡,有双口RAM的概念,对PLC有输入输出映射区,实际上指的都是固定的RAM 空间,相对于计算机来说,就是一段内存空间.
熟悉PLC的朋友都非常清楚,PLC是采用循环扫描的方式来运行程序的,扫描开始前,一次性地读入外部开关的状态,存入输入映射区中,在一次扫描程序运行期间,它的状态是不变的.
我们在LABVIEW设计控制程序时,也完全可以借用这个方法,实际上很多DSC和外部设备通过OPC通讯都是采用固定间隔更新的方法.
输入更新(开关,模拟量)--->写入共享内存------>程序处理------>输出更新(读共享内存,继电器,模拟量输出,写入硬件设备)
LABVIEW的共享内存是通过AE结合FUNCTIN GLOBAL实现的.
我们看一下它的实现过程.
首先定义了AE的四个动作,INIT READ WRITE READALL
然后定义的四个选择项,分别对应离散输入,线圈,输入寄存器,保持寄存器(MODBUS定义)
对应四中数据,分别在INIT的CASE中定义了长度为65536的数组,实际上定义了四个共享内存区 [p]
上图是读离散性输入的CASE,其他分别是读COILS,INPUT REG,HOLDING REG
其它写的CASE类似.
这样,我们在LABVIEW中任何位置,包括子VI,对这四个共享内存空间进行读写操作,实现的数据交换的功能.
上一篇:labview串口通讯的深入分析.
下一篇:labview的数据类型----BOOLEAN
AND
BOOLEAN
ARRAY