From eb6d28c71b2a9800bf3b523f555621cd7040aba1 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Fri, 29 Aug 2014 14:55:20 +0000 Subject: [PATCH] Rename generated.dbc and generated.vsysvar into Modbus.* DeviceInformation.cin struct device now contains all 4 bytes of the IP as fields MakeConfig.can Improved code and comments MakeConfig.can PollingModbusClient.can Removed the subnetting stuff. We simply can add the net to the node name --- Modbus-CAPL/include/CAPL/DEU Power.can | 10 - Modbus-CAPL/include/CAPL/MakeConfig.can | 363 +++++++++--------- .../include/CAPL/PollingModbusClient.can | 72 ++-- .../CAPL/include/DeviceInformation.cin | 6 +- .../include/DBC/{generated.dbc => Modbus.dbc} | 0 .../include/DBC/{generated.ini => Modbus.ini} | 0 .../{generated.vsysvar => Modbus.vsysvar} | 0 7 files changed, 228 insertions(+), 223 deletions(-) rename Modbus-CAPL/include/DBC/{generated.dbc => Modbus.dbc} (100%) rename Modbus-CAPL/include/DBC/{generated.ini => Modbus.ini} (100%) rename Modbus-CAPL/include/SysVars/{generated.vsysvar => Modbus.vsysvar} (100%) diff --git a/Modbus-CAPL/include/CAPL/DEU Power.can b/Modbus-CAPL/include/CAPL/DEU Power.can index 2cf7e15..ace9015 100644 --- a/Modbus-CAPL/include/CAPL/DEU Power.can +++ b/Modbus-CAPL/include/CAPL/DEU Power.can @@ -1,14 +1,4 @@ /*@!Encoding:1252*/ -includes -{ - -} - -variables -{ - -} - on sysvar sysvar::Airbus::ESS_DC1 { if (@this) diff --git a/Modbus-CAPL/include/CAPL/MakeConfig.can b/Modbus-CAPL/include/CAPL/MakeConfig.can index 82b7498..eeef94a 100644 --- a/Modbus-CAPL/include/CAPL/MakeConfig.can +++ b/Modbus-CAPL/include/CAPL/MakeConfig.can @@ -8,25 +8,25 @@ includes variables { - char[16] gIps[long]; // List IP addresses. These will be analysed + char[16] gIps[long]; // List of IP addresses. These will be analysed char gScanFirstIp[16]; // The first IP address that will be scanned - char gScanLastIp[16]; // The first IP address that will not be scanned anymore. + char gScanLastIp[16]; // The first IP address that will be scanned + byte skip255; // Whether the IP address .255 (broadcast in /24 nets) shall be skipped - char fnSysvar[40]; // Filename of Sysvars - char fnDbc[40]; // Filename of DBC - char name[20]; // Name of project (not important) - dword ips[50]; // detected IPs. We need this array for enumeration with integers + char fnSysvar[100]; // Filename of Sysvars + char fnDbc[100]; // Filename of DBC + dword ips[50]; // detected IPs. We need this array for enumeration with integers (assoc. arrays cannot be enumerated with integers :( ) file f; // The file we are writing to - byte gIpNets[long]; // A list of nets struct device gIpsSorted[long]; // The final array with the devices - dword gScanFirst, gScanLast; // The first and last IP address as dword - word ADi, ADn, ADl; // Some variables for "AnalyzeDevices" + dword gScanCurr, gScanLast; // The first and last IP address as dword + word ADi, ADn, ADl; // Some variables for AnalyzeDevices() (event driven, so global) - byte ggMaxTransmissionCount; - byte useThirdIpByteForNames; // Whether the third byte of the IP address shall be used in the node name - byte skip255; // Whether the IP address .255 (broadcast in /24) shall be skipped + byte ggMaxTransmissionCount; // temp var for gMaxTransmissionCount + + enum eNodeName {WholeIP, LastByte, TwoLastBytes, ThreeLastBytes} + enum eNodeName NodeNameStyle; // The style of the node name } on preStart @@ -35,25 +35,23 @@ on preStart // List of IPs of devices goes here ///strncpy(gIps[i++], "192.168.1.100", elCount(gIps)); ///strncpy(gIps[i++], "192.168.1.101", elCount(gIps)); - ///strncpy(gIps[i++], "192.168.100.2", elCount(gIps)); - ///strncpy(gIps[i++], "192.168.1.8", elCount(gIps)); // Scan a range of IPs for devices (if nothing was set above). Start and Stop go here - // Please note: Currently .255 will be skipped! Don't use this address for devices strncpy(gScanFirstIp, "192.168.1.2", elCount(gScanFirstIp)); strncpy(gScanLastIp, "192.168.1.255", elCount(gScanLastIp)); - // Whether the third byte of the IP address shall be used in the node name - useThirdIpByteForNames = 0; + // How the Node name shall be formatted + // LastByte: 192.168.12.34 --> Client_34 + // TwoLastBytes: 192.168.12.34 --> Client_12_34 + // ThreeLastBytes: 192.168.12.34 --> Client_168_12_34 + // WholeIp: 192.168.12.34 --> Client_192_168_12_34 + NodeNameStyle = LastByte; // Whether the IP address .255 (broadcast in /24) shall be skipped skip255 = 1; - // Name of the project - strncpy(name, "Modbus", elCount(name)); - // Paths to the generated files relative to MakeConfig.cfg - strncpy(fnSysvar, "include/SysVars/generated.vsysvar", elCount(fnSysvar)); - strncpy(fnDbc, "include/DBC/generated.dbc", elCount(fnDbc)); + strncpy(fnSysvar, "include/SysVars/Modbus.vsysvar", elCount(fnSysvar)); + strncpy(fnDbc, "include/DBC/Modbus.dbc", elCount(fnDbc)); OutputDebugLevel = Error; } @@ -96,10 +94,10 @@ void DetectDevices() { writeLineEx(0, 1, "Scanning from %s to %s with timeout of %d ms", gScanFirstIp, gScanLastIp, @sysvar::Config::Modbus::RequestTimeout); - gScanFirst = ipGetAddressAsNumber(gScanFirstIp); // We have to use big endian here + gScanCurr = ipGetAddressAsNumber(gScanFirstIp); // We have to use big endian here gScanLast = swapDWord(ipGetAddressAsNumber(gScanLastIp)); // But not here :) - writeLineEx(0, 0, "%d.%d.%d.%d ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24); + writeLineEx(0, 0, "%d.%d.%d.%d ", gScanCurr & 0xFF, (gScanCurr >> 8) & 0xFF, (gScanCurr >> 16) & 0xFF, gScanCurr >> 24); ModbusInit(gScanFirstIp, @sysvar::Config::Modbus::Port, @sysvar::Config::Modbus::RequestTimeout, 1); // Open socket and set variables ModbusReadBits(0, 1); // Start device detection } @@ -107,46 +105,43 @@ void DetectDevices() /// void DetectDevicesNext() { - gScanFirst = swapDWord(gScanFirst); - gScanFirst++; - if (skip255 && (gScanFirst & 0xFF) == 0xFF) // skip .255 + gScanCurr = swapDWord(gScanCurr); // Swap to increment + gScanCurr++; // Increment + if ((gScanCurr & 0xFF) == 0xFF) // If .255 { - gScanFirst++; - writeLineEx(0, 0, "%d.%d.%d.%d ", gScanFirst >> 24, (gScanFirst >> 16) & 0xFF, (gScanFirst >> 8) & 0xFF, gScanFirst & 0xFF); - } - else if (!skip255 && (gScanFirst & 0xFF) == 0x00) - { - writeLineEx(0, 0, "%d.%d.%d.%d ", gScanFirst >> 24, (gScanFirst >> 16) & 0xFF, (gScanFirst >> 8) & 0xFF, gScanFirst & 0xFF); + if (skip255) // If we shall skip .255 + gScanCurr++; + writeLineEx(0, 0, "%d.%d.%d.%d ", gScanCurr >> 24, (gScanCurr >> 16) & 0xFF, (gScanCurr >> 8) & 0xFF, gScanCurr & 0xFF); } - if (gScanFirst > gScanLast) + if (gScanCurr > gScanLast) // If we are beyond the last ip address { - @sysvar::Config::Modbus::MaxTransmissionCount = ggMaxTransmissionCount; - MakeIpNets(); + @sysvar::Config::Modbus::MaxTransmissionCount = ggMaxTransmissionCount; // reset + MakeIpNets(); // Continue with Step 2 return; } - gScanFirst = swapDWord(gScanFirst); + gScanCurr = swapDWord(gScanCurr); // Swap back writeEx(0, 0, "."); // Write something so the user knows something is happening - gRemoteIP = gScanFirst; // Don't open new socket, it takes too much time. This means we should use UDP here! + gRemoteIP = gScanCurr; // Don't open new socket, it takes too much time. This means we should use UDP or EIL here! ModbusReadBits(0, 1); // Scan the next device } /// void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap) { - DetectDevicesNext(); // Timeout, NotSent, Exception! We will go to the next device + DetectDevicesNext(); // Timeout, NotSent or Exception! We will go to the next device } /// void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq) { - ipGetAddressAsString(gScanFirst, gIps[gScanFirst], 16); // store the detected device's IP address + ipGetAddressAsString(gScanCurr, gIps[gScanCurr], 16); // store the detected device's IP address DetectDevicesNext(); // and continue } // Step 2: Sort into subnets and create structure -// Sort the IPs from gIps to gIpsSorted and add their subnet to gIpNets +// Sort the IPs from gIps to gIpsSorted /// void MakeIpNets() { @@ -159,16 +154,17 @@ void MakeIpNets() return; } - for (long i : gIps) // Go through all devices + for (long i : gIps) // Iterate all devices { ipNum = ipGetAddressAsNumber(gIps[i]); // convert IP to dword - gIpNets[(ipNum >> 16) & 0xFF] = 1; // register subnet ips[gIpsSorted.size()] = ipNum; // add ip address to normal array // fill the device structure array: strncpy(gIpsSorted[ipNum].IP, gIps[i], 16); // set .IP - ltoa((ipNum >> 16) & 0xFF, gIpsSorted[ipNum].IpNet, 10); // set .IpNet - ltoa((ipNum >> 24) & 0xFF, gIpsSorted[ipNum].IpLsb, 10); // set .IpLsb + ltoa((ipNum ) & 0xFF, gIpsSorted[ipNum].Ip1, 10); // set .Ip1 + ltoa((ipNum >> 8) & 0xFF, gIpsSorted[ipNum].Ip2, 10); // set .Ip2 + ltoa((ipNum >> 16) & 0xFF, gIpsSorted[ipNum].Ip3, 10); // set .Ip3 + ltoa((ipNum >> 24) & 0xFF, gIpsSorted[ipNum].Ip4, 10); // set .Ip4 gIps.Remove(i); } @@ -182,7 +178,7 @@ void MakeIpNets() void AnalyzeDevices() { // Init counters - ADn = 1; // expect 10 responses + ADn = 1; // expect 1 response ADi = 0; // First IP address ADl = gIpsSorted.Size(); @@ -203,17 +199,19 @@ void AnalyzeDevices() /// void AnalyzeDevicesNext() { - if (strlen(gIpsSorted[ips[ADi]].DeviceIOs.Modules) > 0) - gIpsSorted[ips[ADi]].DeviceIOs.Modules[strlen(gIpsSorted[ips[ADi]].DeviceIOs.Modules)-1] = 0; + // clean up the string of the previous devices + if (strlen(gIpsSorted[ips[ADi]].DeviceIOs.Modules) > 0) // If we do have some Modules in this string + gIpsSorted[ips[ADi]].DeviceIOs.Modules[strlen(gIpsSorted[ips[ADi]].DeviceIOs.Modules)-1] = 0; // Remove the last comma (set the char to NUL) + // print the result writeEx(0, 1, ": AOs: %d, AIs: %d, DOs: %d, DIs: %d --> %s", gIpsSorted[ips[ADi]].DeviceIOs.OutputRegisters, gIpsSorted[ips[ADi]].DeviceIOs.InputRegisters, gIpsSorted[ips[ADi]].DeviceIOs.OutputBits, gIpsSorted[ips[ADi]].DeviceIOs.InputBits, gIpsSorted[ips[ADi]].DeviceIOs.Modules); - if (++ADi >= ADl) // we have analyzed all devices + if (++ADi >= ADl) // continue with the next device. If we have analyzed all devices { MakeFiles(); // go to Step4 return; } - ADn = 1; // expect 10 responses + ADn = 1; // expect 1 response again gRemoteIP = ips[ADi]; // Next IP address writeLineEx(0, 1, "Analyzing %s", gIpsSorted[ips[ADi]].Ip); // request something special to get the vendor @@ -226,12 +224,10 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep switch (error) { - case Timeout: - return; case Exception: memcpy_n2h(mbreq, gQueueAck[mbap.TxID].Buffer); - if (mbreq.Address == 0x1000 && ex == IllegalDataAddress) // We requested Wago SerialCode and it didn't work --> Not Wago --> B&R. Not future proof + if (mbreq.Address == 0x1000 && ex == IllegalDataAddress) // We requested B&R MAC and it didn't work --> Not B&R --> Wago. Not future proof :( { gIpsSorted[ips[ADi]].Vendor = Wago; // request information @@ -241,6 +237,8 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep writeLineEx(0, 3, "Error while analyzing %s! The device respond with exception code %d! Ignoring...", gIpsSorted[ips[ADi]].IP, ex); break; + case Timeout: + return; // Timeout is unimportant, it means the request will be resent case FinalTimeout: writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP); break; @@ -261,7 +259,7 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep /// void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq) { - if (mbreq.Address == 0x1000) // We detected a B&R device + if (mbreq.Address == 0x1000) // We detected a B&R device (from MAC address) { gIpsSorted[ips[ADi]].Vendor = BuR; @@ -270,10 +268,11 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct return; } + // else parse the received data _DeviceParseRegister(gIpsSorted[ips[ADi]], mbreq.Address, mbres.Data, mbreq.Count); - if (--ADn == 0) // If we received all registers - AnalyzeDevicesNext(); + if (--ADn == 0) // If we received all registers + AnalyzeDevicesNext(); // Continue with the next device } // Step 4: Create the files with the queried data @@ -313,123 +312,126 @@ void GenSysvars() PutString(" \n"); PutString(" \n"); - for (long net : gIpNets) + PutString(" \n"); + + for (long ipN : gIpsSorted) { - byte nett; - nett = net; - PutString(" \n"); + if ((ipN >> 16) & 0xFF != net) // This IP does not belong to the current net + continue; + DeviceInit(gIpsSorted[ipN].Vendor); - for (long ipN : gIpsSorted) - { - if (((ipN >> 16) & 0xFF) != net) - continue; - DeviceInit(gIpsSorted[ipN].Vendor); - - PutString(" \n"); + case ThreeLastBytes: + PutString(gIpsSorted[ipN].Ip2); + PutString("_"); + case TwoLastBytes: + PutString(gIpsSorted[ipN].Ip3); + PutString("_"); + case LastByte: + PutString(gIpsSorted[ipN].Ip4); + return; + default: + writeDbg(MbError, "The NodeNameStyle %d is unknown, please use a value of the enum!", NodeNameStyle); + runError(1001, 0); + break; + } + PutString("\" comment=\"Server with ip address '"); + PutString(gIpsSorted[ipN].Ip); + PutString("'\">\n"); - // Namespace Config - PutString(" \n"); - // IP - PutString(" \n"); - // Intveral - PutString(" \n"); - PutString(" \n"); + // Namespace Config + PutString(" \n"); + // IP + PutString(" \n"); + // Intveral + PutString(" \n"); + PutString(" \n"); - //Namespace Info - PutString(" \n"); - // Vendor - PutString(" \n"); - PutString(" \n"); - PutString(" \n"); - PutString(" \n"); - PutString(" \n"); - PutString(" \n"); - // SerialCode - PutString(" \n"); - // DeviceCode - PutString(" \n"); - // Modules - PutString(" \n"); - // InputRegisters - PutString(" \n"); - // InputBits - PutString(" \n"); - // OutputRegisters - PutString(" \n"); - // OutputBits - PutString(" \n"); - PutString(" \n"); + //Namespace Info + PutString(" \n"); + // Vendor + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + // SerialCode + PutString(" \n"); + // DeviceCode + PutString(" \n"); + // Modules + PutString(" \n"); + // InputRegisters + PutString(" \n"); + // InputBits + PutString(" \n"); + // OutputRegisters + PutString(" \n"); + // OutputBits + PutString(" \n"); + PutString(" \n"); - // Namespace Data - PutString(" \n"); - // InputRegisters - PutString(" \n"); - // InputBits - PutString(" \n"); - // OutputRegisters - PutString(" \n"); - // OutputBits - PutString(" \n"); + // Namespace Data + PutString(" \n"); + // InputRegisters + PutString(" \n"); + // InputBits + PutString(" \n"); + // OutputRegisters + PutString(" \n"); + // OutputBits + PutString(" \n"); - PutString(" \n"); - PutString(" \n"); - } - PutString(" \n"); + PutString(" \n"); + PutString(" \n"); } PutString(" \n"); @@ -482,12 +484,25 @@ void GenDbc() for (long ipN : gIpsSorted) { PutString(" Client_"); - if (useThirdIpByteForNames) - { - PutString(gIpsSorted[ipN].IpNet); - PutString("_"); - } - PutString(gIpsSorted[ipN].IpLsb); + switch (NodeNameStyle) // Add the IP bytes depending on the style. Don't break anywhere. + { + case WholeIp: + PutString(gIpsSorted[ipN].Ip1); + PutString("_"); + case ThreeLastBytes: + PutString(gIpsSorted[ipN].Ip2); + PutString("_"); + case TwoLastBytes: + PutString(gIpsSorted[ipN].Ip3); + PutString("_"); + case LastByte: + PutString(gIpsSorted[ipN].Ip4); + break; + default: + writeDbg(MbError, "The NodeNameStyle %d is unknown, please use a value of the enum!", NodeNameStyle); + runError(1001, 0); + return; + } } PutString("\n\n\n\n"); PutString("BA_DEF_ BU_ \"NodeLayerModules\" STRING ;\n"); @@ -497,9 +512,7 @@ void GenDbc() PutString("BA_DEF_DEF_ \"DBName\" \"\";\n"); PutString("BA_DEF_DEF_ \"BusType\" \"Ethernet\";\n"); PutString("BA_ \"BusType\" \"Ethernet\";\n"); - PutString("BA_ \"DBName\" \""); - PutString(name); - PutString("\";\n"); + PutString("BA_ \"DBName\" \"Modbus\";\n"); f.Close(); } diff --git a/Modbus-CAPL/include/CAPL/PollingModbusClient.can b/Modbus-CAPL/include/CAPL/PollingModbusClient.can index 42a7f7f..9fb4954 100644 --- a/Modbus-CAPL/include/CAPL/PollingModbusClient.can +++ b/Modbus-CAPL/include/CAPL/PollingModbusClient.can @@ -1,7 +1,7 @@ /*@!Encoding:1252*/ // This file is the Modbus Client for Airbus CIDS -// It automatically and periodically reads all input bits and registers and writes them to SysVars %BUSTYPE%%CHANNEL%::%NODE_NAME%::Data +// It automatically and periodically reads all input bits and registers and writes them to SysVars %BUSTYPE%::%NODE_NAME%::Data // It also reacts on changes in the output SysVars and write those to the Modbus device. includes @@ -27,9 +27,9 @@ on preStart on start { char ip[16]; - sysGetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config", "IP", ip, elCount(ip)); // Get IP address of device from sysvars config + sysGetVariableString("%BUS_TYPE%::%NODE_NAME%::Config", "IP", ip, elCount(ip)); // Get IP address of device from sysvars config - DeviceInit(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::Vendor); // Set all device specific parameters (Wago / B&R) + DeviceInit(@sysvar::%BUS_TYPE%::%NODE_NAME%::Info::Vendor); // Set all device specific parameters (Wago / B&R) writeDbg(MbInfo, "Connecting to %s:%d", ip, @sysvar::Config::Modbus::Port); ModbusInit(ip, @sysvar::Config::Modbus::Port, @sysvar::Config::Modbus::RequestTimeout, @sysvar::Config::Modbus::MaxTransmissionCount); // Connect to device. Opens socket and connection or what ever @@ -37,11 +37,11 @@ on start if (gSocketState < CONNECTING) // We are not connecting and not connected return; - ModbusReadOutBits(thisDev.Addr.Read.OutputBits, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits); // Read the start status of the output bits - ModbusReadOutRegisters(thisDev.Addr.Read.OutputRegisters, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters); // Read the start status of the output registers + ModbusReadOutBits(thisDev.Addr.Read.OutputBits, @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::OutputBits); // Read the start status of the output bits + ModbusReadOutRegisters(thisDev.Addr.Read.OutputRegisters, @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::OutputRegisters); // Read the start status of the output registers - if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval > 0) // Start the polling timer - setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval); + if (@sysvar::%BUS_TYPE%::%NODE_NAME%::Config::Interval > 0) // Start the polling timer + setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%::%NODE_NAME%::Config::Interval); } // Stop all transactions and close connection @@ -72,10 +72,10 @@ void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException case NotSent: break; case FinalTimeout: - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); - for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i] = -1; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputBits"); + for (i = 0; i < @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::InputBits; i++) + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::InputBits[i] = -1; + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputBits"); break; default: writeDbg(MbError, "OnModbusReadBitsFailed: Unkown error: %d", error); @@ -96,10 +96,10 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep case NotSent: break; case FinalTimeout: - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); - for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = -1; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputRegisters"); + for (i = 0; i < @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::InputRegisters; i++) + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::InputRegisters[i] = -1; + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputRegisters"); break; default: writeDbg(MbError, "OnModbusReadBitsFailed: Unkown error: %d", error); @@ -134,24 +134,24 @@ void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[] switch (mbres.Header.FuncCode) // We assume that we separate between 0x01 and 0x02 even though the address space may be the same { case ReadBitsOut: // Read output bits - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "OutputBits"); offset = mbreq.Address - thisDev.Addr.Read.OutputBits; // Get the offset to the base output bit address for (i = 0; i < mbreq.Count; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i + offset] = bitStatus[i]; + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::OutputBits[i + offset] = bitStatus[i]; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits"); + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "OutputBits"); break; case ReadBitsIn: // Read input bits - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputBits"); offset = mbreq.Address - thisDev.Addr.Read.InputBits; // Get the offset to the base input bit address for (i = 0; i < mbreq.Count; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputBits[i + offset] = bitStatus[i]; + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::InputBits[i + offset] = bitStatus[i]; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputBits"); break; default: @@ -169,24 +169,24 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct switch (mbres.Header.FuncCode) // We assume that we separate between 0x03 and 0x04 even though the address space may be the same { case ReadRegistersOut: // Read output registers - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "OutputRegisters"); offset = mbreq.Address - thisDev.Addr.Read.OutputRegisters; // Get the offset to the base output register address for (i = 0; i < mbreq.Count; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i + offset] = mbres.Data[i]; + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::OutputRegisters[i + offset] = mbres.Data[i]; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "OutputRegisters"); break; case ReadRegistersIn: // Read input registers - sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); + sysBeginVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputRegisters"); offset = mbreq.Address - thisDev.Addr.Read.InputRegisters; // Get the offset to the base input bit address for (i = 0; i < mbreq.Count; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i + offset] = mbres.Data[i]; + @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::InputRegisters[i + offset] = mbres.Data[i]; - sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); + sysEndVariableStructUpdate("%BUS_TYPE%::%NODE_NAME%::Data", "InputRegisters"); break; default: @@ -250,38 +250,38 @@ void OnModbusClientPanics(enum FatalErrors reason) // The timer will continuously poll the input registers and intput bits on timer gtRead { - ModbusReadRegisters(thisDev.Addr.Read.InputRegisters, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters); - ModbusReadBits(thisDev.Addr.Read.InputBits, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits); + ModbusReadRegisters(thisDev.Addr.Read.InputRegisters, @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::InputRegisters); + ModbusReadBits(thisDev.Addr.Read.InputBits, @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::InputBits); } // If Data::OutputBits is changed we will send this update to the device -on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits +on sysvar %BUS_TYPE%::%NODE_NAME%::Data::OutputBits { word count, i; byte bitStatus[1968]; - count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits; + count = @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::OutputBits; for (i = 0; i < count; i++) // Copy the data from SysVars to byte[] - bitStatus[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputBits[i]; + bitStatus[i] = @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::OutputBits[i]; ModbusWriteBitsB(0, count, bitStatus); // Send update command } // If Data::OutputRergisters is changed we will send this update to the device -on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters +on sysvar %BUS_TYPE%::%NODE_NAME%::Data::OutputRegisters { word count, i; word regValues[123]; - count = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters; + count = @sysvar::%BUS_TYPE%::%NODE_NAME%::Info::OutputRegisters; for (i = 0; i < count; i++) // Copy the data from SysVars to word[] - regValues[i] = @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i]; + regValues[i] = @sysvar::%BUS_TYPE%::%NODE_NAME%::Data::OutputRegisters[i]; ModbusWriteRegisters(0, count, regValues); // Send update command } // Config::Interval is changed we will update the timer gtRead accordingly -on sysvar %BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval +on sysvar %BUS_TYPE%::%NODE_NAME%::Config::Interval { if (@this <= 0) gtRead.Cancel(); diff --git a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin index efe49c2..e178a84 100644 --- a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin +++ b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin @@ -53,8 +53,10 @@ variables struct device // A structure that contains information about an Modbus device. Used in MakeConfig. { char Ip[16]; // String: The IP address - char IpLsb[4]; // String: The last byte of the IP address. Used as index of node name - char IpNet[4]; // String: The second last byte of the IP. Used as index of net + char Ip4[4]; // String: The last byte of the IP address. + char Ip3[4]; // String: The third byte of the IP. + char Ip2[4]; // String: The second byte of the IP. + char Ip1[4]; // String: Thefirst byte of the IP. enum Vendor Vendor; // The Vendor (Wago / B&R) word SerialCode; // Serial Code word DeviceCode; // Device Code diff --git a/Modbus-CAPL/include/DBC/generated.dbc b/Modbus-CAPL/include/DBC/Modbus.dbc similarity index 100% rename from Modbus-CAPL/include/DBC/generated.dbc rename to Modbus-CAPL/include/DBC/Modbus.dbc diff --git a/Modbus-CAPL/include/DBC/generated.ini b/Modbus-CAPL/include/DBC/Modbus.ini similarity index 100% rename from Modbus-CAPL/include/DBC/generated.ini rename to Modbus-CAPL/include/DBC/Modbus.ini diff --git a/Modbus-CAPL/include/SysVars/generated.vsysvar b/Modbus-CAPL/include/SysVars/Modbus.vsysvar similarity index 100% rename from Modbus-CAPL/include/SysVars/generated.vsysvar rename to Modbus-CAPL/include/SysVars/Modbus.vsysvar