MATLAB uses shared memory to transfer data with applications

Preface

The easiest way for MATLAB/Simulink to transfer numerical calculations or simulation results to other application software or other hardware platforms is to use UDP communication. The communication protocol is simple to use, and there are encapsulation functions that support UDP communication in MATLAB, as well as in the Simulink module library. Encapsulation module for UDP communication. However, the security of this method is insufficient, and there is no synchronization mechanism, and it is difficult to customize the signal transmission mechanism and logic between different applications. There is also a process of unpacking data. It is more convenient to use UDP to transmit information on different hardware platforms. However, the efficiency and speed of data transmission under one platform is not ideal.
This document mainly introduces the use of shared memory on a hardware platform (for example, a computer) to transfer data calculated in MATLAB/Simulink to other application software. Or input information to control MATLAB/Simulink execution by other application software (such as vs, or user interaction interface software written in .Net, etc.). However, the disadvantage of shared memory is that mutual exclusion locks and synchronization operations require user-defined rules to enable orderly, correct, and efficient transfers between different applications. This article mainly talks about MATLAB operating shared memory by calling the mex function. For the method of Simulink operating shared memory, please refer to the blog post:
All the codes in this article can be obtained at the end of the article.

MATLAB shared memory

Shared memory is a system function provided by windows. You can write C, C++, or even C# to create shared memory and manipulate shared memory. Based on this, we can use the method of calling external C functions provided by MATLAB software, use C language and MATLAB to program jointly, call compiled C, and achieve the purpose of operating shared memory.
The specific way to realize shared memory in MATLAB is as follows:
1. Configure MATLAB mex compilation environment; first you need to install visual studio or C language compiler. Note that you need to install vs software and adapt to the version of MATLAB. For details, please refer to the input in MATLAB Command: mex -setup to select the compiler).
2. Convert the C function that operates the shared memory into a MEX file, and the MATLAB command to compile the C function is as follows:

mex write_register_double.c
在MATLAB命令窗中,将共享内存操作的MATLAB C混合编程的C文件编译成MEX文件
语法为 : mex 函数名称.c,上面编译的函数名为 write_register_double.c

3. After MATLAB compiles the C function correctly, it will convert the C function file into a MEX function file, and then use MATLAB to directly call the MEX file in the same way as calling the M function, and then write to the shared memory by calling the MEX function Data and information in the MATLAB environment.

MATLAB shared memory functions

One, MATLAB and C joint interactive function

This function is the entry function for MATLAB to call the C function, which can be understood as the main function. When MATLAB calls the C-compiled MEX file, MATLAB will use mexFunction as the entry function for calling MEX to call all functions in the entire C file. This function can be found in the MATLAB help file. Comment in the code to get the input parameter description of the function.
Among them: nlhs is the number of output parameters, as can be seen from the English name, the number of left-side arguments on the left side of the equal sign (Number of left-side arguments), abbreviated as nlhs
plhs is the output parameter matrix pointer, pointing to all the output parameters of the mex function . As can be seen from the English name, the parameter on the left side of the equal sign (Array of left-side output arguments) is abbreviated as plhs.
nrhs and prhs are the number of input parameters and the pointer of the input parameters, respectively.
The following function first obtains the pointers of the input parameters through the mxGetPr provided by MATLAB. These two pointers point to the parameter value and the offset address of the shared memory to be written to the shared memory, and then use these two parameters as the call to the shared memory write function write_register , To complete the operation of writing to shared memory, please see the second part of this section for the function of writing to shared memory.

/*******************************************************************************
* Function mexFunction()
* Goal  : The gateway routine called mexFunction is the entry point to the MEX
*         file. It is through this routine that MATLAB accesses the rest of the
*         routines in the MEX files. It takes the place of the main function in
*         the source code.
* IN    : - nlhs: Number of left-side arguments, or the size of the plhs array
*         - plhs: Array of left-side output arguments
*         - nrhs: Number of right-side arguments, or the size of the prhs array
*         - prhs: Array of right-side input arguments
* IN/OUT: -
* OUT   : -
*******************************************************************************/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    
    
  /* Declaration of local variables */
  unsigned short *register_address;
  unsigned char  *register_value;
  mwSignedIndex dims[2];

  /* Read input data */
  register_address = mxGetPr(prhs[0]);
  register_value   = mxGetPr(prhs[1]);

  /* Call of the C computational routine */
  write_register(*register_address, *register_value);
  return;
}

Two, write shared memory function

The function write_register for writing shared memory is shown below. According to the input shared memory offset address and shared memory write value value, the value is written into the memory with the offset address address. The internal operation of the specific function is very simple, that is, the value is written into the memory. Among them, sharedMemoryAddress is the base address of the shared memory, which is also the address dynamically obtained when calling the shared memory function. This variable is used in the shared memory write function, shared memory function, and read shared memory function. Therefore, the variable is declared as Global variables. For the development of shared memory functions, please see the third section of this section.

static volatile char * sharedMemoryAddress = NULL;
/*******************************************************************************
* Function write_register()
* Goal  : Write the current value to the desire HW register address
* IN    : - value to store in the register as an unsigned 8 bit
* IN/OUT: - address of the register in unsigned 16 bit
* OUT   : -
*******************************************************************************/
void write_register(unsigned short address, unsigned char value)
{
    
    
  /* Access the shared memory area */
  if (open_shared_memory() == 0)
  {
    
    
    /* Set the new value in the desired register */
    *(sharedMemoryAddress + address) = value;
  }
  else
  {
    
    
    getchar();
    exit(EXIT_FAILURE);
  }
}

Three, open up shared memory space function

Use the C function to apply for shared memory in the system. The code is as follows: The
most critical input when opening up shared memory is the tag of shared memory, that is, the SHARED_MEMORY_NAME in the function. This tag is used as the only sign of system shared memory; All marked applications can access and manipulate this shared memory.

/*******************************************************************************
* Function open_shared_memory()
* Goal  : Creation of a memory-mapped file to share data between 2 processes
* IN    : -
* IN/OUT: -
* OUT   : - Error status in integer coded as following:
*          > 0 => No error occurred and the shared memory has been created
*          > 1 => The process could not create the memory-mapped file object
*          > 2 => The process could not return a pointer to the file view
*******************************************************************************/
int open_shared_memory()
{
    
    
  /* Definition of the handle to the memory-mapped file object */
  HANDLE hMappingFile;

  /* Create a new shared memory area if it does not exist yet */
  if (sharedMemoryAddress == NULL)
  {
    
    
    /* Creation of the file mapping object */
    hMappingFile = CreateFileMapping(
      INVALID_HANDLE_VALUE, // use paging file
      NULL,                 // default security
      PAGE_READWRITE,       // read/write access
      0,                    // maximum object size (high-order DWORD)
      BUFFER_SIZE,          // maximum object size (low-order DWORD)
      SHARED_MEMORY_NAME);  // name of the mapping object
    /* Exception handling */
    if (hMappingFile == NULL)
    {
    
    
      /* The file mapping object could not have been created */
      _tprintf(TEXT("Could not create the shared memory called: %s\n"), SHARED_MEMORY_NAME);
      return 1;
    }
    /* Create a view of the file in the process address space */
    sharedMemoryAddress = MapViewOfFile(hMappingFile, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
    /* Exception handling */
    if (sharedMemoryAddress == NULL)
    {
    
    
      /* No pointer to the file view could have been returned */
      _tprintf(TEXT("Could not map the shared memory called: %s\n"), SHARED_MEMORY_NAME);
      /* The process no longer needs access to the file mapping object */
      CloseHandle(hMappingFile);
      return 2;
    }
  }
  /* No error occurred */
  return 0;
}

Four, read memory space function

Now that the shared memory write function has been introduced, it is natural to use the read shared memory function to read shared memory. This function needs to enter the offset address of the shared memory. When this offset address is consistent with the input offset address of the write shared memory, you can use the read shared memory function to get the value written by the write shared memory function. The specific code is as follows:

/*******************************************************************************
* Function read_register()
* Goal  : Get the current value of the desire HW register address that is mapped
*         on top of the offset address of the shared memory location
* IN    : - address of the register in unsigned 16 bit
* IN/OUT: -
* OUT   : - value stored in the register as an unsigned 8 bit
*******************************************************************************/
unsigned char read_register(unsigned short address)
{
    
    
  /* Access the shared memory area */
  if (open_shared_memory() == 0)
  {
    
    
    /* Output the value of the desired register */
    return *(sharedMemoryAddress + address);
  }
  else
  {
    
    
    getchar();
    exit(EXIT_FAILURE);
  }
}

5. The header file .h and some attachment information

Because the above functions use the function of mex to obtain the pointer and the function of opening up shared memory provided by windows, some header files need to be added. And declare some global variables to assist.

Six, experimental test

The specific function. c file and function declaration header file .h can download the source code at the end of the article.
The compressed package provides MATLAB/Simulink shared memory operation functions, among which read_register.c and write_register.c are responsible for reading and writing shared memory respectively. Users can directly compile these two functions with the MEX command to generate read_register.mex and write_register.mex functions. After the compilation is successful and the mex file is generated, two MATLAB windows can be opened for testing at the same time: one MATLAB calls write_register to write to the shared memory, while another MATLAB calls read_register to read the shared memory. When the offset address of the shared memory, that is, when the input addresses of these two functions are the same, the shared memory offset address that can be entered is an integer (for example, 0xA010). When the written value and the read value are the same, it is enough Experiments with these two MATLAB operating the shared memory address together. (Note that the read and write values ​​received by these two functions are of uint8 type, when the value passed into this function must be converted to uint8 type, such as uint8(255)); in
addition, the double value is also provided in the compressed package The read and write shared memory functions for operations are read_register_double.c and write_register_double.c respectively, and the MEX file has been compiled in the compressed package. Since the default value type in MATLAB is double, the user can directly input the variables in MATLAB for experiment.
The above content can transfer parameters between multiple MATLAB, similar to MATLAB and .Net, C, C# application interaction, use C# to call the shared memory function to read the value written by MATLAB, ( refer to Annex 2, github sharing The reference example of the memory function application and attachment 3, C# shared memory operation source code ), thus realizing the numerical interaction between MATLAB and other applications.

to sum up

Using MATLAB and C mixed programming, using open shared memory functions, read shared memory functions, write shared memory functions, and the entry mexfunction function of MATLAB and C mixed programming, you can complete the operation of MATLAB on shared memory, so as to realize MATLAB and Data transfer between other applications.

Comments and comments are welcome.

Source code download

Guess you like

Origin blog.csdn.net/qq_36320710/article/details/112004756