From 3e3a24a2a3a3987717d39bdca5656b8e1cc5c2f6 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Thu, 10 Jul 2014 07:56:55 +0000 Subject: [PATCH] DeviceInformation.cin Improved device structure --- Modbus-CAPL/MakeConfig.cfg | 45 +--- Modbus-CAPL/ModbusNet.cfg | 233 +++++++++--------- Modbus-CAPL/include/CAPL/MakeConfig.can | 64 ++--- .../include/CAPL/PollingModbusClient.can | 42 +++- Modbus-CAPL/include/CAPL/include/Common.cin | 42 ++++ .../CAPL/include/DeviceInformation.cin | 60 +++-- .../include/CAPL/include/ModbusEil.cin | 8 +- .../include/CAPL/include/ModbusStructs.cin | 6 +- .../include/CAPL/include/ModbusTcp.cin | 2 +- .../include/CAPL/include/ModbusUdp.cin | 2 +- .../include/CAPL/include/TcpUdpEilCommon.cin | 2 +- 11 files changed, 279 insertions(+), 227 deletions(-) diff --git a/Modbus-CAPL/MakeConfig.cfg b/Modbus-CAPL/MakeConfig.cfg index 71e6925..975572b 100644 --- a/Modbus-CAPL/MakeConfig.cfg +++ b/Modbus-CAPL/MakeConfig.cfg @@ -1,4 +1,4 @@ -;CANoe Version |4|7|1|35761 MakeConfig +;CANoe Version |4|7|1|52132 MakeConfig Version: 8.2.40 Build 40 32 PRO 5 @@ -348,7 +348,7 @@ VCaplOptionsStreamer 3 Begin_Of_Object End_Of_Object VCaplOptionsStreamer 3 VSVConfigurationStreamer 3 Begin_Of_Object 1 -829 +830 @@ -356,7 +356,7 @@ VSVConfigurationStreamer 3 Begin_Of_Object - + @@ -1261,37 +1261,9 @@ Grafik-Fenster 237 0 0 -1 0 0 0 --11 -0 -0 -0 -0 -0 -0 -0 -400 -0 -Tahoma -0 -1 -0 -0 -0 --11 -0 -0 -0 -34 -0 -0 -0 -400 -0 -Tahoma 0 1 1 @@ -2961,7 +2933,7 @@ End_Of_Object VGrMnBox 3 VDOLocalInfoStruct 3 Begin_Of_Object 3 1 -95 +98 VDAOBus 4 Begin_Of_Object 1 1 @@ -3091,7 +3063,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -580410699 +4212996857 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -3129,7 +3101,7 @@ NULL End_Of_Object VDOLocalInfoStruct 3 0.000000 0 0 -1 1 0 59420 1 233 1 2882400001 98 331 371 619 2882400002 0 0 0 0 0 0 1 2882400001 1270 1270 373 373 2882400002 0 0 0 408326576 0 407053980 3 +1 1 0 59420 1 233 1 2882400001 98 331 371 619 2882400002 0 0 0 0 0 0 1 2882400001 1270 1270 373 373 2882400002 0 0 0 335238400 0 336542644 3 SS_BEGIN_COMMON_INFO 1 0 @@ -3141,7 +3113,7 @@ Ethernet 11 1 1 -408424704 1 0 1 0 0 1 0 0 0 2000 1 +335879144 1 0 1 0 0 1 0 0 0 2000 1 SS_BEGIN_COMMON_INFO 1 3 @@ -3252,7 +3224,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 @@ -3564,6 +3536,7 @@ End FiltersEnd 0 0 + END_OF_WORKSPACE_MEMBER_DATA END_OF_WORKSPACE_MEMBER 1 diff --git a/Modbus-CAPL/ModbusNet.cfg b/Modbus-CAPL/ModbusNet.cfg index 9f0e4e9..334b4da 100644 --- a/Modbus-CAPL/ModbusNet.cfg +++ b/Modbus-CAPL/ModbusNet.cfg @@ -1,4 +1,4 @@ -;CANoe Version |4|7|1|38817 ModbusNet +;CANoe Version |4|7|1|55205 ModbusNet Version: 8.2.40 Build 40 32 PRO 10 @@ -746,9 +746,9 @@ Begin_Of_Multi_Line_String kPersistNoLineBreak ey="{28077F35-C142-4ACC-B040-1BF0AB026C11}" Guid="ac9be154-bd12-4ff9-b255-03e05277dbe2" DockedSize="201, 281" FloatingLocation="111, 442" FloatingSize="1192, 514" HasOptions="False" ImageIndex="-1" Text="Trace" TitleBarText="Trace"> +ock="Bottom" DockOperationType="TopOuter" IsTopMost="True" /> End_Of_Serialized_Data 3 End_Of_Object VDesktop 3 VDesktop 3 Begin_Of_Object @@ -4880,10 +4880,10 @@ MDI_DOCK_INFO_END 0 1 -1 -1 -8 -30 0 0 890 487 6 3 0 0 0 0 0 0 890 483 0 0 1 20372 1904 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 347 323 1 0 0 0 1 641 0 59421 1 END_OF_DOCK_INFO -0 +1 0 1 -0 1 -1 -1 -1 -1 -293 402 601 893 +0 1 -1 -1 -1 -1 240 244 1134 735 0 1 776 389 @@ -4937,7 +4937,7 @@ End_Of_Object VGrMnBox 3 VDOLocalInfoStruct 3 Begin_Of_Object 3 1 -243 +248 VDAOBus 4 Begin_Of_Object 1 1 @@ -5200,7 +5200,7 @@ VBoxRoot 12 Begin_Of_Object 1 3 1 -1 2 3 -1 -1 -8 -30 171 76 688 306 -Debugger - Client_2 +Debugger - Client_100 1 MDI_DOCK_INFO_END @@ -5441,7 +5441,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -1368551005 +498267762 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5576,7 +5576,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -1368551005 +498267762 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5609,7 +5609,7 @@ VBoxRoot 9 Begin_Of_Object 1 3 1 1 1 1 0 166 -8 -30 61 86 1093 577 -Ethernet Packet Builder + 1 MDI_DOCK_INFO_END @@ -5687,11 +5687,105 @@ EOF_MBSSDATA 1 0 1 - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5702,104 +5796,10 @@ EOF_MBSSDATA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + End_Of_Object VSSPlugInConfiguration 6 NULL @@ -5835,7 +5835,7 @@ NULL End_Of_Object VDOLocalInfoStruct 3 0.000000 0 0 -1 1 0 59420 1 176 1 2882400001 464 664 430 885 2882400002 0 0 0 0 0 20 1 2882400001 681 881 432 632 2882400002 0 0 0 0 0 0 3 +1 1 0 59420 1 176 1 2882400001 336 512 272 727 2882400002 0 0 0 0 0 0 1 2882400001 1214 1214 274 274 2882400002 0 0 0 355173464 355403088 354462900 3 SS_BEGIN_COMMON_INFO 1 0 @@ -5847,7 +5847,7 @@ Ether1 11 1 1 -0 1 0 1 0 1 1 0 0 0 2000 1 +421824208 1 0 1 0 1 1 0 0 0 2000 1 SS_BEGIN_COMMON_INFO 1 3 @@ -5958,7 +5958,7 @@ End_Of_Serialized_Data 2 End_Of_Object VWriteBox 2 VWinStore 2 Begin_Of_Object 1 -22 2 3 -1 -1 -1 -1 -10088 -10000 -9070 -9233 +22 2 3 -32088 -32000 -1 -1 -10088 -10000 -9070 -9233 End_Of_Child_List End_Of_Object VWinStore 2 VWinStore 2 Begin_Of_Object @@ -6279,6 +6279,7 @@ End FiltersEnd 1 1 + END_OF_WORKSPACE_MEMBER_DATA END_OF_WORKSPACE_MEMBER 1 diff --git a/Modbus-CAPL/include/CAPL/MakeConfig.can b/Modbus-CAPL/include/CAPL/MakeConfig.can index 557dbf0..679209c 100644 --- a/Modbus-CAPL/include/CAPL/MakeConfig.can +++ b/Modbus-CAPL/include/CAPL/MakeConfig.can @@ -2,7 +2,8 @@ includes { #include "include/DeviceInformation.cin" - #include "include/ModbusUdpClientCommon.cin" + #include "include/ModbusUdp.cin" + #include "include/ModbusClient.cin" } variables @@ -23,22 +24,22 @@ variables dword gScanFirst, gScanLast; // The first and last IP address as dword word ADi, ADn, ADl; // Some variables for "AnalyzeDevices" - byte gMaxTransmissionCount; + byte ggMaxTransmissionCount; } on preStart { - // List of IPs of devices go here - - strncpy(gIps[0], "192.168.1.100", 16); - strncpy(gIps[2], "192.168.1.101", 16); - strncpy(gIps[1], "192.168.100.2", 16); - //strncpy(gIps[3], "192.168.1.8", 16); + byte i = 0; + // 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 it for devices - strncpy(gScanFirstIp, "192.168.1.2", 16); - strncpy(gScanLastIp, "192.168.1.20", 16); + // 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.20", elCount(gScanLastIp)); // Name of the project strncpy(name, "Modbus", elCount(name)); @@ -47,14 +48,14 @@ on preStart strncpy(fnSysvar, "include/SysVars/generated.vsysvar", elCount(fnSysvar)); strncpy(fnDbc, "include/DBC/generated.dbc", elCount(fnDbc)); - OutputDebugLevel = Error; + OutputDebugLevel = Debug;//Error; } on start { - gMaxTransmissionCount = @sysvar::Config::Modbus::MaxTransmissionCount; // save the value - @sysvar::Config::Modbus::MaxTransmissionCount = 1; // and then don't retransmit + ggMaxTransmissionCount = @sysvar::Config::Modbus::MaxTransmissionCount; // save the value + DeviceInit(All); if (gIps.Size() == 0) // if no IP address were specified DetectDevices(); // scan network for devices (Step1) else @@ -88,11 +89,11 @@ void DetectDevices() { write("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 - gScanLast = swapDWord(ipGetAddressAsNumber(gScanLastIp)); // But not here :) + gScanFirst = 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); - ModbusConnectTo(gScanFirst, @sysvar::Config::Modbus::Port); // Open socket and set variables + ModbusInit(gScanFirstIp, @sysvar::Config::Modbus::Port, @sysvar::Config::Modbus::RequestTimeout, 1); // Open socket and set variables ModbusReadBits(0, 1); // Start device detection } // This function will increment the IP address and continue the detection @@ -101,7 +102,7 @@ void DetectDevicesNext() { gScanFirst = swapDWord(gScanFirst); gScanFirst++; - if ((gScanFirst & 0xFF) == 0xFF) // .255 + if ((gScanFirst & 0xFF) == 0xFF) // skip .255 { gScanFirst++; writeLineEx(0, 0, "%d.%d.%d.%d ", gScanFirst >> 24, (gScanFirst >> 16) & 0xFF, (gScanFirst >> 8) & 0xFF, gScanFirst & 0xFF); @@ -109,7 +110,7 @@ void DetectDevicesNext() if (gScanFirst > gScanLast) { - @sysvar::Config::Modbus::MaxTransmissionCount = gMaxTransmissionCount; + @sysvar::Config::Modbus::MaxTransmissionCount = ggMaxTransmissionCount; MakeIpNets(); return; } @@ -147,6 +148,7 @@ void MakeIpNets() if (gIps.Size() == 0) // If no devices were specified and detected { + writeDbg(MbError, "No devices found!"); stop(); // Don't do anything return; } @@ -183,7 +185,7 @@ void AnalyzeDevices() 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); + _ModbusConnectTo(ips[ADi], @sysvar::Config::Modbus::Port); // request something special to get the vendor // since there is no common register that holds the vendor @@ -227,7 +229,7 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep { gIpsSorted[ips[ADi]].Vendor = Wago; // request information - ADn = DeviceGetInformation(Wago); + ADn = _DeviceGetInformation(Wago); return; } @@ -251,11 +253,11 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct gIpsSorted[ips[ADi]].Vendor = BuR; // request further information - ADn = DeviceGetInformation(BuR); + ADn = _DeviceGetInformation(BuR); return; } - DeviceParseRegister(gIpsSorted[ips[ADi]], mbreq.Address, mbres.Data, mbreq.Count); + _DeviceParseRegister(gIpsSorted[ips[ADi]], mbreq.Address, mbres.Data, mbreq.Count); if (--ADn == 0) // If we received all registers AnalyzeDevicesNext(); @@ -359,33 +361,33 @@ void GenSysvars() PutString(" \n"); // InputBits PutString(" \n"); // OutputRegisters PutString(" \n"); // OutputBits PutString(" \n"); PutString(" \n"); diff --git a/Modbus-CAPL/include/CAPL/PollingModbusClient.can b/Modbus-CAPL/include/CAPL/PollingModbusClient.can index 0e822e7..be43cd1 100644 --- a/Modbus-CAPL/include/CAPL/PollingModbusClient.can +++ b/Modbus-CAPL/include/CAPL/PollingModbusClient.can @@ -34,13 +34,22 @@ on start 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 - ModbusReadOutBits(thisDev.Address.Read.OutputBit, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits); // Read the start status of the output bits - ModbusReadOutRegisters(thisDev.Address.Read.OutputReg, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters); // Read the start status of the output registers + 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 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); } +// Stop all transactions and close connection +on preStop +{ + ModbusEnd(); +} + // Modbus events ---------------------------------------------------------------------- /// All these events will be called by functions out of ModbusClientCommon.cin @@ -119,7 +128,7 @@ void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[] case ReadBitsOut: // Read output bits sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits"); - offset = mbreq.Address - thisDev.Address.Read.OutputBit; // Get the offset to the base output bit address + 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]; @@ -130,7 +139,7 @@ void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[] case ReadBitsIn: // Read input bits sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); - offset = mbreq.Address - thisDev.Address.Read.InputBit; // Get the offset to the base input bit address + 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]; @@ -149,7 +158,7 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct case ReadRegistersOut: // Read output registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); - offset = mbreq.Address - thisDev.Address.Read.OutputReg; // Get the offset to the base output register address + 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]; @@ -160,7 +169,7 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct case ReadRegistersIn: // Read input registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); - offset = mbreq.Address - thisDev.Address.Read.InputReg; // Get the offset to the base input bit address + 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]; @@ -185,15 +194,30 @@ void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbres){} // It will pass as argument what happened. Please see the log (increase debug level in preStart) for more details. void OnModbusClientPanics(enum FatalErrors reason) { - writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason); switch(reason) { case ParsingBuffer: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Error while parsing the received buffer", reason); + runError(1001, reason); + break; case ModbusPackageWasSplit: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Error while parsing the received buffer: The Modbus package was split", reason); + runError(1001, reason); + break; case VendorIdUnknown: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Error: Vendor ID unknown", reason); + runError(1001, reason); + break; + case FuncCodeIncorrect: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Error: Function code is incorrect", reason); + runError(1001, reason); + break; + case AddressFailure: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Error: Start address is incorrect", reason); runError(1001, reason); break; case ConnectionError: + writeLineEx(0, 4, "<%NODE_NAME%> Fatal Connection Error", reason); gtRead.Cancel(); break; } @@ -203,8 +227,8 @@ void OnModbusClientPanics(enum FatalErrors reason) // The timer will continuously poll the input registers and intput bits on timer gtRead { - ModbusReadRegisters(thisDev.Address.Read.InputReg, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters); - ModbusReadBits(thisDev.Address.Read.InputBit, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits); + 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); } // If Data::OutputBits is changed we will send this update to the device diff --git a/Modbus-CAPL/include/CAPL/include/Common.cin b/Modbus-CAPL/include/CAPL/include/Common.cin index 15e6e8f..667050e 100644 --- a/Modbus-CAPL/include/CAPL/include/Common.cin +++ b/Modbus-CAPL/include/CAPL/include/Common.cin @@ -90,6 +90,34 @@ void writeDbg(enum DebugLvl lvl, char format[], char string1[], char string2[]) } // This method prints the specified arguments to CAPL/Write Window if the debug level is high enough /// +void writeDbg(enum DebugLvl lvl, char format[], char string1[], char string2[], long num1, long num2) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(1, lVl, msg, string1, string2, num1, num2); +} +// This method prints the specified arguments to CAPL/Write Window if the debug level is high enough +/// +void writeDbg(enum DebugLvl lvl, char format[], char string1[], char string2[], long num1) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(1, lVl, msg, string1, string2, num1); +} +// This method prints the specified arguments to CAPL/Write Window if the debug level is high enough +/// void writeDbg(enum DebugLvl lvl, char format[], long num, char string[]) { char msg[500]; @@ -118,6 +146,20 @@ void writeDbg(enum DebugLvl lvl, char format[], char string[], long num) } // This method prints the specified arguments to CAPL/Write Window if the debug level is high enough /// +void writeDbg(enum DebugLvl lvl, char format[], char string[], long num, float fl) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(1, lVl, msg, string, num, fl); +} +// This method prints the specified arguments to CAPL/Write Window if the debug level is high enough +/// void writeDbg(enum DebugLvl lvl, char format[], long num1) { char msg[500]; diff --git a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin index c48c13b..b4dcb8a 100644 --- a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin +++ b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin @@ -20,24 +20,25 @@ variables { struct // Start addresses Read { - word OutputBit; - word OutputReg; - word InputBit; - word InputReg; + word OutputBits; + word OutputRegisters; + word InputBits; + word InputRegisters; } Read; struct // Start addresses Write { - word OutputBit; - word OutputReg; + word OutputBits; + word OutputRegisters; } Write; - } Address; - word BitMaxCount; // Max number of bits - word RegMaxCount; // Max number of registers + } Addr; + word MaxBitCount; // Max number of bits + word MaxRegisterCount; // Max number of registers byte ReceiveWindow; } thisDev; enum Vendor // The Vendor enum. All Vendors have to listed here and all listed vendors have to be implemented in this file { + All = 0xFFFF, Wago = 23, // Wago BuR = 2 // B&R }; @@ -68,27 +69,32 @@ void DeviceInit(byte vendor) { switch ((enum Vendor) vendor) { + case All: // information that may apply to all devices + thisDev.MaxBitCount = 0x0100; + thisDev.MaxRegisterCount = 0x0100; + thisDev.ReceiveWindow = 1; + break; case Wago: - thisDev.Address.Read.InputBit = 0x0000; // Wago inputs start at 0x000 - thisDev.Address.Read.InputReg = 0x0000; - thisDev.Address.Read.OutputBit = 0x0200; // Wago reading outputs start at 0x200 - thisDev.Address.Read.OutputReg = 0x0200; - thisDev.Address.Write.OutputBit = 0x0000; // Wago writing outputs start at 0x000 - thisDev.Address.Write.OutputReg = 0x0000; - thisDev.BitMaxCount = 0x0100; // Wago allows up to 256 inputs - thisDev.RegMaxCount = 0x0100; - thisDev.ReceiveWindow = 5; // Wago can handle 5 requests simultaneously + thisDev.Addr.Read.InputBits = 0x0000; // Wago inputs start at 0x000 + thisDev.Addr.Read.InputRegisters = 0x0000; + thisDev.Addr.Read.OutputBits = 0x0200; // Wago reading outputs start at 0x200 + thisDev.Addr.Read.OutputRegisters = 0x0200; + thisDev.Addr.Write.OutputBits = 0x0000; // Wago writing outputs start at 0x000 + thisDev.Addr.Write.OutputRegisters = 0x0000; + thisDev.MaxBitCount = 0x0200; // Wago allows up to 512 digital inputs (trial & error) + thisDev.MaxRegisterCount = 0x0100; // Wago allows up to 256 analog inputs (trial & error) + thisDev.ReceiveWindow = 5; // Wago can handle 5 requests simultaneously break; case BuR: - thisDev.Address.Read.InputBit = 0x0000; // B&R inputs start at 0x000 - thisDev.Address.Read.InputReg = 0x0000; - thisDev.Address.Read.OutputBit = 0x0000; // B&R reading digital outputs start at 0x000 - thisDev.Address.Read.OutputReg = 0x0800; // B&R reading analog outputs start at 0x800 - thisDev.Address.Write.OutputBit = 0x0000; // B&R writing outputs start at 0x000 - thisDev.Address.Write.OutputReg = 0x0000; - thisDev.BitMaxCount = 0x4000; // B&R allows up to 16348 digital inputs - thisDev.RegMaxCount = 0x0800; // B&R allows up to 2048 analog inputs - thisDev.ReceiveWindow = 1; // B&R can only handle 1 request at a time + thisDev.Addr.Read.InputBits = 0x0000; // B&R inputs start at 0x000 + thisDev.Addr.Read.InputRegisters = 0x0000; + thisDev.Addr.Read.OutputBits = 0x0000; // B&R reading digital outputs start at 0x000 + thisDev.Addr.Read.OutputRegisters = 0x0800; // B&R reading analog outputs start at 0x800 + thisDev.Addr.Write.OutputBits = 0x0000; // B&R writing outputs start at 0x000 + thisDev.Addr.Write.OutputRegisters = 0x0000; + thisDev.MaxBitCount = 0x4000; // B&R allows up to 16348 digital inputs + thisDev.MaxRegisterCount = 0x0800; // B&R allows up to 2048 analog inputs + thisDev.ReceiveWindow = 1; // B&R can only handle 1 request at a time break; default: OnModbusClientPanics(VendorIdUnknown); diff --git a/Modbus-CAPL/include/CAPL/include/ModbusEil.cin b/Modbus-CAPL/include/CAPL/include/ModbusEil.cin index e96a521..a551bdb 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusEil.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusEil.cin @@ -75,6 +75,8 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) return error; } + gSocketState = CONNECTING; + EthSetTokenData(gPacket, "eth", "source" , elCount(gLocalMac), gLocalMac); EthSetTokenData(gPacket, "eth", "destination" , elCount(broadcastMac), broadcastMac); EthSetTokenInt(gPacket, "arp", "hwType" , 1); // Ethernet @@ -148,18 +150,18 @@ byte _ModbusSnd(byte buffer[], word length) _ModbusConnectTo(gRemoteIP, gRemotePort); if (gSocketState != OK) { - writeDbg(ConnWarning, "EilSnd: Reconnecting failed! Doing nothing."); + writeDbg(ConnWarning, "_ModbusSnd: Reconnecting failed!"); return 1; } case OK: break; default: - writeDbg(ConnWarning, "EilSnd: Socket status is not OK! Doing nothing."); + writeDbg(ConnWarning, "_ModbusSnd: Socket status is not OK!); return 1; } bin_to_strhex(buffer, str); - writeDbg(ConnDebug, "EilSnd: %s (Länge: %d)", str, length); + writeDbg(ConnDebug, "_ModbusSnd: %s (Länge: %d)", str, length); EthResizeToken(gPacket, "udp", "data" , length*8); EthSetTokenData(gPacket, "udp", "data" , length, buffer); diff --git a/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin b/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin index 21a379c..2e742e5 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin @@ -28,7 +28,7 @@ variables word Protocol; word Length; byte UnitID; - byte FuncCode; + /*enum ModbusFuncCode*/ byte FuncCode; }; // Read Data from the host. We only need the start address and the number of bits/registers we want to read _align(1) struct ModbusReqRead @@ -147,6 +147,8 @@ variables ModbusPackageWasSplit, DeviceCodeUnknown, VendorIdUnknown, - ConnectionError + ConnectionError, + FuncCodeIncorrect, + AddressFailure }; } \ No newline at end of file diff --git a/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin b/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin index 31ddf03..42420a8 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin @@ -101,7 +101,7 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) else { writeDbg(ConnDebug, "_ModbusConnectTo: WSAE would block"); - gSocketState = NULL; + gSocketState = CONNECTING; } return 0; } diff --git a/Modbus-CAPL/include/CAPL/include/ModbusUdp.cin b/Modbus-CAPL/include/CAPL/include/ModbusUdp.cin index db40863..123d434 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusUdp.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusUdp.cin @@ -150,7 +150,7 @@ byte _ModbusSnd(byte buffer[], word length) } bin_to_strhex(buffer, str); - writeDbg(ConnDebug, "ModbusSnd: %s (Länge: %d)", str, length); + writeDbg(ConnDebug, "ModbusSnd: %s (Länge: %d, Time: %f)", str, length, timeNowFloat()/100000.0); if (gSocket.SendTo(gRemoteIP, gRemotePort, buffer, length) != 0) { diff --git a/Modbus-CAPL/include/CAPL/include/TcpUdpEilCommon.cin b/Modbus-CAPL/include/CAPL/include/TcpUdpEilCommon.cin index 75aabb1..da8e614 100644 --- a/Modbus-CAPL/include/CAPL/include/TcpUdpEilCommon.cin +++ b/Modbus-CAPL/include/CAPL/include/TcpUdpEilCommon.cin @@ -11,7 +11,7 @@ variables char gIpLastErrStr[512] = ""; // The state of the socket will be safed here. This way we can check if we can send/receive packets - enum SocketState { NULL, OK, ERROR, CLOSED }; + enum SocketState { NULL = 100, CONNECTING = 120, OK = 200, ERROR = 0, CLOSED = 20}; enum SocketState gSocketState = NULL; dword gRemoteIP = INVALID_IP;