技术中心
 
 

LabVIEW教程之如何实现内存空间共享

   日期:2012-04-09     来源:中国测控网    

  在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可以用内置全局变量也可以用FUNCTIONGLOBAL(我前面的文章中专门谈到了FUNCTIONGLOBAL和AE的概念,可以参照一下)

  在自动化控制领域,内存共享应用非常广泛,对CAN总线控制卡,有双口RAM的概念,对PLC有输入输出映射区,实际上指的都是固定的RAM空间,相对于计算机来说,就是一段内存空间.

  熟悉PLC的朋友都非常清楚,PLC是采用循环扫描的方式来运行程序的,扫描开始前,一次性地读入外部开关的状态,存入输入映射区中,在一次扫描程序运行期间,它的状态是不变的.

  我们在LabVIEW设计控制程序时,也完全可以借用这个方法,实际上很多DSC和外部设备通过OPC通讯都是采用固定间隔更新的方法.

  输入更新(开关,模拟量)--->写入共享内存------>程序处理------>输出更新(读共享内存,继电器,模拟量输出,写入硬件设备)

  LabVIEW的共享内存是通过AE结合FUNCTINGLOBAL实现的.

  我们看一下它的实现过程.

  首先定义了AE的四个动作,INITREADWRITEREADALL

  然后定义的四个选择项,分别对应离散输入,线圈,输入寄存器,保持寄存器(MODBUS定义)

  对应四中数据,分别在INIT的CASE中定义了长度为65536的数组,实际上定义了四个共享内存区

  上图是读离散性输入的CASE,其他分别是读COILS,INPUTREG,HOLDINGREG

  其它写的CASE类似.

  这样,我们在LabVIEW中任何位置,包括子VI,对这四个共享内存空间进行读写操作,实现的数据交换的功能.

 
  
  
  
  
 
更多>同类技术
 
全年征稿 / 资讯合作
 
推荐图文
推荐技术
可能喜欢