From 57ea11238f1b45169ba281305035a682a0351a42 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Thu, 12 Jun 2014 15:28:05 +0000 Subject: [PATCH] Comments in MakeConfig.can --- Modbus-CAPL/include/CAPL/MakeConfig.can | 450 +++++++++++++----------- 1 file changed, 236 insertions(+), 214 deletions(-) diff --git a/Modbus-CAPL/include/CAPL/MakeConfig.can b/Modbus-CAPL/include/CAPL/MakeConfig.can index f2c2d2d..4799dc6 100644 --- a/Modbus-CAPL/include/CAPL/MakeConfig.can +++ b/Modbus-CAPL/include/CAPL/MakeConfig.can @@ -7,32 +7,32 @@ includes variables { - struct device + struct device // A structure that contains information about an Modbus device { - char Ip[16]; - char IpLsb[4]; - char IpNet[4]; - enum Vendor Vendor; - word SerialCode; - word DeviceCode; - struct deviceIOs DeviceIOs; + 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 + enum Vendor Vendor; // The Vendor (Wago / B&R) + word SerialCode; // Serial Code + word DeviceCode; // Device Code + struct deviceIOs DeviceIOs; // A structure with more information about IOs }; - char[16] gIps[long]; - char gScanFirstIp[16]; - char gScanLastIp[16]; + char[16] gIps[long]; // List 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 fnSysvar[40]; // Filename of Sysvars - char fnDbc[40]; // Filename of DBC - char name[20]; // Name of project - dword ips[50]; // detected IPs + 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 - file f; - byte gIpNets[long]; - struct device gIpsSorted[long]; - dword gScanFirst, gScanLast; - word ADi, ADn, ADl; + 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" byte gMaxTransmissionCount; } @@ -47,43 +47,45 @@ on preStart */ // Scan a range of IPs for devices. Start and Stop go here - // Please note: Currelty .255 will be skipped! + // Please note: Currently .255 will be skipped! Don't use it for devices and as stop address strncpy(gScanFirstIp, "192.168.1.2", 16); strncpy(gScanLastIp, "192.168.1.10", 16); // Name of the project strncpy(name, "Modbus", elCount(name)); - // Paths to the generated files relative to .cfg + + // 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)); - + OutputDebugLevel = Error; } on start { - gMaxTransmissionCount = @sysvar::Config::Modbus::MaxTransmissionCount; + gMaxTransmissionCount = @sysvar::Config::Modbus::MaxTransmissionCount; // save the value + @sysvar::Config::Modbus::MaxTransmissionCount = 1; // and then don't retransmit - if (gIps.Size() == 0) - DetectDevices(); + if (gIps.Size() == 0) // if no IP address were specified + DetectDevices(); // scan network for devices (Step1) else - MakeIpNets(); + MakeIpNets(); // else continue with Step2 } /// -void PutString(file f, char str[]) +void PutString(char str[]) { f.PutString(str, strlen(str)); } /// -void PutString(file f, word d) +void PutString(word d) { char str[6]; ltoa(d, str, 10); f.PutString(str, strlen(str)); } /// -void PutString(file f, byte d) +void PutString(byte d) { char str[4]; ltoa(d, str, 10); @@ -91,94 +93,106 @@ void PutString(file f, byte d) } // Step 1: Detect active devices and collect IP addresses +// This function will convert the IP address, open the socket and start the detection. The rest will be done by events /// void DetectDevices() { - @sysvar::Config::Modbus::MaxTransmissionCount = 1; write("Scanning from %s to %s with timeout of %d ms", gScanFirstIp, gScanLastIp, @sysvar::Config::Modbus::RequestTimeout); + gScanFirst = ipGetAddressAsNumber(gScanFirstIp); gScanLast = ipGetAddressAsNumber(gScanLastIp); + write("%d.%d.%d.%d ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24); - ModbusConnectTo(gScanFirst, @sysvar::Config::Modbus::Port); - ModbusReadBits(0, 1); + ModbusConnectTo(gScanFirst, @sysvar::Config::Modbus::Port); // Open socket and set variables + ModbusReadBits(0, 1); // Start device detection } +// This function will increment the IP address and continue the detection /// void DetectDevicesNext() { // next IP + // Note: IP address is stored as big endian, comments are notated as little endian :) // 0xFE...... --> Skip xxx.xxx.xxx.255 which is broadcast address in 192.168.xxx.0 nets + + // If first three bytes are full (123.255.255.255), set those to 0 and increment the first byte (124.0.0.0) if ((gScanFirst & 0xFFFFFF00) == 0xFEFFFF00) { gScanFirst &= 0x000000FF; gScanFirst += 0x00000001; write("%d.%d.%d.%d ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24); } + // If first two bytes are full (124.111.255.255), set those to 0 and increment the second byte (124.112.0.0) else if ((gScanFirst & 0xFFFF0000) == 0xFEFF0000) { gScanFirst &= 0x0000FFF; gScanFirst += 0x00000100; write("%d.%d.%d.%d ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24); } + // If first last byte is full (124.112.222.255), set it to 0 and increment the third byte (124.112.223.0) else if ((gScanFirst & 0xFF000000) == 0xFE000000) { gScanFirst &= 0x00FFFFFF; gScanFirst += 0x00010000; - write("%d.%d.%d.%d ", gScanFirst & 0xFF, (gScanFirst >> 8) & 0xFF, (gScanFirst >> 16) & 0xFF, gScanFirst >> 24); } + // Else simply increment the LSB else { gScanFirst += 0x01000000; } - if (gScanFirst == gScanLast) + + if (gScanFirst == gScanLast) // If this is the last address we stop the detection { @sysvar::Config::Modbus::MaxTransmissionCount = gMaxTransmissionCount; MakeIpNets(); return; } - writeEx(1, 1, "."); - gRemoteIP = gScanFirst; // Don't open new socket, it takes too much time. - ModbusReadBits(0, 1); + + writeEx(1, 1, "."); // 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! + ModbusReadBits(0, 1); // Scan the next device } /// void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap) { - DetectDevicesNext(); + DetectDevicesNext(); // Timeout! We will go to the next device } /// void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq) { - ipGetAddressAsString(gScanFirst, gIps[gScanFirst], 16); - DetectDevicesNext(); + ipGetAddressAsString(gScanFirst, gIps[gScanFirst], 16); // store the detected device's IP address + DetectDevicesNext(); // and continue } -// Step 2: Sort into subnets + +// Step 2: Sort into subnets and create structure // Sort the IPs from gIps to gIpsSorted and add their subnet to gIpNets /// void MakeIpNets() { long ipNum; - if (gIps.Size() == 0) + if (gIps.Size() == 0) // If no devices were specified and detected { - stop(); + stop(); // Don't do anything return; } - for (long i : gIps) + for (long i : gIps) // Go through all devices { ipNum = ipGetAddressAsNumber(gIps[i]); // convert IP to dword - gIpNets[(ipNum >> 16) & 0xFF] = 1; // add subnet - ips[gIpsSorted.size()] = ipNum; // add ip to array - strncpy(gIpsSorted[ipNum].IP, gIps[i], 16); // copy to new array - ltoa((ipNum >> 16) & 0xFF, gIpsSorted[ipNum].IpNet, 10); // add .IpNet - ltoa((ipNum >> 24) & 0xFF, gIpsSorted[ipNum].IpLsb, 10); // add .IpLsb + 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 gIps.Remove(i); } - AnalyzeDevices(); + AnalyzeDevices(); // Continue with step 3 } @@ -186,21 +200,26 @@ void MakeIpNets() /// void AnalyzeDevices() { - ADn = 0; - ADi = 0; + // Init counters + ADn = 0; // Zero message received + ADi = 0; // First IP address ADl = gIpsSorted.Size(); + write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip); gIpsSorted[ips[ADi]].Vendor = Wago; - if (gRemoteIP != INVALID_IP) - gRemoteIP = ips[ADi]; - else + + if (gRemoteIP != INVALID_IP) // If we already do have a socket + gRemoteIP = ips[ADi]; // use it + else // else create a new one ModbusConnectTo(ips[ADi], @sysvar::Config::Modbus::Port); - ModbusReadRegisters(0x2011, 1); - ModbusReadRegisters(0x2012, 1); - ModbusReadRegisters(0x2030, 65); - ModbusReadRegisters(0x2031, 64); - ModbusReadRegisters(0x2032, 64); - ModbusReadRegisters(0x2033, 63); + + // read the important registers from the device + ModbusReadRegisters(0x2011, 1); // Serial Code + ModbusReadRegisters(0x2012, 1); // Device Code + ModbusReadRegisters(0x2030, 65); // Connected IO 1 + ModbusReadRegisters(0x2031, 64); // Connected IO 2 + ModbusReadRegisters(0x2032, 64); // Connected IO 3 + ModbusReadRegisters(0x2033, 63); // Connected IO 4 } /// @@ -208,19 +227,19 @@ void AnalyzeDevicesNext() { if (++ADi >= ADl) // we have analyzed all devices { - MakeFiles(); + MakeFiles(); // go to Step4 return; } - ADn = 0; - gRemoteIP = ips[ADi]; + ADn = 0; // Zero message received + gRemoteIP = ips[ADi]; // Next IP address write("Analyzing %s...", gIpsSorted[ips[ADi]].Ip); - ModbusReadRegisters(0x2011, 1); - ModbusReadRegisters(0x2012, 1); - ModbusReadRegisters(0x2030, 65); - ModbusReadRegisters(0x2031, 64); - ModbusReadRegisters(0x2032, 64); - ModbusReadRegisters(0x2033, 63); + ModbusReadRegisters(0x2011, 1); // Serial Code + ModbusReadRegisters(0x2012, 1); // Device Code + ModbusReadRegisters(0x2030, 65); // Connected IO 1 + ModbusReadRegisters(0x2031, 64); // Connected IO 2 + ModbusReadRegisters(0x2032, 64); // Connected IO 3 + ModbusReadRegisters(0x2033, 63); // Connected IO 4 } /// @@ -230,19 +249,19 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep { case FinalTimeout: writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP); - gQueueAck.Clear(); + gQueueAck.Clear(); // Clear all queues gQueuePending.Clear(); gQueueSent.Clear(); - gIpsSorted.Remove(ips[ADi]); - AnalyzeDevicesNext(); + gIpsSorted.Remove(ips[ADi]); // Remove the IP + AnalyzeDevicesNext(); // And go to the next device break; case Exception: writeLineEx(0, 3, "Error while analyzing %s! The device respond with exception code %d! Ignoring...", gIpsSorted[ips[ADi]].IP, ex); - gQueueAck.Clear(); + gQueueAck.Clear(); // Clear all queues gQueuePending.Clear(); gQueueSent.Clear(); - gIpsSorted.Remove(ips[ADi]); - AnalyzeDevicesNext(); + gIpsSorted.Remove(ips[ADi]); // Remove the IP + AnalyzeDevicesNext(); // And go to the next device break; } } @@ -252,6 +271,7 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct { byte i; + // Parse the received data switch (mbreq.Address) { case 0x2011: @@ -266,14 +286,14 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct case 0x2033: for (i = 0; i < mbreq.Count; i++) { - if (mbres.Data[i] == 0x0000) + if (mbres.Data[i] == 0x0000) // No more devices --> end break; ParseDeviceCode(mbres.Data[i], gIpsSorted[ips[ADi]].Vendor, gIpsSorted[ips[ADi]].DeviceIOs); } break; } - if (++ADn == 6) + if (++ADn == 6) // If we received all registers (6 messages) AnalyzeDevicesNext(); } @@ -293,36 +313,36 @@ void GenSysvars() write("GenSysvars() -> %s", fnSysvar); f.Open(fnSysvar, 0, 0); // rewrite file in ASCII - PutString(f, "\n"); - PutString(f, "\n"); - PutString(f, " \n"); + PutString("\n"); + PutString("\n"); + PutString(" \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); for (long net : gIpNets) { byte nett; nett = net; - PutString(f, " \n"); + PutString(" \n"); for (long ipN : gIpsSorted) { @@ -330,93 +350,93 @@ void GenSysvars() if (((ipN >> 16) & 0xFF) != net) continue; - PutString(f, " \n"); + PutString(" \n"); // Namespace Config - PutString(f, " \n"); + PutString(" \n"); // IP - PutString(f, " \n"); + PutString(" \n"); // Intveral - PutString(f, " \n"); - PutString(f, " \n"); + PutString(" \n"); + PutString(" \n"); //Namespace Info - PutString(f, " \n"); + PutString(" \n"); // Vendor - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); - PutString(f, " \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); + PutString(" \n"); // SerialCode - PutString(f, " \n"); + PutString(" \n"); // DeviceCode - PutString(f, " \n"); + PutString(" \n"); // Modules gIpsSorted[ipN].DeviceIOs.Modules[strlen(gIpsSorted[ipN].DeviceIOs.Modules)-1] = 0; - PutString(f, " \n"); + PutString(" \n"); // InputRegisters - PutString(f, " \n"); + PutString(" \n"); // InputBits - PutString(f, " \n"); + PutString(" \n"); // OutputRegisters - PutString(f, " \n"); + PutString(" \n"); // OutputBits - PutString(f, " \n"); - PutString(f, " \n"); + PutString(" \n"); + PutString(" \n"); // Namespace Data - PutString(f, " \n"); + PutString(" \n"); // InputRegisters - PutString(f, " \n"); + PutString(" \n"); // InputBits - PutString(f, " \n"); + PutString(" \n"); // OutputRegisters - PutString(f, " \n"); + PutString(" \n"); // OutputBits - PutString(f, " \n"); + PutString(" \n"); - PutString(f, " \n"); - PutString(f, " \n"); + PutString(" \n"); + PutString(" \n"); } - PutString(f, " \n"); + PutString(" \n"); } - PutString(f, " \n"); - PutString(f, "\n"); + PutString(" \n"); + PutString("\n"); f.Close(); } @@ -428,58 +448,58 @@ void GenDbc() write("GenDbc() -> %s", fnDbc); f.Open(fnDbc, 0, 0); // rewrite file in ASCII - PutString(f, "VERSION \"\"\n\n\n"); - PutString(f, "NS_ :\n"); - PutString(f, " NS_DESC_\n"); - PutString(f, " CM_\n"); - PutString(f, " BA_DEF_\n"); - PutString(f, " BA_\n"); - PutString(f, " VAL_\n"); - PutString(f, " CAT_DEF_\n"); - PutString(f, " CAT_\n"); - PutString(f, " FILTER\n"); - PutString(f, " BA_DEF_DEF_\n"); - PutString(f, " EV_DATA_\n"); - PutString(f, " ENVVAR_DATA_\n"); - PutString(f, " SGTYPE_\n"); - PutString(f, " SGTYPE_VAL_\n"); - PutString(f, " BA_DEF_SGTYPE_\n"); - PutString(f, " BA_SGTYPE_\n"); - PutString(f, " SIG_TYPE_REF_\n"); - PutString(f, " VAL_TABLE_\n"); - PutString(f, " SIG_GROUP_\n"); - PutString(f, " SIG_VALTYPE_\n"); - PutString(f, " SIGTYPE_VALTYPE_\n"); - PutString(f, " BO_TX_BU_\n"); - PutString(f, " BA_DEF_REL_\n"); - PutString(f, " BA_REL_\n"); - PutString(f, " BA_DEF_DEF_REL_\n"); - PutString(f, " BU_SG_REL_\n"); - PutString(f, " BU_EV_REL_\n"); - PutString(f, " BU_BO_REL_\n"); - PutString(f, " SG_MUL_VAL_\n"); - PutString(f, "\n"); - PutString(f, "BS_:\n"); - PutString(f, "\nBU_:"); + PutString("VERSION \"\"\n\n\n"); + PutString("NS_ :\n"); + PutString(" NS_DESC_\n"); + PutString(" CM_\n"); + PutString(" BA_DEF_\n"); + PutString(" BA_\n"); + PutString(" VAL_\n"); + PutString(" CAT_DEF_\n"); + PutString(" CAT_\n"); + PutString(" FILTER\n"); + PutString(" BA_DEF_DEF_\n"); + PutString(" EV_DATA_\n"); + PutString(" ENVVAR_DATA_\n"); + PutString(" SGTYPE_\n"); + PutString(" SGTYPE_VAL_\n"); + PutString(" BA_DEF_SGTYPE_\n"); + PutString(" BA_SGTYPE_\n"); + PutString(" SIG_TYPE_REF_\n"); + PutString(" VAL_TABLE_\n"); + PutString(" SIG_GROUP_\n"); + PutString(" SIG_VALTYPE_\n"); + PutString(" SIGTYPE_VALTYPE_\n"); + PutString(" BO_TX_BU_\n"); + PutString(" BA_DEF_REL_\n"); + PutString(" BA_REL_\n"); + PutString(" BA_DEF_DEF_REL_\n"); + PutString(" BU_SG_REL_\n"); + PutString(" BU_EV_REL_\n"); + PutString(" BU_BO_REL_\n"); + PutString(" SG_MUL_VAL_\n"); + PutString("\n"); + PutString("BS_:\n"); + PutString("\nBU_:"); for (long ipN : gIpsSorted) { - PutString(f, " Client_"); - //PutString(f, gIpsSorted[ipN].IpNet); - //PutString(f, "_"); - PutString(f, gIpsSorted[ipN].IpLsb); + PutString(" Client_"); + //PutString(gIpsSorted[ipN].IpNet); + //PutString("_"); + PutString(gIpsSorted[ipN].IpLsb); } - PutString(f, "\n\n\n\n"); - PutString(f, "BA_DEF_ BU_ \"NodeLayerModules\" STRING ;\n"); - PutString(f, "BA_DEF_ \"DBName\" STRING ;\n"); - PutString(f, "BA_DEF_ \"BusType\" STRING ;\n"); - PutString(f, "BA_DEF_DEF_ \"NodeLayerModules\" \"Ethernet_IL.DLL\";\n"); - PutString(f, "BA_DEF_DEF_ \"DBName\" \"\";\n"); - PutString(f, "BA_DEF_DEF_ \"BusType\" \"Ethernet\";\n"); - PutString(f, "BA_ \"BusType\" \"Ethernet\";\n"); - PutString(f, "BA_ \"DBName\" \""); - PutString(f, name); - PutString(f, "\";\n"); + PutString("\n\n\n\n"); + PutString("BA_DEF_ BU_ \"NodeLayerModules\" STRING ;\n"); + PutString("BA_DEF_ \"DBName\" STRING ;\n"); + PutString("BA_DEF_ \"BusType\" STRING ;\n"); + PutString("BA_DEF_DEF_ \"NodeLayerModules\" \"Ethernet_IL.DLL\";\n"); + 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"); f.Close(); } @@ -491,11 +511,12 @@ void GenDbc() +// The stuff below is not needed /// void OnModbusClientPanics(enum FatalErrors reason) { writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason); - switch(reason) +/* switch(reason) { case ParsingBuffer: case ModbusPackageWasSplit: @@ -504,6 +525,7 @@ void OnModbusClientPanics(enum FatalErrors reason) case ConnectionError: break; } +*/ } /// void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){}