admin 发表于 2020-8-7 16:30:36

Codesys 使用共享内存 打通通讯

Codesys V3.5 平台   提供了库SysShm,其中包含了共享内存操作的接口函数:SysSharedMemoryClose;SysSharedMemoryCreate;SysSharedMemoryDelete;SysSharedMemoryGetPointer;SysSharedMemoryOpen2;SysSharedMemoryRead;SysSharedMemoryReadByte;SysSharedMemoryWrite;SysSharedMemoryWriteByte;
与其进行共享内存通讯的平台Linux,window;下的编程Demo:Linux:#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>


struct DataExchange {
    int i1;
    int i2;
};


int main(int argc, char **argv)



{

    struct DataExchange *pRead, *pWrite;

    char sSharedMemReadName = "_CODESYS_SharedMemoryTest_Write";

    char sSharedMemWriteName = "_CODESYS_SharedMemoryTest_Read";

    int fdRead = shm_open(sSharedMemReadName, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);

    printf("Shared Memory Read: %s %d\n\n",sSharedMemReadName, fdRead);

    ftruncate(fdRead, sizeof(*pRead));

    pRead = mmap(0, sizeof(*pRead), PROT_READ | PROT_WRITE, MAP_SHARED, fdRead, 0);

    close(fdRead);

    int fdWrite = shm_open(sSharedMemWriteName, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);

    printf("Shared Memory Write: %s %d\n\n",sSharedMemWriteName, fdWrite);

    ftruncate(fdWrite, sizeof(*pWrite));

    pWrite = mmap(0, sizeof(*pWrite), PROT_READ | PROT_WRITE, MAP_SHARED, fdWrite, 0);

    close(fdWrite);

    do

      sleep(1);

      printf("pRead->i1: %d pRead->i2: %d pWrite->i1: %d pWrite->i2: %d\n",

         pRead->i1, pRead->i2, pWrite->i1, pWrite->i2);

      printf("Press 'Enter' to increment values or 'q' and then 'Enter' to quit\n");

      pWrite->i1++;

      pWrite->i2--;

    } while (getchar() != 'q');

    munmap(pRead, sizeof(*pRead));

    shm_unlink(sSharedMemReadName);

    munmap(pWrite, sizeof(*pWrite));

    shm_unlink(sSharedMemWriteName);

    exit(0);

}

在Linux 下的编程注意 shm_open();若使用使有问题,可以用open()函数替代。Linux下共享内存的实质:是在/dev/shm/   文件夹下创建相应文件,路径为:/dev/shm/文件名;Codesys若运行于Linux下则是在该路径创建共享文件。

Windows平台,C++/ C # 编程:C++:OpenFileMapping();CreateFileMapping();MapViewOfFile();GetProcessWorkingSetSize(); //查询进程最大,最小工作集内存大小SetProcessWorkingSetSize(); //设定进程最大,最小工作集内存大小,在进程挂起,或最小化时,将部分内存交换到虚拟内存。VirtualLock();   //锁定进程的虚拟地址空间的指定块到物理内存。

C#:using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Threading;

namespace SharedMemoryWin
{

    // Example structure for data exchange
    internal struct DataExchange
    {
      internal Int32 i1;
      internal Int32 i2;
    }

    class Program
    {
      static void Main(string[] args)
      {
            DataExchange dataExchangeRead, dataExchangeWrite;         
            dataExchangeWrite.i1 = 0;
            dataExchangeWrite.i2 = 0;
         
            Console.Out.WriteLine("Press 'q' to quit");

            int dataSIze = Marshal.SizeOf(typeof(DataExchange));
         
            // Open a mapped file with read access and one with write access.
            using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
            using (var mmfWrite = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Read", dataSIze))
            {
                bool quit = false;
                while (!quit)
                {
                  using (var accessorRead = mmfRead.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Read))
                  using (var accessorWrite = mmfWrite.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Write))
                  {
                        // Read the structure
                        accessorRead.Read(0, out dataExchangeRead);
                        // Write the structure
                        accessorWrite.Write(0, ref dataExchangeWrite);

                        // Display the values
                        Console.Out.Write("Read i1: {0} i2: {1}       Write i1: {2} i2: {3}\r",
                                          dataExchangeRead.i1,
                                          dataExchangeRead.i2,
                                          dataExchangeWrite.i1,
                                          dataExchangeWrite.i2);

                        // Wait a second
                        Thread.Sleep(1000);

                        // Increment sample values
                        dataExchangeWrite.i1++;
                        dataExchangeWrite.i2--;

                        // Check quit condition
                        if(Console.KeyAvailable)
                            if (Console.ReadKey().KeyChar == 'q')      
                              quit = true;
                  }
                }
            }
      }
    }
}

askina 发表于 2020-9-3 16:44:40

这种是不是cosesys和C#只能在同一台电脑上

beginner 发表于 2021-2-25 14:14:30

RTE 可以用吗
页: [1]
查看完整版本: Codesys 使用共享内存 打通通讯