From 4484ed15fb54931a5533d2721dc3d92036c3d672 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Thu, 8 May 2014 13:34:28 +0000 Subject: [PATCH] Modbus TCP Stack implemented --- Modbus TCP/socket.can | 59 ----- {Modbus TCP => Modbus}/Common.cin | 0 {Modbus TCP => Modbus}/IPClient.can | 0 {Modbus TCP => Modbus}/IPServer.can | 0 Modbus/ModbusTcpCommon.cin | 368 +++++++++++++++++++++++++++ {Modbus TCP => Modbus}/TcpCommon.cin | 92 ++++--- {Modbus TCP => Modbus}/modbus.cfg | 348 ++++++++++++++++++++----- {Modbus TCP => Modbus}/sender.can | 0 Modbus/socket.can | 122 +++++++++ {Modbus TCP => Modbus}/socket.cfg | 0 10 files changed, 836 insertions(+), 153 deletions(-) delete mode 100644 Modbus TCP/socket.can rename {Modbus TCP => Modbus}/Common.cin (100%) rename {Modbus TCP => Modbus}/IPClient.can (100%) rename {Modbus TCP => Modbus}/IPServer.can (100%) create mode 100644 Modbus/ModbusTcpCommon.cin rename {Modbus TCP => Modbus}/TcpCommon.cin (68%) rename {Modbus TCP => Modbus}/modbus.cfg (86%) rename {Modbus TCP => Modbus}/sender.can (100%) create mode 100644 Modbus/socket.can rename {Modbus TCP => Modbus}/socket.cfg (100%) diff --git a/Modbus TCP/socket.can b/Modbus TCP/socket.can deleted file mode 100644 index f367184..0000000 --- a/Modbus TCP/socket.can +++ /dev/null @@ -1,59 +0,0 @@ -/*@!Encoding:1252*/ - -includes -{ - #include "TcpCommon.cin" -} - -variables -{ -} - -// Get information of local network interface such like ip address - -on preStart -{ - setStartdelay(1000); -} - -on start -{ - long fehler; - - TcpConnectTo("192.168.1.3", 502); -} - -on key 's' -{ - SendTcpData(); -} - -on key 'r' -{ - TcpRecv(); -} - -void SendTcpData() -{ - const word length = 12; - byte buffer[length]; - - // Modbus Application Header - buffer[00] = 0x0C; // [2] Transaction ID - buffer[01] = 0x2D; - buffer[02] = 0x00; // [2] Protocol ID = 0 - buffer[03] = 0x00; - buffer[04] = (length-6)>>8; // [2] Length; Number of bytes following - buffer[05] = (length-6)&0xFF; - buffer[06] = 0xFF; // [1] Unit identifier; not relevant - // Payload - buffer[07] = 0x01; // [1] Function Code; 1:Read DI; 2:Read DIO; 3:Read AIO; 4:Read AI; 5:Write 1 DO; 6:Write 1 AO; 7: Read Exeption, 15:Write n DO; 16:Write n AO; - buffer[08] = 0x00; // [2] Start address - buffer[09] = 0x00; - buffer[10] = 0x01; // [2] Number of items; 1:max 2000=0x7D0 - buffer[11] = 0xFF; - - TcpSnd(buffer); -} - -/**/ diff --git a/Modbus TCP/Common.cin b/Modbus/Common.cin similarity index 100% rename from Modbus TCP/Common.cin rename to Modbus/Common.cin diff --git a/Modbus TCP/IPClient.can b/Modbus/IPClient.can similarity index 100% rename from Modbus TCP/IPClient.can rename to Modbus/IPClient.can diff --git a/Modbus TCP/IPServer.can b/Modbus/IPServer.can similarity index 100% rename from Modbus TCP/IPServer.can rename to Modbus/IPServer.can diff --git a/Modbus/ModbusTcpCommon.cin b/Modbus/ModbusTcpCommon.cin new file mode 100644 index 0000000..05629c2 --- /dev/null +++ b/Modbus/ModbusTcpCommon.cin @@ -0,0 +1,368 @@ +/*@!Encoding:1252*/ +includes +{ + #include "TcpCommon.cin" +} + +variables +{ + struct ModbusApHeader { + word TxID; + word Protocol; + word Length; + byte UnitID; + byte FuncCode; + }; + struct ModbusRead { + struct ModbusApHeader Header; + word Address; + word Count; + }; + struct ModbusWriteSingle { + struct ModbusApHeader Header; + word Address; + word Value; + }; + struct ModbusWriteMultiple { + struct ModbusApHeader Header; + word Address; + word Count; + byte ByteCount; + }; +} + +// TODO: Add request timeout timers + +void ModbusInit(char Remote_IP[], word Remote_Port) +{ + TcpConnectTo("192.168.1.3", 502); +} + +void ModbusMakeHeader(struct ModbusApHeader mbap, byte length) +{ + mbap.TxID = 0x1234; // [2] Transaction ID. Not needed here? + mbap.Protocol = 0x0000; // [2] Protocol ID = 0 = Modbus + mbap.Length = length-6; // [2] Length; Number of bytes following + mbap.UnitID = 0xFF; // [1] Unit identifier; not relevant + + // 2:Read DIO; 3:Read AIO; 4:Read AI; 5:Write 1 DO; 6:Write 1 AO; 7: Read Exeption, 15:Write n DO; 16:Write n AO; +} + + + +void ModbusReadBits(word address, word count) +{ + const byte length = 12; + byte buffer[length]; + struct ModbusRead mbr; + + ModbusMakeHeader(mbr.Header, length); + // Payload + mbr.Header.FuncCode = 0x01; // [1] Function Code; 1: Read Coils (DI), 2: Read Discret Inputs (DIO), seems to be the same for WAGO 750-881 + mbr.Address = address; // [2] Start address + mbr.Count = count; // [2] Number of items; 1:max 2000=0x7D0 + + memcpy_h2n(buffer, mbr); + TcpSnd(buffer); + TcpRecv(); +} + +void OnModbusReceiveBits(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusReceiveBits: Received %d bytes: %d...", response[0], response[1]); +} + + +void ModbusReadRegisters(word address, word count) // 16 bit +{ + const byte length = 12; + byte buffer[length]; + struct ModbusRead mbr; + + ModbusMakeHeader(mbr.Header, length); + // Payload + mbr.Header.FuncCode = 0x03; // [1] Function Code; 3: Read Holding Registers (AI), 4: Read Input Registers (AIO), seems to be the same for WAGO 750-881 + mbr.Address = address; // [2] Start address + mbr.Count = count; // [2] Number of items; 1:max 2000=0x7D0 + + memcpy_h2n(buffer, mbr); + TcpSnd(buffer); + TcpRecv(); +} + +void OnModbusReceiveRegisters(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusReceiveRegisters: Received %d bytes: %d...", response[0]/2, response[1]<<8+response[2]); +} + + +void ModbusWriteBit(word address, byte value) +{ + const byte length = 12; + byte buffer[length]; + struct ModbusWriteSingle mbw; + + if (value >= 1) + value = 0xFF; + + ModbusMakeHeader(mbw.Header, length); + // Payload + mbw.Header.FuncCode = 0x05; // [1] Function Code; 5: Write Single Coil (DO) + mbw.Address = address; // [2] Output address + mbw.Value = value << 8; // [2] Output value (0x0000: Off, 0xFF00: On) + + memcpy_h2n(buffer, mbw); + TcpSnd(buffer); + TcpRecv(); +} + +void OnModbusConfirmBit(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusConfirmBit: Set bit 0x%X to %d", (response[0]<<8) + response[1], ((response[2]<<8) + response[3] > 0 ? 1 : 0)); +} + + +void ModbusWriteRegister(word address, word value) +{ + const byte length = 12; + byte buffer[length]; + struct ModbusWriteSingle mbw; + + ModbusMakeHeader(mbw.Header, length); + // Payload + mbw.Header.FuncCode = 0x06; // [1] Function Code; 5: Write Single Register (AO) + mbw.Address = address; // [2] Output address + mbw.Value = value; // [2] Output value + + memcpy_h2n(buffer, mbw); + TcpSnd(buffer); + TcpRecv(); +} + +void OnModbusConfirmRegister(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusConfirmRegister: Set register 0x%X to %d", (response[0]<<8) + response[1], (response[2]<<8) + response[3]); +} + + +void ModbusWriteBits(word address, word count, byte values[]) +{ + const byte length = 13 + 2; //_ceil(count / 8.0) + byte buffer[length]; + struct ModbusWriteMultiple mbw; + word i; + + ModbusMakeHeader(mbw.Header, length); + // Payload + mbw.Header.FuncCode = 0x0F; // [1] Function Code; 15: Write Multiple Bits (DOs) + mbw.Address = address; // [2] Output address + mbw.Count = count; // [2] Number of items; 1:max 1968=0x7B0 + mbw.ByteCount = 2; // [1] Number of bytes; = ceil(count/8) + + memcpy_h2n(buffer, mbw); + + for (i = 0; i < length-13; i++) + { + buffer[i+13] = values[i]; + } + TcpSnd(buffer); + TcpRecv(); +} + +void ModbusWriteBitsB(word address, word count, byte values[]) +{ + byte buffer[2]; // length + word length; + dword ellCount; + dword i; + dword j; + char str1[20*3], str2[20*3]; + + ellCount = elCount(values); + length = (word)_ceil(ellCount / 8.0); + //writeLineEx(0, 3, "ellCount: %d; length: %d", ellCount, length); + + if (ellCount % 8 != 0) + length--; + + for (i = 0; i < length; i++) + { + buffer[i] = 0; + for (j = 0; j < 8; j++) + { + buffer[i] |= (values[i*8 + j] & 0x01) << j; + //writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j)); + } + //writeLineEx(0, 3, "%d: %X", i, buffer[i]); + } + for (j = 0; j < ellCount % 8; j++) // wont be executed if there is no remainder + { + //writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j)); + buffer[length] |= (values[(length)*8 + j] & 0x01) << j; + } + //writeLineEx(0, 3, "%d: %X", length-1, buffer[length-1]); + + bin_to_strhex(values, str1); + bin_to_strhex(buffer, str2); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> ModbusWriteBitsB: Encoded %s to %s", str1, str2); + ModbusWriteBits(address, count, buffer); +} + +void OnModbusConfirmBits(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusConfirmBits: Set %d bits beginning with 0x%X", (response[2]<<8) + response[3], (response[0]<<8) + response[1]); +} + + +void ModbusWriteRegisters(word address, word count, word values[]) +{ + const byte length = 13 + 2; //13 + 2*count + byte buffer[length]; + struct ModbusWriteMultiple mbw; + word i; + + ModbusMakeHeader(mbw.Header, length); + // Payload + mbw.Header.FuncCode = 0x10; // [1] Function Code; 16: Write Multiple Registers (AOs) + mbw.Address = address; // [2] Output address + mbw.Count = count; // [2] Number of items; 1:max 123=0x7B + mbw.ByteCount = 2 * count; // [1] Number of bytes; = 2 * count + + memcpy_h2n(buffer, mbw); + + for (i = 0; i < length-13; i += 2) + { + buffer[i+13] = values[i] >> 8; + buffer[i+14] = values[i] & 0xFF; + } + TcpSnd(buffer); + TcpRecv(); +} + +void OnModbusConfirmRegisters(byte response[], dword size) +{ + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusConfirmRegisters: Set %d registers beginning with 0x%X", (response[2]<<8) + response[3], (response[0]<<8) + response[1]); +} + + + + + + +void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size) +{ + if (result == 0) + { + if (size == 0) + { + // Size of zero indicates that the socket was closed by the communication peer. + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); + g_%NODE_NAME%_Socket.Close(); + g_%NODE_NAME%_TcpState = CLOSED; + } + else + { + // Sucessfully received some bytes over the TCP/IP connection. + OnModbusReceive(buffer, size); + TcpRecv(); + } + } + else + { + gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); + g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); + g_%NODE_NAME%_Socket.Close(); + g_%NODE_NAME%_TcpState = CLOSED; + } +} + +void OnModbusReceive(byte buffer[], dword size) +{ + // Test transaction identifier? + // Test unit/device identifier? + char str[20*3]; + byte x[2]; + byte mbuffer[8192]; + dword i; + struct ModbusApHeader mbap; + + memcpy_n2h(mbap, buffer); + + if (size < 8) // No complete Modbus Application Header + { + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnModbusReceive Error: Tcp packet is too short: Length = %d", size); + return; + } + if (size != 6 + mbap.Length) // TCP packet not as large as specified in length field + { + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnModbusReceive Error: Size of Tcp packet is incorrect: Length = %d, has to be %d", size, 6 + mbap.Length); + return; + } + if (mbap.Protocol != 0) // Protocol is not Modbus (0x0000) + { + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnModbusReceive Error: Tcp packet is no Modbus packet: Protocol = %d", mbap.Protocol); + return; + } + // MBAP Header is OK :) Go on + + + if (mbap.FuncCode > 0x80) // Oh no, we got a exception! + { + switch(buffer[08]) // Let's have a look at the reason + { + case 0x01: // Illegal function code: Implementation failure! + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Illegal function code (0x01). The function code %d is unknown by the server.", buffer[7] & 0x0F); + return; + case 0x02: // Illegal data address: Configuration failure! + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Illegal data address (0x02). Please check your configuration!"); + return; + case 0x03: // Illegal data value: Depends. + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Illegal data value (0x03)."); + return; + case 0x04: // Server failure: We can't do anything about that, can we? + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Server failure (0x04). The server failed during execution."); + return; + case 0x05: // Acknowledge: That's ok. + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Acknowledge (0x05). The server simply needs more time to generate the response."); + return; + case 0x06: // Server busy: We should resend the request. + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Server busy (0x06). The request could not be accepted."); + return; + case 0x0A: // Gateway problem: We don't have gateways :) + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Gateway problem (0x0A). Gateway paths not available."); + return; + case 0x0B: // Gateway problem: We don't have gateways :) + writeLineEx(0, 3, "<%BASE_FILE_NAME%> OnModbusReceive Exception: Gateway problem (0x0B). The targeted device failed to respond."); + return; + } + } + + + // Extract the PDU for further processing + size -= 8; + for (i = 0; i < size; i++) + mbuffer[i] = buffer[i+8]; + + // Let's give the PDU to the corresponding function + switch (mbap.FuncCode) + { + case 0x01: + case 0x02: + OnModbusReceiveBits(mbuffer, size); + break; + case 0x03: + case 0x04: + OnModbusReceiveRegisters(mbuffer, size); + break; + case 0x05: + OnModbusConfirmBit(mbuffer, size); + break; + case 0x0F: + OnModbusConfirmBits(mbuffer, size); + break; + case 0x10: + OnModbusConfirmRegisters(mbuffer, size); + break; + } +} \ No newline at end of file diff --git a/Modbus TCP/TcpCommon.cin b/Modbus/TcpCommon.cin similarity index 68% rename from Modbus TCP/TcpCommon.cin rename to Modbus/TcpCommon.cin index 4211ff9..813d1f9 100644 --- a/Modbus TCP/TcpCommon.cin +++ b/Modbus/TcpCommon.cin @@ -14,6 +14,9 @@ variables char gIpLastErrStr[512] = ""; TcpSocket g_%NODE_NAME%_Socket; + dword g_%NODE_NAME%_RemoteIP = INVALID_IP; + word g_%NODE_NAME%_RemotePort = 0; + enum TcpState { NULL, OK, ERROR, CLOSED }; enum TcpState g_%NODE_NAME%_TcpState = NULL; @@ -38,33 +41,33 @@ dword TcpSetupIp(char Local_IP[]) switch (adapterCount) { case 0: - writelineex(0, 3, "<%BASE_FILE_NAME%> Error: There is no network interface available!"); + writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: There is no network interface available!"); stop(); return INVALID_IP; break; case 1: - writelineex(0, 1, "<%BASE_FILE_NAME%> Info: There is 1 network interface available!"); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There is 1 network interface available!"); if (adapterIndex != 1) { - writelineex(0, 3, "<%BASE_FILE_NAME%> Error: You have not selected the first adapter!"); + writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: You have not selected the first adapter!"); stop(); return INVALID_IP; } break; default: - writelineex(0, 1, "<%BASE_FILE_NAME%> Info: There are %d network interfaces available!", adapterCount); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: There are %d network interfaces available!", adapterCount); // // // // TEST \\ \\ \\ \\ for (i = 1; i <= adapterCount; i++) { IpGetAdapterDescription(i, text, size); - writelineex(0, 1, "<%BASE_FILE_NAME%> Info: Interface %d: %s", i, text); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Info: Interface %d: %s", i, text); } break; } if (IpGetAdapterAddress(adapterIndex, addresses, 1) != 0) { - writelineex(0, 3, "<%BASE_FILE_NAME%> Error: Could not retrieve IP address!"); + writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: Could not retrieve IP address!"); stop(); return INVALID_IP; } @@ -73,24 +76,24 @@ dword TcpSetupIp(char Local_IP[]) if (address == INVALID_IP) { - writelineex(0, 3, "<%BASE_FILE_NAME%> Error: IP address to be used is invalid!"); + writeLineEx(0, 3, "<%BASE_FILE_NAME%> Error: IP address to be used is invalid!"); stop(); return INVALID_IP; } IpGetAdapterDescription(adapterIndex, text, size); - writelineex(0, 1, "<%BASE_FILE_NAME%> Interface: %s", text); - writelineex(0, 1, "<%BASE_FILE_NAME%> Wrong interface? Change sysvar::TCPIP::AdapterIndex"); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Interface: %s", text); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Wrong interface? Change sysvar::TCPIP::AdapterIndex"); IpGetAdapterAddressAsString(adapterIndex, text, size); - writelineex(0, 1, "<%BASE_FILE_NAME%> Ip address: %s", text); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Ip address: %s", text); strncpy(Local_IP, text, 16); IpGetAdapterMaskAsString(adapterIndex, text, size); - writelineex(0, 1, "<%BASE_FILE_NAME%> Subnet mask: %s", text); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Subnet mask: %s", text); IpGetAdapterGatewayAsString(adapterIndex, text, size); - writelineex(0, 1, "<%BASE_FILE_NAME%> Gateway address: %s", text); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Gateway address: %s", text); return address; } @@ -116,19 +119,19 @@ word TcpOpenSocket() if (g_%NODE_NAME%_Socket.GetLastSocketError() != 0) { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(errorText, elcount(errorText)); - writelineex(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket on %s:%d, %s (%d)!", Local_IP, localPort, errorText, g_%NODE_NAME%_Socket.GetLastSocketError()); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket on %s:%d, %s (%d)!", Local_IP, localPort, errorText, g_%NODE_NAME%_Socket.GetLastSocketError()); } } while (g_%NODE_NAME%_Socket.GetLastSocketError() != 0 && i++ < 9); if (g_%NODE_NAME%_Socket.GetLastSocketError() != 0) { - writelineex(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket!"); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: could not open Tcp socket!"); return g_%NODE_NAME%_Socket.GetLastSocketError(); } else { - writelineex(0, 1, "<%BASE_FILE_NAME%> Tcp socket opened on %s:%d.", Local_IP, localPort); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Tcp socket opened on %s:%d.", Local_IP, localPort); } return 0; @@ -137,23 +140,33 @@ word TcpOpenSocket() word TcpConnectTo(char Remote_IP[], word remotePort) { dword remoteIp; + + // Convert IP string to Number + remoteIp = IpGetAddressAsNumber(Remote_IP); + if (remoteIp == INVALID_IP) + { + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Error: invalid server Ip address!"); + + return 1; + } + + return TcpConnectTo(remoteIp, remotePort); +} + +word TcpConnectTo(dword remoteIp, word remotePort) +{ long fehler; // Try to open a socket fehler = TcpOpenSocket(); if (fehler != 0) { + g_%NODE_NAME%_TcpState = ERROR; return fehler; } - // Convert IP string to Number - remoteIp = IpGetAddressAsNumber(Remote_IP); - if (remoteIp == INVALID_IP) - { - writelineex(0, 1, "<%BASE_FILE_NAME%> Error: invalid server Ip address!"); - - return 1; - } + g_%NODE_NAME%_RemoteIP = remoteIp; + g_%NODE_NAME%_RemotePort = remotePort; // Connect to Server @@ -171,11 +184,10 @@ word TcpConnectTo(char Remote_IP[], word remotePort) } else { - writelineex(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server %s:%d", Remote_IP, remotePort); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); g_%NODE_NAME%_TcpState = OK; return 0; } - } void OnTcpConnect(dword socket, long result) @@ -183,13 +195,13 @@ void OnTcpConnect(dword socket, long result) if (result != 0) { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writelineex(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", g_%NODE_NAME%_Socket.GetLastSocketError(), gIpLastErrStr); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpConnect error (%d): %s", g_%NODE_NAME%_Socket.GetLastSocketError(), gIpLastErrStr); g_%NODE_NAME%_TcpState = ERROR; return; } else { - writelineex(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> Successfully connected to server"); g_%NODE_NAME%_TcpState = OK; } } @@ -200,7 +212,7 @@ void TcpRecv() if (g_%NODE_NAME%_TcpState != OK) { - writelineex(0, 2, "TcpRecv: Socket status is not OK!"); + writeLineEx(0, 2, "TcpRecv: Socket status is not OK!"); return; } @@ -213,7 +225,7 @@ void TcpRecv() if (gIpLastErr != WSA_IO_PENDING) // Calling OnTcpReceive otherwise { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writelineex(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } @@ -222,6 +234,7 @@ void TcpRecv() return; } +/* void OnTcpReceive(dword socket, long result, dword address, dword port, char buffer[], dword size) { char str[20*3]; @@ -231,7 +244,7 @@ void OnTcpReceive(dword socket, long result, dword address, dword port, char buf if (size == 0) { // Size of zero indicates that the socket was closed by the communication peer. - writelineex(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive: Socket closed by peer"); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } @@ -239,18 +252,19 @@ void OnTcpReceive(dword socket, long result, dword address, dword port, char buf { // Sucessfully received some bytes over the TCP/IP connection. bin_to_strhex(gTcpRxBuffer, str); - writelineex(0, 1, "<%BASE_FILE_NAME%> OnTcpReceive: %s", str); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> OnTcpReceive: %s", str); } } else { gIpLastErr = g_%NODE_NAME%_Socket.GetLastSocketError(); g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writelineex(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> OnTcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } } +*/ void TcpSnd(byte buffer[]) { @@ -259,17 +273,21 @@ void TcpSnd(byte buffer[]) switch (g_%NODE_NAME%_TcpState) { case CLOSED: - TcpOpenSocket(); - break; + TcpConnectTo(g_%NODE_NAME%_RemoteIP, g_%NODE_NAME%_RemotePort); + if (g_%NODE_NAME%_TcpState != OK) + { + writeLineEx(0, 2, "TcpSnd: Reconnecting failed!"); + return; + } case OK: break; default: - writelineex(0, 2, "TcpSnd: Socket status is not OK!"); + writeLineEx(0, 2, "TcpSnd: Socket status is not OK!"); return; } bin_to_strhex(buffer, str); - writelineex(0, 1, "<%BASE_FILE_NAME%> TcpSnd: %s (Länge: %d)", str, elCount(buffer)); + writeLineEx(0, 1, "<%BASE_FILE_NAME%> TcpSnd: %s (Länge: %d)", str, elCount(buffer)); if (g_%NODE_NAME%_Socket.Send(buffer, elCount(buffer)) != 0) { @@ -278,7 +296,7 @@ void TcpSnd(byte buffer[]) if (gIpLastErr != WSA_IO_PENDING) { g_%NODE_NAME%_Socket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writelineex(0, 2, "<%BASE_FILE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); + writeLineEx(0, 2, "<%BASE_FILE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); g_%NODE_NAME%_Socket.Close(); g_%NODE_NAME%_TcpState = CLOSED; } diff --git a/Modbus TCP/modbus.cfg b/Modbus/modbus.cfg similarity index 86% rename from Modbus TCP/modbus.cfg rename to Modbus/modbus.cfg index a0cdb06..654942a 100644 --- a/Modbus TCP/modbus.cfg +++ b/Modbus/modbus.cfg @@ -1,12 +1,17 @@ -;CANoe Version |4|7|1|58720 modbus +;CANoe Version |4|7|1|42357 modbus Version: 8.2.40 Build 40 32 PRO -5 +10 APPDIR Vector.CANoe.SignalGenerators.DLL Vector.CANoe.SignalGenerators, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null Vector.CANoe.SignalGenerators.ComponentWrapper 1 1.0.1 +APPDIR Vector.CANoe.Debugger.DLL +Vector.CANoe.Debugger, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null +Vector.CANoe.Debugger.DebuggerComponent +2 +1.0.0 VGlobalConfiguration 1 Begin_Of_Object 17 VGlobalParameters 2 Begin_Of_Object @@ -411,12 +416,12 @@ VCaplOptionsStreamer 3 Begin_Of_Object End_Of_Object VCaplOptionsStreamer 3 VSVConfigurationStreamer 3 Begin_Of_Object 1 -701 +700 - + @@ -687,11 +692,11 @@ Begin_Of_Multi_Line_String Copyright (c) 2001-2006 Actipro Software LLC. All rights reserved. http://www.ActiproSoftware.com/Products/DotNet/ ---> kPersistNoLineBreak -t" IsAttached="False" /> + End_Of_Serialized_Data 3 End_Of_Object VDesktop 3 VDesktop 3 Begin_Of_Object @@ -1481,7 +1486,7 @@ VTraceAnalysisSingleFilter 17 Begin_Of_Object End_Of_Object VTraceAnalysisSingleFilter 17 VTraceAnalysisSingleFilter 17 Begin_Of_Object 3 -1 +0 0 0 End_Of_Object VTraceAnalysisSingleFilter 17 @@ -1537,7 +1542,10 @@ End_Of_Serialized_Data 14 16 0 17 -0 +1 +14 +ver=2: FT +End_Of_Serialized_Data 14 18 0 19 @@ -1557,24 +1565,24 @@ End_Of_Serialized_Data 14 23 1 14 -ver=2: FF +ver=2: FT End_Of_Serialized_Data 14 24 1 14 -ver=2: FF +ver=2: FT End_Of_Serialized_Data 14 25 0 26 1 14 -ver=2: FF +ver=2: FT End_Of_Serialized_Data 14 27 1 14 -ver=2: FF +ver=2: FT End_Of_Serialized_Data 14 0 2 @@ -3445,7 +3453,7 @@ Trace Window End_Of_Object VLogExportPersister 15 End_Of_Serialized_Data 14 -0 +3 0 0 290 @@ -3471,7 +3479,7 @@ MDI_DOCK_INFO_END 1 6 0 1 -1 -1 -1 -1 -15 105 1285 623 -6 1 0 0 0 0 0 0 1192 514 0 0 1 36756 1904 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 111 442 1 0 0 0 1 200 0 59422 1 +6 1 0 0 0 0 0 0 1192 514 0 0 1 36756 1904 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 111 442 1 0 0 0 1 284 0 59422 1 END_OF_DOCK_INFO 1 3 @@ -4256,7 +4264,7 @@ VUniqueBox 4 Begin_Of_Object VBoxRoot 5 Begin_Of_Object 1 3 -0 0 0 1 -1 -1 -8 -30 0 0 890 487 +0 0 2 3 -1 -1 -8 -30 0 0 890 487 1 @@ -4264,7 +4272,7 @@ MDI_DOCK_INFO_END 5 1 6 -0 1 -1 -1 -8 -30 0 0 890 487 +2 3 -1 -1 -8 -30 0 0 890 487 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 END_OF_DOCK_INFO 1 @@ -4272,7 +4280,7 @@ END_OF_DOCK_INFO 0 0 1 -1188 492 +859 382 END_OF_DESKTOP_DATA 6 0 1 0 0 -1 -1 44 44 1544 1005 @@ -4323,7 +4331,7 @@ End_Of_Object VGrMnBox 3 VDOLocalInfoStruct 3 Begin_Of_Object 3 1 -76 +88 VDAOBus 4 Begin_Of_Object 1 1 @@ -4516,7 +4524,7 @@ EOF_ASSEMBLYDATA 1 "socket.cbf" VIPBStackSetting 8 Begin_Of_Object 3 -2 +0 1 VIPBAdapterSetting 9 Begin_Of_Object 4 @@ -4562,7 +4570,243 @@ End_Of_Object VIPBAdapterSetting 9 0 End_Of_Object VIPBStackSetting 8 7 -NULL +NDebugger::VDebuggerHost 8 Begin_Of_Object +2 +0 +4 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "socket.can" +0 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "Common.cin" +1 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "ModbusCommon.cin" +2 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "TcpCommon.cin" +3 +End_Of_Object NDebugger::VFile 9 +VNETStandaloneComponent 9 Begin_Of_Object +1 +VNETControlBox 10 Begin_Of_Object +2 +VUniqueBox 11 Begin_Of_Object +1 +VBoxRoot 12 Begin_Of_Object +1 +3 +1 -1 2 3 -1 -1 -8 -30 171 76 688 306 +Debugger - Programm: socket [Debugging ausgeschaltet] +1 + +MDI_DOCK_INFO_END +5 +1 +6 +2 3 -1 -1 -8 -30 171 76 688 306 +6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +END_OF_DOCK_INFO +0 +-1 +0 +0 +0 +859 382 +END_OF_DESKTOP_DATA +6 +0 1 0 0 0 0 171 76 688 306 +6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +END_OF_DOCK_INFO +0 +-1 +0 +0 +0 +0 0 +END_OF_DESKTOP_DATA +END_OF_DESKTOP_DATA_COLLECTION +0 +0 1 +1 +6 +0 1 0 0 0 0 171 76 688 306 +6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +END_OF_DOCK_INFO +0 +-1 +0 +0 +0 +0 0 +END_OF_DESKTOP_DATA +6 +0 1 0 0 0 0 171 76 688 306 +6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +END_OF_DOCK_INFO +0 +-1 +0 +0 +0 +0 0 +END_OF_DESKTOP_DATA +END_OF_DESKTOP_DATA_COLLECTION +0 +END_OF_DESKTOP_MEMBER +{48CC8AD8-485E-4CF0-AB4F-37B0280AD2E5} +0 +End_Of_Object VBoxRoot 12 +1 -1 0 0 0 0 0 0 0 0 0 0 +End_Of_Object VUniqueBox 11 +1 +1 -1 0 0 0 0 0 0 0 0 0 0 +0 +End_Of_Object VNETControlBox 10 +132 +APPDIR Vector.CANoe.Debugger.DLL +Vector.CANoe.Debugger, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null +Vector.CANoe.Debugger.DebuggerComponent +1 +1 +APPDIR CANoe_Net.DLL +CANoe_Net, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null +Vector.CANalyzer.ApplicationSerializer +2 +mApplication +2 +APPDIR Vector.CANoe.Debugger.DLL +Vector.CANoe.Debugger, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null +Vector.CANoe.Debugger.DebuggerModel +3 +mModel +3 +APPDIR Components\Vector.CANalyzer.Serialization\1.5.0.0\Vector.CANalyzer.Serialization.dll +Vector.CANalyzer.Serialization, Version=1.5.0.0, Culture=neutral, PublicKeyToken=b273882a063429a6 +Vector.CANalyzer.Serialization.SerializationVersion +4 +SerializationVersion +4 +UInt16 +mMajor +1 +UInt16 +mMinor +0 +UInt16 +mPatch +0 +--TextFormatter: End of Object-- +--TextFormatter: End of Object-- +TypeRef:2 +2 +--TextFormatter: End of Object-- +TypeRef:3 +3 +Int32 +NrOfFiles +4 +Int32 +FileID0 +0 +Int32 +CurrentLine0 +0 +Int32 +FileID1 +1 +Int32 +CurrentLine1 +0 +Int32 +FileID2 +2 +Int32 +CurrentLine2 +0 +Int32 +FileID3 +3 +Int32 +CurrentLine3 +0 +Int32 +SelectedFileID +0 +Int32 +NrOfWatchedVariables +0 +String +WindowLayout +37 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Boolean +ShowOnlyLocalsVar +True +Boolean +ShowOnlyLocalsWatch +True +TypeRef:4 +SerializationVersion +5 +UInt16 +mMajor +1 +UInt16 +mMinor +0 +UInt16 +mPatch +3 +--TextFormatter: End of Object-- +--TextFormatter: End of Object-- +End_Of_Object VNETStandaloneComponent 9 +0 +End_Of_Object NDebugger::VDebuggerHost 8 + End_Of_Serialized_Data 7 End_Of_Object VProgrammedNode 7 0 @@ -4582,7 +4826,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -3411971265 +3370075276 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -4625,12 +4869,12 @@ MDI_DOCK_INFO_END 2 3 -1 -1 -8 -30 114 0 1146 491 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 END_OF_DOCK_INFO -1 +0 1 0 0 1 -1188 492 +1188 466 END_OF_DESKTOP_DATA 6 0 1 0 0 -1 -1 216 113 867 455 @@ -4690,7 +4934,7 @@ SS_END_COMMON_INFO EOF_MBSSDATA 1 -0 1 +0 0 @@ -4710,8 +4954,8 @@ EOF_MBSSDATA - - + + @@ -4765,8 +5009,8 @@ EOF_MBSSDATA - - + + @@ -4789,11 +5033,11 @@ EOF_MBSSDATA - - + + - + @@ -4866,7 +5110,7 @@ EOF_ASSEMBLYDATA 1 "IPServer.cbf" VIPBStackSetting 8 Begin_Of_Object 3 -2 +0 1 VIPBAdapterSetting 9 Begin_Of_Object 4 @@ -4969,7 +5213,7 @@ NULL End_Of_Object VDOLocalInfoStruct 3 0.000000 0 0 -1 1 0 59420 1 233 1 2882400001 98 331 309 760 2882400002 0 0 0 0 0 0 1 2882400001 972 972 311 311 2882400002 0 0 0 342574200 564561232 342632844 3 +1 1 0 59420 1 233 1 2882400001 419 652 305 689 2882400002 0 0 0 0 0 0 1 2882400001 1278 1278 307 307 2882400002 0 0 0 0 0 0 3 SS_BEGIN_COMMON_INFO 1 0 @@ -4981,7 +5225,7 @@ Ethernet 11 1 1 -564438760 1 0 0 0 1 1 0 0 0 2000 1 +339354440 1 0 0 0 1 1 0 0 0 2000 1 SS_BEGIN_COMMON_INFO 1 2 @@ -5017,7 +5261,7 @@ MDI_DOCK_INFO_END 1 6 0 1 -1 -1 -8 -30 162 249 890 645 -6 1 1010 180 0 0 300 180 300 180 0 61440 1 12180 1904 0 0 0 0 260 0 0 0 1 5 32767 1 59422 1 5 1011 185 4 6 433 1 10 0 0 1 201 0 59419 1 +6 1 1010 180 0 0 300 180 300 180 0 61440 1 12180 1904 0 0 0 0 260 0 0 0 1 5 32767 1 59422 1 5 1011 185 4 6 433 1 10 0 0 1 227 0 59419 1 END_OF_DOCK_INFO 1 2 @@ -5090,7 +5334,7 @@ End_Of_Serialized_Data 2 End_Of_Object VWriteBox 2 VWinStore 2 Begin_Of_Object 1 -22 2 3 -32088 -32000 -1 -1 -10088 -10000 -9070 -9233 +22 2 3 -1 -1 -1 -1 -10088 -10000 -9070 -9233 End_Of_Child_List End_Of_Object VWinStore 2 VWinStore 2 Begin_Of_Object @@ -5365,20 +5609,24 @@ HistoryEnd FiltersBegin Begin 3 0 0 --1 +2 +Netzwerke +( 0) +Busstatistik Signale + ( 1 ( 0 ) 0 ) SymbSelHeaderMgrBegin 1 6 0 1 200 0 0 1 1 100 0 0 2 0 100 0 0 3 0 75 1 1 -5 0 200 0 0 +5 0 200 1 1 6 1 200 0 0 SymbSelHeaderMgrEnd End Begin 3 0 0 --1 +0 SymbSelHeaderMgrBegin 1 4 0 1 200 0 0 @@ -5388,7 +5636,7 @@ SymbSelHeaderMgrBegin SymbSelHeaderMgrEnd End Begin -3 0 0 +3 0 -1 -1 SymbSelHeaderMgrBegin 1 3 @@ -5399,25 +5647,11 @@ SymbSelHeaderMgrEnd End FiltersEnd -0 0 - - - - - - - - - - - - - - +1 1 END_OF_WORKSPACE_MEMBER_DATA END_OF_WORKSPACE_MEMBER 1 -0 +1 0 END_OF_WORKSPACE_DATA diff --git a/Modbus TCP/sender.can b/Modbus/sender.can similarity index 100% rename from Modbus TCP/sender.can rename to Modbus/sender.can diff --git a/Modbus/socket.can b/Modbus/socket.can new file mode 100644 index 0000000..682f63b --- /dev/null +++ b/Modbus/socket.can @@ -0,0 +1,122 @@ +/*@!Encoding:1252*/ + +includes +{ + #include "ModbusCommon.cin" +} + +variables +{ + msTimer muster; + byte gX[2] = {1, 0}; +} + +// Get information of local network interface such like ip address + +on preStart +{ + writeClear(0); + setStartdelay(1000); +} + +on start +{ + long fehler; + + ModbusInit("192.168.1.3", 502); +} + +on key 'a' +{ + byte x[16] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; + ModbusWriteBitsB(0, 16, x); +} + +on key 's' +{ + byte x[16] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + ModbusWriteBitsB(0, 16, x); +} + +on key 'Y' +{ + ModbusWriteBit(0, 0); +} +on key 'y' +{ + ModbusWriteBit(0, 1); +} + +on key 'X' +{ + ModbusWriteBit(1, 0); +} +on key 'x' +{ + ModbusWriteBit(1, 1); +} + +on key 'C' +{ + ModbusWriteBit(2, 0); +} +on key 'c' +{ + ModbusWriteBit(2, 1); +} + +on key 'V' +{ + ModbusWriteBit(3, 0); +} +on key 'v' +{ + ModbusWriteBit(3, 1); +} + +on key '+' +{ + byte x[2] = {0xFF, 0xFF}; + ModbusWriteBits(0, 16, x); +} +on key '-' +{ + byte x[2] = {0x00, 0x00}; + ModbusWriteBits(0, 16, x); +} + +on key 't' +{ + setTimerCyclic(muster, 1); +} +on key 'T' +{ + cancelTimer(muster); +} + +on timer muster +{ + if (gX[0] != 0) + { + if (gX[0] == 0x80) + { + gX[0] = 0x00; + gX[1] = 0x01; + } + else + gX[0] <<= 1; + } + else + { + if (gX[1] == 0x80) + { + gX[0] = 0x01; + gX[1] = 0x00; + } + else + gX[1] <<= 1; + } + ModbusWriteBits(0, 16, gX); +} + +/**/ diff --git a/Modbus TCP/socket.cfg b/Modbus/socket.cfg similarity index 100% rename from Modbus TCP/socket.cfg rename to Modbus/socket.cfg