diff --git a/Modbus-CAPL/ModbusNet.cfg b/Modbus-CAPL/ModbusNet.cfg index a266e26..9f0e4e9 100644 --- a/Modbus-CAPL/ModbusNet.cfg +++ b/Modbus-CAPL/ModbusNet.cfg @@ -1,4 +1,4 @@ -;CANoe Version |4|7|1|55221 ModbusNet +;CANoe Version |4|7|1|38817 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"> +eInfo RootDock="Right" /> End_Of_Serialized_Data 3 End_Of_Object VDesktop 3 VDesktop 3 Begin_Of_Object @@ -1380,7 +1380,7 @@ End_Of_Serialized_Data 15 End_Of_Object VSysVarObject 15 [MeasurementObject] Client_2::InputBits_[0] -"" 223 b86b8 0. 1. -100. 100. 1 0 0 0 36000000 1 1 0 0 +"" 1 b86b8 0. 1. -100. 100. 0.1 0 0 0 36000000 1 1 0 0 VSysVarObject 15 Begin_Of_Object 1 VHostSignal 16 Begin_Of_Object @@ -1414,7 +1414,7 @@ End_Of_Serialized_Data 15 End_Of_Object VSysVarObject 15 [MeasurementObject] Client_2::InputBits_[1] -"" 223 d7ff -1. 1. -100. 100. 1 0 0 0 36000000 1 1 0 0 +"" 1 d7ff -1. 1. -100. 100. 0.2 0 0 0 36000000 1 1 0 0 VSysVarObject 15 Begin_Of_Object 1 VHostSignal 16 Begin_Of_Object @@ -1448,7 +1448,7 @@ End_Of_Serialized_Data 15 End_Of_Object VSysVarObject 15 [MeasurementObject] Client_3::InputBits_[5] -"" 223 9314ff 0. 1. -100. 100. 1 0 0 0 36000000 1 1 0 0 +"" 1 9314ff 0. 1. -100. 100. 0.1 0 0 0 36000000 1 1 0 0 VSysVarObject 15 Begin_Of_Object 1 VHostSignal 16 Begin_Of_Object @@ -1482,7 +1482,7 @@ End_Of_Serialized_Data 15 End_Of_Object VSysVarObject 15 [MeasurementObject] Client_2::InputRegisters_[0] -"" 223 ff00 2741. 6073. -100. 100. 500 0 0 0 36000000 1 1 0 0 +"" 1 ff00 2741. 6073. -100. 100. 500 0 0 0 36000000 1 1 0 0 VSysVarObject 15 Begin_Of_Object 1 VHostSignal 16 Begin_Of_Object @@ -1516,9 +1516,9 @@ End_Of_Serialized_Data 15 End_Of_Object VSysVarObject 15 [MeasurementObject] Client_3::InputRegisters_[3] -"" 223 228b22 8971. 19903. -100. 100. 1000 0 0 0 36000000 1 1 0 0 +"" 1 228b22 8971. 19903. -100. 100. 1000 0 0 0 36000000 1 1 0 0 [GraphWindow:x_x_x_x_x_x_WindowBk_Grid_AxisBk_XAxisFr_YAxisFr_x_x_x_x_x_x] -721742.55151999998 1037422.41889 423751.50296999997 200000 36000000 1 ffffff b2b2b2 ffffff 0 0 0 0 1 1 1 0 +0 315679.86736999999 315679.86736999999 200000 36000000 1 ffffff b2b2b2 ffffff 0 0 0 0 1 1 1 0 0 30 5000 0 0 100 @@ -1797,7 +1797,7 @@ End_Of_Serialized_Data 14 6 1 14 -ver=2: FT TF TF FT FT FT;F T Config;F T Ethernet1;F T GLLogger;T F _Statistics +ver=2: FT TF TF FT FT FT;F T Config;F T Ethernet1;F T Ethernet100;F T GLLogger;T F _Statistics End_Of_Serialized_Data 14 7 0 @@ -1823,7 +1823,10 @@ End_Of_Serialized_Data 14 16 0 17 -0 +1 +14 +ver=2: FT +End_Of_Serialized_Data 14 18 0 19 @@ -4120,7 +4123,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::DeviceCode +DeviceCode 0 End_Of_Object VHostSignal 15 14 @@ -4156,7 +4159,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::SerialCode +SerialCode 0 End_Of_Object VHostSignal 15 14 @@ -4192,7 +4195,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::InputBits +InputBits 0 End_Of_Object VHostSignal 15 14 @@ -4228,7 +4231,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::InputRegisters +InputRegisters 0 End_Of_Object VHostSignal 15 14 @@ -4264,7 +4267,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::OutputBits +OutputBits 0 End_Of_Object VHostSignal 15 14 @@ -4300,7 +4303,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::OutputRegisters +OutputRegisters 0 End_Of_Object VHostSignal 15 14 @@ -4336,7 +4339,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Info::Modules +Modules 0 End_Of_Object VHostSignal 15 14 @@ -4372,7 +4375,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Data::OutputBits +OutputBits 0 End_Of_Object VHostSignal 15 14 @@ -4408,7 +4411,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Data::InputBits +InputBits 0 End_Of_Object VHostSignal 15 14 @@ -4588,7 +4591,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Config::Interval +Interval 0 End_Of_Object VHostSignal 15 14 @@ -4624,7 +4627,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_2::Data::InputRegisters [0] +InputRegisters 0 End_Of_Object VHostSignal 15 14 @@ -4660,7 +4663,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_3::Data::InputBits +InputBits 0 End_Of_Object VHostSignal 15 14 @@ -4696,7 +4699,7 @@ VSysVarObject 14 Begin_Of_Object VHostSignal 15 Begin_Of_Object 2 3 -Ethernet1::Client_3::Data::InputRegisters +InputRegisters 0 End_Of_Object VHostSignal 15 14 @@ -4880,7 +4883,7 @@ END_OF_DOCK_INFO 0 0 1 -0 1 -1 -1 -1 -1 -205 402 689 893 +0 1 -1 -1 -1 -1 -293 402 601 893 0 1 776 389 @@ -4934,7 +4937,7 @@ End_Of_Object VGrMnBox 3 VDOLocalInfoStruct 3 Begin_Of_Object 3 1 -238 +243 VDAOBus 4 Begin_Of_Object 1 1 @@ -4954,16 +4957,16 @@ VProgrammedNode 7 Begin_Of_Object VConfigurationRoot 8 Begin_Of_Object 1 End_Of_Object VConfigurationRoot 8 - 1 "include\CAPL\ModbusClient.can" + 1 "include\CAPL\PollingModbusClient.can" 1 -J:\HsKA\NB7\Bachelorthesis\CANoe\Modbus-CAPL\include\CAPL\ModbusClient.cbf -Client_2 +J:\HsKA\NB7\Bachelorthesis\CANoe\Modbus-CAPL\include\CAPL\PollingModbusClient.cbf +Client_100 Modbus 5 ECU 2 ECU 2 EOF_TITLE_INFO -Client_2 +Client_100 1 0 1 @@ -4994,7 +4997,7 @@ EOF_MBSSDATA EOF_NLDATA 0 EOF_ASSEMBLYDATA - 1 "include\CAPL\ModbusClient.cbf" + 1 "include\CAPL\PollingModbusClient.cbf" VIPBStackSetting 8 Begin_Of_Object 3 1 @@ -5046,7 +5049,7 @@ End_Of_Object VIPBStackSetting 8 NDebugger::VDebuggerHost 8 Begin_Of_Object 2 0 -27 +28 NDebugger::VFile 9 Begin_Of_Object 1 1 "ModbusTcpCommon.cin" @@ -5124,26 +5127,6 @@ NDebugger::VFile 9 Begin_Of_Object End_Of_Object NDebugger::VFile 9 NDebugger::VFile 9 Begin_Of_Object 1 - 1 "include\CAPL\include\Common.cin" -28 -End_Of_Object NDebugger::VFile 9 -NDebugger::VFile 9 Begin_Of_Object -1 - 1 "include\CAPL\include\ModbusClientCommon.cin" -29 -End_Of_Object NDebugger::VFile 9 -NDebugger::VFile 9 Begin_Of_Object -1 - 1 "include\CAPL\include\TcpUdpCommon.cin" -33 -End_Of_Object NDebugger::VFile 9 -NDebugger::VFile 9 Begin_Of_Object -1 - 1 "include\CAPL\ModbusClient.can" -35 -End_Of_Object NDebugger::VFile 9 -NDebugger::VFile 9 Begin_Of_Object -1 1 "include\CAPL\include\EilCommon.cin" 36 End_Of_Object NDebugger::VFile 9 @@ -5182,6 +5165,31 @@ NDebugger::VFile 9 Begin_Of_Object 1 "include\CAPL\include\DeviceInformation.cin" 43 End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\PollingModbusClient.can" +44 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\Common.cin" +45 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusClient.cin" +46 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusUdp.cin" +47 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\TcpUdpEilCommon.cin" +48 +End_Of_Object NDebugger::VFile 9 VNETStandaloneComponent 9 Begin_Of_Object 1 VNETControlBox 10 Begin_Of_Object @@ -5258,7 +5266,7 @@ End_Of_Object VUniqueBox 11 1 -1 0 0 0 0 0 0 0 0 0 0 0 End_Of_Object VNETControlBox 10 -132 +150 APPDIR Vector.CANoe.Debugger.DLL Vector.CANoe.Debugger, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null Vector.CANoe.Debugger.DebuggerComponent @@ -5300,34 +5308,52 @@ TypeRef:3 3 Int32 NrOfFiles -4 +7 Int32 FileID0 -35 +44 Int32 CurrentLine0 0 Int32 FileID1 -28 +45 Int32 CurrentLine1 0 Int32 FileID2 -29 +43 Int32 CurrentLine2 0 Int32 FileID3 -33 +46 Int32 CurrentLine3 0 Int32 +FileID4 +42 +Int32 +CurrentLine4 +0 +Int32 +FileID5 +47 +Int32 +CurrentLine5 +0 +Int32 +FileID6 +48 +Int32 +CurrentLine6 +0 +Int32 SelectedFileID -35 +44 Int32 NrOfWatchedVariables 0 @@ -5415,7 +5441,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -169746433 +1368551005 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5440,16 +5466,16 @@ VProgrammedNode 7 Begin_Of_Object VConfigurationRoot 8 Begin_Of_Object 1 End_Of_Object VConfigurationRoot 8 - 1 "include\CAPL\ModbusClient.can" + 1 "include\CAPL\PollingModbusClient.can" 1 -J:\HsKA\NB7\Bachelorthesis\CANoe\Modbus-CAPL\include\CAPL\ModbusClient2.cbf -Client_3 +J:\HsKA\NB7\Bachelorthesis\CANoe\Modbus-CAPL\include\CAPL\PollingModbusClient2.cbf +Client_101 Modbus 5 ECU 1 ECU 1 EOF_TITLE_INFO -Client_3 +Client_101 1 0 1 @@ -5480,7 +5506,7 @@ EOF_MBSSDATA EOF_NLDATA 0 EOF_ASSEMBLYDATA - 1 "include\CAPL\ModbusClient2.cbf" + 1 "include\CAPL\PollingModbusClient2.cbf" VIPBStackSetting 8 Begin_Of_Object 3 1 @@ -5550,7 +5576,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -169746433 +1368551005 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5583,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 @@ -5661,105 +5687,11 @@ EOF_MBSSDATA 1 0 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -5770,10 +5702,104 @@ EOF_MBSSDATA - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + End_Of_Object VSSPlugInConfiguration 6 NULL @@ -5809,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 769 969 432 632 2882400002 0 0 0 0 0 0 3 +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 SS_BEGIN_COMMON_INFO 1 0 @@ -5833,7 +5859,6 @@ Misc 1 SS_END_COMMON_INFO - EOF_BUSDATA 1 _Start_VPRBSManager 1 @@ -5933,7 +5958,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 @@ -6253,6 +6278,7 @@ End FiltersEnd 1 1 + END_OF_WORKSPACE_MEMBER_DATA END_OF_WORKSPACE_MEMBER 1 diff --git a/Modbus-CAPL/include/CAPL/PollingModbusClient.can b/Modbus-CAPL/include/CAPL/PollingModbusClient.can index e44725c..0e822e7 100644 --- a/Modbus-CAPL/include/CAPL/PollingModbusClient.can +++ b/Modbus-CAPL/include/CAPL/PollingModbusClient.can @@ -23,6 +23,7 @@ on preStart OutputDebugLevel = Warning; // The debug level (messages in write window) } +// Connect to Modbus server, read the status of output registers and bits and start the cyclic timer on start { char ip[16]; @@ -33,8 +34,8 @@ 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(gDevOutputBitAddrR, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits); // Read the start status of the output bits - ModbusReadOutRegisters(gDevOutputRegAddrR, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters); // Read the start status of the output registers + 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 (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval > 0) // Start the polling timer setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval); @@ -50,7 +51,7 @@ on start /// error == FinalTimeout: The packet will not be resent /// error == Exception: The client responded with an exception (which again can have several reasons, see enum ModbusException) -/// This method gets called when an error occured while trying to read some bits (ModbusReadBits()) +// This method gets called when an error occured while trying to read some bits (ModbusReadBits()) void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap) { word i; @@ -70,7 +71,7 @@ void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException } } -/// This method gets called when an error occured while trying to read some registers (ModbusReadRegisters()) +// This method gets called when an error occured while trying to read some registers (ModbusReadRegisters()) void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap) { byte i; @@ -90,17 +91,17 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep } } -/// This method gets called when an error occured while trying to set a bit (ModbusWriteBit()) +// This method gets called when an error occured while trying to set a bit (ModbusWriteBit()) void OnModbusWriteBitFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} -/// This method gets called when an error occured while trying to set a register (ModbusWriteRegister()) +// This method gets called when an error occured while trying to set a register (ModbusWriteRegister()) void OnModbusWriteRegisterFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} -/// This method gets called when an error occured while trying to apply a mask on a register (ModbusWriteMask()) +// This method gets called when an error occured while trying to apply a mask on a register (ModbusWriteMask()) void OnModbusWriteMasksFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} -/// This method gets called when an error occured while trying to read and write registers (ModbusReadWriteRegisters()) +// This method gets called when an error occured while trying to read and write registers (ModbusReadWriteRegisters()) void OnModbusReadWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} -/// This method gets called when an error occured while trying to set multiple bits (ModbusWriteBits()) +// This method gets called when an error occured while trying to set multiple bits (ModbusWriteBits()) void OnModbusWriteBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} -/// This method gets called when an error occured while trying to set multiple registers (ModbusWriteRegisters()) +// This method gets called when an error occured while trying to set multiple registers (ModbusWriteRegisters()) void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap){} // -- Modbus Success ------------------------------------------------------------------ @@ -115,10 +116,10 @@ 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 0x01: // Read output bits + case ReadBitsOut: // Read output bits sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits"); - offset = mbreq.Address - gDevOutputBitAddrR; // Get the offset to the base output bit address + offset = mbreq.Address - thisDev.Address.Read.OutputBit; // 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]; @@ -126,10 +127,10 @@ void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[] break; - case 0x02: // Read input bits + case ReadBitsIn: // Read input bits sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); - offset = mbreq.Address - gDevInputBitAddr; // Get the offset to the base input bit address + offset = mbreq.Address - thisDev.Address.Read.InputBit; // 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]; @@ -145,10 +146,10 @@ 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 0x03: // Read output registers + case ReadRegistersOut: // Read output registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); - offset = mbreq.Address - gDevOutputRegAddrR; // Get the offset to the base output register address + offset = mbreq.Address - thisDev.Address.Read.OutputReg; // 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]; @@ -156,10 +157,10 @@ void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct break; - case 0x04: // Read input registers + case ReadRegistersIn: // Read input registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); - offset = mbreq.Address - gDevInputRegAddr; // Get the offset to the base input bit address + offset = mbreq.Address - thisDev.Address.Read.InputReg; // 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]; @@ -202,8 +203,8 @@ void OnModbusClientPanics(enum FatalErrors reason) // The timer will continuously poll the input registers and intput bits on timer gtRead { - ModbusReadRegisters(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters); - ModbusReadBits(0x0000, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputBits); + 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); } // 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 86b08e7..15e6e8f 100644 --- a/Modbus-CAPL/include/CAPL/include/Common.cin +++ b/Modbus-CAPL/include/CAPL/include/Common.cin @@ -174,6 +174,20 @@ void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3) } // 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, long num2, long num3, char str[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(1, lVl, msg, num1, num2, num3, str); +} +// 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, long num2, long num3, long num4) { char msg[500]; diff --git a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin index 66bc414..c48c13b 100644 --- a/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin +++ b/Modbus-CAPL/include/CAPL/include/DeviceInformation.cin @@ -13,11 +13,28 @@ /// This file is used at two position: The majority of the functions are used to analyze devices when making the config. The minority has to be called when initiating a Modbus client so it knows about the addresses and window size. variables { - word gDevOutputBitAddrR, gDevOutputRegAddrR; // Output start addresses Read - word gDevOutputBitAddrW, gDevOutputRegAddrW; // Output start addresses Write - word gDevInputBitAddr, gDevInputRegAddr; // Input start addresses - word gDevBitMaxCount, gDevRegMaxCount; // Max number of bits/registers - word gDevReceiveWindow = 1; // Registers size + // This structure is used by the Modbus Client. + struct + { + struct // Start addresses + { + struct // Start addresses Read + { + word OutputBit; + word OutputReg; + word InputBit; + word InputReg; + } Read; + struct // Start addresses Write + { + word OutputBit; + word OutputReg; + } Write; + } Address; + word BitMaxCount; // Max number of bits + word RegMaxCount; // 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 { @@ -52,26 +69,26 @@ void DeviceInit(byte vendor) switch ((enum Vendor) vendor) { case Wago: - gDevInputBitAddr = 0x0000; // Wago inputs start at 0x000 - gDevInputRegAddr = 0x0000; - gDevOutputBitAddrR = 0x0200; // Wago reading outputs start at 0x200 - gDevOutputRegAddrR = 0x0200; - gDevOutputBitAddrW = 0x0000; // Wago writing outputs start at 0x000 - gDevOutputRegAddrW = 0x0000; - gDevBitMaxCount = 0x0100; // Wago allows up to 256 inputs - gDevRegMaxCount = 0x0100; - gDevReceiveWindow = 5; // Wago can handle 5 requests simultaneously + 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 break; case BuR: - gDevInputBitAddr = 0x0000; // B&R inputs start at 0x000 - gDevInputRegAddr = 0x0000; - gDevOutputBitAddrR = 0x0000; // B&R reading digital outputs start at 0x000 - gDevOutputRegAddrR = 0x0800; // B&R reading analog outputs start at 0x800 - gDevOutputBitAddrW = 0x0000; // B&R writing outputs start at 0x000 - gDevOutputRegAddrW = 0x0000; - gDevBitMaxCount = 0x4000; // B&R allows up to 16348 digital inputs - gDevRegMaxCount = 0x0800; // B&R allows up to 2048 analog inputs - gDevReceiveWindow = 1; // B&R can only handle 1 request at a time + 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 break; default: OnModbusClientPanics(VendorIdUnknown); @@ -244,6 +261,7 @@ void _DeviceParseRegister(struct device device, word address, word data[], word { byte i; + //writeDbg(Debug, "_DeviceParseRegister: Address: 0x%04X, Data[0]: %d", address, data[0]); switch (device.Vendor) { case Wago: @@ -304,5 +322,8 @@ void _DeviceParseRegister(struct device device, word address, word data[], word break; } break; + default: + writeDbg(AlgoError, "DeviceGetInformation: Unknown vendor id: %d", device.Vendor); + OnModbusClientPanics(VendorIdUnknown); } } \ No newline at end of file diff --git a/Modbus-CAPL/include/CAPL/include/ModbusClient.cin b/Modbus-CAPL/include/CAPL/include/ModbusClient.cin index 80932e2..ea15c17 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusClient.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusClient.cin @@ -9,6 +9,7 @@ /// It provides following methods /// - ModbusInit() Prepare anything that Modbus works (open connection etc.) +/// - ModbusEnd() Client up everything (close connection etc.) /// - ModbusReadOutBits() Modbus Function Code: 0x01 (Discrete inputs) /// - ModbusReadInBits() Modbus Function Code: 0x02 (Coils) @@ -84,9 +85,19 @@ void ModbusInit(char Remote_IP[], word remotePort, word requestTimeout, byte max gMaxTransmissionCount = maxRetransmissions; } +// This method cleans up everything: Closes the connection, clears the queues and stops the timer +// It has to be called by the user/modbus client at the end of the measurement +void ModbusEnd() +{ + _ModbusDisconnect(); + gQueuePending.Clear(); + gQueueSent.Clear(); + gtModbusRobin.Cancel(); +} + // This method fills the ModbusApHeader structure 'mbap'. // It gets called by the Modbus request methods -void _ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode) +void _ModbusMakeHeader(struct ModbusApHeader mbap, word length, enum ModbusFuncCode funcCode) { mbap.TxID = gTxID++; // [2] Transaction ID mbap.Protocol = 0x0000; // [2] Protocol ID = 0 = Modbus @@ -102,23 +113,23 @@ void _ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode) // This method will submit a request to the Modbus server to read discrete inputs void ModbusReadInBits(word address, long count) { - _ModbusReadBits(0x02, address, count); + _ModbusReadBits(ReadBitsIn, address, count); } /// // This method will submit a request to the Modbus server to read coils void ModbusReadBits(word address, long count) { - _ModbusReadBits(0x02, address, count); + _ModbusReadBits(ReadBitsIn, address, count); } /// // This method will submit a request to the Modbus server to read coils void ModbusReadOutBits(word address, long count) { - _ModbusReadBits(0x01, address, count); + _ModbusReadBits(ReadBitsOut, address, count); } /// // This method will submit a request to the Modbus server to read discrete inputs or coils -void _ModbusReadBits(byte funcCode, word address, long count) +void _ModbusReadBits(enum ModbusFuncCode funcCode, word address, long count) { const byte length = __size_of(struct ModbusReqRead); byte buffer[length]; @@ -186,23 +197,23 @@ void _OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusExcept // This method will submit a request to the Modbus server to read input registers void ModbusReadInRegisters(word address, long count) { - _ModbusReadRegisters(0x04, address, count); + _ModbusReadRegisters(ReadRegistersIn, address, count); } /// // This method will submit a request to the Modbus server to read holding registers void ModbusReadRegisters(word address, long count) { - _ModbusReadRegisters(0x04, address, count); + _ModbusReadRegisters(ReadRegistersIn, address, count); } /// // This method will submit a request to the Modbus server to read holding registers void ModbusReadOutRegisters(word address, long count) { - _ModbusReadRegisters(0x03, address, count); + _ModbusReadRegisters(ReadRegistersOut, address, count); } /// // This method will submit a request to the Modbus server to read input or holding registers -void _ModbusReadRegisters(byte funcCode, word address, long count) +void _ModbusReadRegisters(enum ModbusFuncCode funcCode, word address, long count) { const byte length = __size_of(struct ModbusReqRead); byte buffer[length]; @@ -261,7 +272,7 @@ void _OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusE void ModbusWriteBit(word address, byte value) { const byte length = __size_of(struct ModbusReqWriteSingle); - const byte funcCode = 0x05; // B&R does not support 0x06 + enum ModbusFuncCode funcCode = WriteBit; byte buffer[length]; struct ModbusReqWriteSingle mbreq; @@ -312,7 +323,7 @@ void _OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusExcepti void ModbusWriteRegister(word address, word value) { const byte length = __size_of(struct ModbusReqWriteSingle); - const byte funcCode = 0x06; + enum ModbusFuncCode funcCode = WriteRegister; byte buffer[length]; struct ModbusReqWriteSingle mbreq; @@ -362,7 +373,7 @@ void _OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusEx void ModbusWriteBits(word address, long count, byte values[]) { const word maxLength = __size_of(struct ModbusReqWriteBits); - const byte funcCode = 0x0F; + enum ModbusFuncCode funcCode = WriteBits; byte buffer[maxLength]; struct ModbusReqWriteBits mbreq; word curCount; @@ -411,11 +422,11 @@ void ModbusWriteBits(word address, long count, byte values[]) // Use this when you simply have 1s and 0s void ModbusWriteBitsB(word address, long count, byte values[]) { - byte buffer[gMaxBitsPerWrite/8]; // length + byte buffer[0x4000/8]; // Maximum value from B&R devices. *sigh* word length; dword ellCount; dword i; - dword j; + byte j; char str1[20*2], str2[20*3]; length = (word)_ceil(count / 8.0); @@ -479,7 +490,7 @@ void _OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusExcept void ModbusWriteRegisters(word address, long count, word values[]) { const word maxLength = __size_of(struct ModbusReqWriteRegisters); - const byte funcCode = 0x10; + enum ModbusFuncCode funcCode = WriteRegisters; byte buffer[maxLength]; struct ModbusReqWriteRegisters mbreq; word curCount; @@ -547,7 +558,7 @@ void _OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusE void ModbusWriteMasks(word address, word and, word or) { const word length = __size_of(struct ModbusReqWriteMasks); - const byte funcCode = 0x16; + enum ModbusFuncCode funcCode = MaskRegister; byte buffer[length]; struct ModbusReqWriteMasks mbreq; @@ -593,7 +604,7 @@ void _OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusExcep void ModbusReadWriteRegisters(word readAddress, long readCount, word writeAddress, long writeCount, word values[]) { const word maxLength = __size_of(struct ModbusReqReadWriteRegisters); - const byte funcCode = 0x17; + enum ModbusFuncCode funcCode = ReadWriteRegisters; byte buffer[maxLength]; struct ModbusReqReadWriteRegisters mbreq; byte dataLength; @@ -691,6 +702,7 @@ void _OnModbusReceive(dword socket, long result, dword address, dword port, byte writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr); _ModbusDisconnect(); } + _ModbusRecv(); } /// <-OnModbusReceive> @@ -708,8 +720,8 @@ void _OnModbusReceive2(byte buffer[], dword size) offset = 0; do { - writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset); memcpy_n2h(mbap, buffer, offset); + writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d. TxID = %d", offset, mbap.TxID); _OnModbusReceive2OnePacket(buffer, offset, mbap); offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; @@ -778,12 +790,12 @@ void _OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap) switch (mbap.FuncCode) { - case 0x80+ReadBits1: - case 0x80+ReadBits2: + case 0x80+ReadBitsOut: + case 0x80+ReadBitsIn: _OnModbusReceiveBitsException(mbap, ex); break; - case 0x80+ReadRegisters1: - case 0x80+ReadRegisters2: + case 0x80+ReadRegistersOut: + case 0x80+ReadRegistersIn: _OnModbusReceiveRegistersException(mbap, ex); break; case 0x80+WriteBit: @@ -819,12 +831,12 @@ void _OnModbusReceive2Success(byte buffer[], struct ModbusApHeader mbap, int off // Let's give the PDU to the corresponding function switch (mbap.FuncCode) { - case ReadBits1: - case ReadBits2: + case ReadBitsOut: + case ReadBitsIn: _OnModbusReceiveBits(mbuffer); break; - case ReadRegisters1: - case ReadRegisters2: + case ReadRegistersOut: + case ReadRegistersIn: _OnModbusReceiveRegisters(mbuffer); break; case WriteBit: @@ -913,12 +925,12 @@ on timer gtModbusRobin memcpy_n2h(mbap, gQueueSent[TxID].Buffer); switch(mbap.FuncCode) // throw an "error" in each case { - case ReadBits1: - case ReadBits2: + case ReadBitsOut: + case ReadBitsIn: OnModbusReadBitsFailed(reqError, None, mbap); break; - case ReadRegisters1: - case ReadRegisters2: + case ReadRegistersOut: + case ReadRegistersIn: OnModbusReadRegistersFailed(reqError, None, mbap); break; case WriteBit: @@ -948,13 +960,12 @@ on timer gtModbusRobin // Second: send new packets for (long TxID : gQueuePending) { - if (gQueueSent.Size() >= gDevReceiveWindow) // Device cannot handle that many messages at a time - break; // Wait for the next turn + if (gQueueSent.Size() >= thisDev.ReceiveWindow) // Device cannot handle that many messages at a time + break; // Wait for the next turn // Now send the packet // if packet was sent or the socket is not currently being opened - // what was that thing with the socket state? Somehow it was neccessary... - if (_ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0 || gSocketState != NULL) + if (_ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0) { memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue gQueuePending.Remove(TxID); diff --git a/Modbus-CAPL/include/CAPL/include/ModbusEil.cin b/Modbus-CAPL/include/CAPL/include/ModbusEil.cin index 2aac176..e96a521 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusEil.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusEil.cin @@ -40,7 +40,7 @@ word _ModbusConnectTo(char Remote_IP[], word remotePort) return ipGetLastError(); } - return ModbusConnectTo(remoteIp, remotePort); + return _ModbusConnectTo(remoteIp, remotePort); } // This method prepares anything in a way that sending with ModbusSnd() is possible. // Here: The method will create an ARP telegram to get the MAC address of the device with the specified remoteIp @@ -63,7 +63,7 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) gRemoteIP = (remoteIp >> 24) | (remoteIp >> 8) & 0x0000FF00 | (remoteIp << 8) & 0x00FF0000 | (remoteIp << 24); if (gPacket != 0) - ModbusDisconnect(); + _ModbusDisconnect(); // Try to create an ARP packet that gets the MAC from remote server gPacket = EthInitPacket("arp"); if (gPacket == 0) @@ -145,7 +145,7 @@ byte _ModbusSnd(byte buffer[], word length) switch (gSocketState) { case CLOSED: - ModbusConnectTo(gRemoteIP, gRemotePort); + _ModbusConnectTo(gRemoteIP, gRemotePort); if (gSocketState != OK) { writeDbg(ConnWarning, "EilSnd: Reconnecting failed! Doing nothing."); diff --git a/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin b/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin index 18c0209..21a379c 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusStructs.cin @@ -7,6 +7,20 @@ variables const word gMaxBitsPerWrite = 1968; // Multiple of 8! const word gMaxRegsPerWrite = 123; + enum ModbusFuncCode + { + ReadBitsOut = 0x01, + ReadBitsIn = 0x02, + ReadRegistersOut = 0x03, + ReadRegistersIn = 0x04, + WriteBit = 0x05, + WriteRegister = 0x06, + WriteBits = 0x0F, + WriteRegisters = 0x10, + MaskRegister = 0x16, + ReadWriteRegisters = 0x17 + }; + // A normal Modbus Application Header. Every Modbus Packet begins with these 7 (+FuncCode) Bytes _align(1) struct ModbusApHeader { @@ -127,27 +141,12 @@ variables GatewayPathsNA = 0x0A, TargetOffline = 0x0B }; - enum ModbusFuncCode - { - ReadBits1 = 0x01, - ReadBits2 = 0x02, - ReadRegisters1 = 0x03, - ReadRegisters2 = 0x04, - WriteBit = 0x05, - WriteRegister = 0x06, - WriteBits = 0x0F, - WriteRegisters = 0x10, - MaskRegister = 0x16, - ReadWriteRegisters = 0x17 - }; - - enum FatalErrors { - ParsingBuffer = 0x00, - ModbusPackageWasSplit = 0x01, - DeviceCodeUnknown = 0x02, - VendorIdUnknown = 0x03, - ConnectionError = 0x04 + ParsingBuffer, + ModbusPackageWasSplit, + DeviceCodeUnknown, + VendorIdUnknown, + ConnectionError }; } \ 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 e099d07..31ddf03 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusTcp.cin @@ -28,7 +28,7 @@ word _TcpOpenSocket() if (EthGetAdapterStatus() != 2) // Not connected { - writeDbg(ConnError, "TcpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus()); + writeDbg(ConnError, "_TcpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus()); OnModbusClientPanics(ConnectionError); return INVALID_IP; } @@ -39,13 +39,13 @@ word _TcpOpenSocket() if (error != 0) { gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText)); - writeDbg(ConnInfo, "TcpOpenSocket: could not open socket: (%d) %s", error, errorText); + writeDbg(ConnInfo, "_TcpOpenSocket: could not open socket: (%d) %s", error, errorText); OnModbusClientPanics(ConnectionError); return error; } else { - writeDbg(ConnInfo, "Tcp socket opened."); + writeDbg(ConnInfo, "_TcpOpenSocket: Tcp socket opened."); } return 0; } @@ -60,7 +60,7 @@ word _ModbusConnectTo(char Remote_IP[], word remotePort) remoteIp = IpGetAddressAsNumber(Remote_IP); if (remoteIp == INVALID_IP) { - writeDbg(ConnError, "TcpConnectTo: invalid server Ip address: %s", Remote_IP); + writeDbg(ConnError, "_ModbusConnectTo: invalid server Ip address: %s", Remote_IP); OnModbusClientPanics(ConnectionError); return 1; } @@ -75,7 +75,7 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) long fehler; // Try to open a socket - fehler = TcpOpenSocket(); + fehler = _TcpOpenSocket(); if (fehler != 0) { gSocketState = ERROR; @@ -93,16 +93,21 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) if (fehler != WSAEWOULDBLOCK) // OnTcpConnect will be called otherwise { - writeDbg(ConnError, "TcpConnectTo: No connection established: %d", fehler); + writeDbg(ConnError, "_ModbusConnectTo: No connection established: %d", fehler); gSocketState = ERROR; OnModbusClientPanics(ConnectionError); return fehler; } + else + { + writeDbg(ConnDebug, "_ModbusConnectTo: WSAE would block"); + gSocketState = NULL; + } return 0; } else { - writeDbg(ConnInfo, "TcpConnectTo: Successfully connected to server"); + writeDbg(ConnInfo, "_ModbusConnectTo: Successfully connected to server"); gSocketState = OK; return 0; } @@ -110,21 +115,21 @@ word _ModbusConnectTo(dword remoteIp, word remotePort) // This method will be called when TcpSocket.Connect() had to defer the result (and returned WSAEWOULDBLOCK). // It checks whether the connection was opened successfully and sets the socket state accordingly -void _OnTcpConnect(dword socket, long result) +void OnTcpConnect(dword socket, long result) { if (result != 0) { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); writeDbg(ConnError, "OnTcpConnect: (%d) %s", gSocket.GetLastSocketError(), gIpLastErrStr); gSocketState = ERROR; - OnModbusClientPanics(ConnectionError); + OnModbusClientPanics(ConnectionError); return; } else { writeDbg(ConnInfo, "OnTcpConnect: Successfully connected to server"); gSocketState = OK; - ModbusStartQueue(); + _ModbusStartQueue(); } } @@ -132,6 +137,7 @@ void _OnTcpConnect(dword socket, long result) // Here: Simply close the socket. This will also disconnect the remote device void _ModbusDisconnect() { + writeDbg(ConnDebug, "_ModbusDisconnect: Disconnecting"); gSocket.Close(); gSocketState = CLOSED; } @@ -144,8 +150,9 @@ void _ModbusRecv() if (gSocketState != OK) { - writeDbg(ConnWarning, "ModbusRecv: Socket status is not OK! Doing nothing."); - OnModbusClientPanics(ConnectionError); + writeDbg(ConnWarning, "_ModbusRecv: Socket status is not OK!"); + _ModbusDisconnect(); +// OnModbusClientPanics(ConnectionError); return; } @@ -158,8 +165,8 @@ void _ModbusRecv() if (gIpLastErr != WSA_IO_PENDING) // Calling OnTcpReceive otherwise { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeDbg(ConnError, "ModbusRecv: (%d) %s", gIpLastErr, gIpLastErrStr); - ModbusDisconnect(); + writeDbg(ConnError, "_ModbusRecv: (%d) %s", gIpLastErr, gIpLastErrStr); + _ModbusDisconnect(); } } @@ -178,20 +185,25 @@ word _ModbusSnd(byte buffer[], word length) _ModbusConnectTo(gRemoteIP, gRemotePort); // Try to (re)connect if (gSocketState != OK) // If this didn't work { - writeDbg(ConnError, "ModbusSnd: Reconnecting failed!"); - OnModbusClientPanics(ConnectionError); + if (gSocketState != NULL) // not WSAE WOULD BLOCK + { + writeDbg(ConnError, "_ModbusSnd: Reconnecting failed!"); + OnModbusClientPanics(ConnectionError); + } return 1; } case OK: break; + case NULL: + return 1; default: - writeDbg(ConnError, "ModbusSnd: Socket status is not OK! Doing nothing."); + writeDbg(ConnError, "_ModbusSnd: Socket status is not OK!"); OnModbusClientPanics(ConnectionError); return 1; } bin_to_strhex(buffer, str); - writeDbg(ConnDebug, "ModbusSnd: %s (Länge: %d)", str, length); + writeDbg(ConnDebug, "_ModbusSnd: %s (Länge: %d)", str, length); if (gSocket.Send(buffer, length) != 0) { @@ -200,8 +212,8 @@ word _ModbusSnd(byte buffer[], word length) if (gIpLastErr != WSA_IO_PENDING) { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeDbg(ConnError, "ModbusSnd: (%d) %s", gIpLastErr, gIpLastErrStr); - ModbusDisconnect(); + writeDbg(ConnError, "_ModbusSnd: (%d) %s", gIpLastErr, gIpLastErrStr); + _ModbusDisconnect(); return 1; } // else: tough luck!