codesys communicates with C# in shared memory

Keywords: C#

This section is about how codesys communicates with C# programs by sharing memory
Shared memory, multiple processes can read and write an area in memory to achieve the purpose of data interaction.

When using shared memory, you need to install the installation package SharedMemoryCommunication under codesys. If the package file needs to be used, please contact me by private mail

After installing codesys's SharedMemoryCommunication, let's start today's learning

1. Create a new project, and then add it in the library manager. In the Advanced tab.


2. Search SysShm and SysTypes2 Interfaces in the search box

In this way, the library is added. The name of the specific function in the library can be viewed in the library, and you can also see the introduction of other bloggers in Baidu. I'll skip it

3. Create a new DUT and select the structure as the type, that is, during communication, the data type is the established types. Similarly, you can also create a DUT for reading data and a DUT for writing data, which is more convenient when sharing memory. The first method is used in this experiment.

TYPE DataExchange :
STRUCT
	diValue1 : DINT;
	diValue2 : DINT;
	bValue3 :BOOL;
	
END_STRUCT
END_TYPE

4. Establishment of PLC program

Declare variable

// This program shows how to read and write to Shared Memory.
PROGRAM PLC_PRG
VAR
	tt: Ton;
	hShMemRead: RTS_IEC_HANDLE;
	ResultRead: RTS_IEC_RESULT;
	deInstRead : DataExchange;
	ReadResult: RTS_IEC_RESULT;
	iRead: __UXINT;
	
	hShMemWrite: RTS_IEC_HANDLE;
	ResultWrite: RTS_IEC_RESULT;
	deInstWrite : DataExchange;
	WriteResult: RTS_IEC_RESULT;
	iWrite: __UXINT;
	ulSize: UDINT := SIZEOF(DataExchange);
END_VAR

It should be noted that the name of shared memory must be consistent with that in C # or there will be communication failure

tt(IN := TRUE,PT:=T#2000MS);
IF tt.Q THEN				
	// Read structure from Shared Memory. 
	hShMemRead := SysSharedMemoryCreate('Test_Read', 0, ADR(ulSize), ADR(ResultRead));
	iRead := SysSharedMemoryRead(hShMemRead, 0, ADR(deInstRead), SIZEOF(deInstRead), ADR(ReadResult));
	iRead := SysSharedMemoryClose(hShm := hShMemRead);
	
	// Write structure to Shared Memory.
	hShMemWrite := SysSharedMemoryCreate('Test_Write', 0, ADR(ulSize), ADR(ResultWrite));	
	deInstWrite.diValue1 := deInstWrite.diValue1 + 2;
	deInstWrite.diValue2 := deInstWrite.diValue2 - 3;
	deInstWrite.bValue3 := TRUE;
	iWrite := SysSharedMemoryWrite(hShMemWrite, 0, ADR(deInstWrite), SIZEOF(deInstWrite), ADR(WriteResult));
	iWrite := SysSharedMemoryClose(hShm := hShMemWrite);
	
	tt(IN:=FALSE);
	tt(IN:=TRUE);
END_IF

5. In order to better experience the effect of shared memory, we are establishing visual Visualization. Just create a view according to your preferences.

Now let's open VS and set up the C# project,
The code is taken out directly

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;
        internal bool b1;
    }

    class Program
    {
        static void Main(string[] args)
        {
            DataExchange dataExchangeRead, dataExchangeWrite;            
            dataExchangeWrite.i1 = 0;   
            dataExchangeWrite.i2 = 0;
            dataExchangeWrite.b1 = true;


            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("Test_Write", dataSIze))
            using (var mmfWrite = MemoryMappedFile.CreateOrOpen("Test_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} b1 {2}      Write i1: {3} i2: {4} b1 {5}\r",
                                            dataExchangeRead.i1,
                                            dataExchangeRead.i2,
                                            dataExchangeRead.b1,

                                            dataExchangeWrite.i1,
                                            dataExchangeWrite.i2,
                                            dataExchangeWrite.b1);

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

                        // Increment sample values
                        dataExchangeWrite.i1++;
                        dataExchangeWrite.i2--;
                        dataExchangeWrite.b1 = true;

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

It should be noted that the data types in C# and CODESYS must match the names of shared memory

If there is a problem, let's communicate and study together

Posted by lorri on Mon, 20 Sep 2021 19:31:14 -0700