ModbusClient.cin
Counting the send attempts to reject packets that cannot be send (e.g. wrong network) MakeConfig.can Introduced options (skip255 and useThirdIpNameForNodeName)
This commit is contained in:
parent
caf58bd7d6
commit
84ab39d5b3
6 changed files with 127 additions and 66 deletions
|
@ -1,4 +1,4 @@
|
||||||
;CANoe Version |4|7|1|52132 MakeConfig
|
;CANoe Version |4|7|1|52133 MakeConfig
|
||||||
Version: 8.2.40 Build 40
|
Version: 8.2.40 Build 40
|
||||||
32 PRO
|
32 PRO
|
||||||
5
|
5
|
||||||
|
@ -1261,9 +1261,37 @@ Grafik-Fenster
|
||||||
237
|
237
|
||||||
0
|
0
|
||||||
0
|
0
|
||||||
|
1
|
||||||
0
|
0
|
||||||
0
|
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
|
0
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
|
@ -2933,7 +2961,7 @@ End_Of_Object VGrMnBox 3
|
||||||
VDOLocalInfoStruct 3 Begin_Of_Object
|
VDOLocalInfoStruct 3 Begin_Of_Object
|
||||||
3
|
3
|
||||||
1
|
1
|
||||||
98
|
101
|
||||||
VDAOBus 4 Begin_Of_Object
|
VDAOBus 4 Begin_Of_Object
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
|
@ -3063,7 +3091,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object
|
||||||
End_Of_Object VSimulinkModelViewerConfiguration 7
|
End_Of_Object VSimulinkModelViewerConfiguration 7
|
||||||
1
|
1
|
||||||
0
|
0
|
||||||
4212996857
|
1115474418
|
||||||
0
|
0
|
||||||
NodeSignalPanelBustypeCount 0
|
NodeSignalPanelBustypeCount 0
|
||||||
End_Of_Object VSimulationNode 6
|
End_Of_Object VSimulationNode 6
|
||||||
|
@ -3101,7 +3129,7 @@ NULL
|
||||||
End_Of_Object VDOLocalInfoStruct 3
|
End_Of_Object VDOLocalInfoStruct 3
|
||||||
0.000000
|
0.000000
|
||||||
0 0
|
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 335238400 0 336542644 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 355173376 0 423022796 3
|
||||||
SS_BEGIN_COMMON_INFO
|
SS_BEGIN_COMMON_INFO
|
||||||
1
|
1
|
||||||
0
|
0
|
||||||
|
@ -3113,7 +3141,7 @@ Ethernet
|
||||||
11
|
11
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
335879144 1 0 1 0 0 1 0 0 0 2000 1
|
422945832 1 0 1 0 0 1 0 0 0 2000 1
|
||||||
SS_BEGIN_COMMON_INFO
|
SS_BEGIN_COMMON_INFO
|
||||||
1
|
1
|
||||||
3
|
3
|
||||||
|
@ -3224,7 +3252,7 @@ End_Of_Serialized_Data 2
|
||||||
End_Of_Object VWriteBox 2
|
End_Of_Object VWriteBox 2
|
||||||
VWinStore 2 Begin_Of_Object
|
VWinStore 2 Begin_Of_Object
|
||||||
1
|
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_Child_List
|
||||||
End_Of_Object VWinStore 2
|
End_Of_Object VWinStore 2
|
||||||
VWinStore 2 Begin_Of_Object
|
VWinStore 2 Begin_Of_Object
|
||||||
|
@ -3537,6 +3565,7 @@ End
|
||||||
FiltersEnd
|
FiltersEnd
|
||||||
0 0
|
0 0
|
||||||
|
|
||||||
|
|
||||||
END_OF_WORKSPACE_MEMBER_DATA
|
END_OF_WORKSPACE_MEMBER_DATA
|
||||||
END_OF_WORKSPACE_MEMBER
|
END_OF_WORKSPACE_MEMBER
|
||||||
1
|
1
|
||||||
|
|
|
@ -25,6 +25,8 @@ variables
|
||||||
word ADi, ADn, ADl; // Some variables for "AnalyzeDevices"
|
word ADi, ADn, ADl; // Some variables for "AnalyzeDevices"
|
||||||
|
|
||||||
byte ggMaxTransmissionCount;
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
on preStart
|
on preStart
|
||||||
|
@ -39,7 +41,12 @@ on preStart
|
||||||
// Scan a range of IPs for devices (if nothing was set above). Start and Stop go here
|
// 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
|
// Please note: Currently .255 will be skipped! Don't use this address for devices
|
||||||
strncpy(gScanFirstIp, "192.168.1.2", elCount(gScanFirstIp));
|
strncpy(gScanFirstIp, "192.168.1.2", elCount(gScanFirstIp));
|
||||||
strncpy(gScanLastIp, "192.168.1.20", elCount(gScanLastIp));
|
strncpy(gScanLastIp, "192.168.2.20", elCount(gScanLastIp));
|
||||||
|
|
||||||
|
// Whether the third byte of the IP address shall be used in the node name
|
||||||
|
useThirdIpByteForNames = 0;
|
||||||
|
// Whether the IP address .255 (broadcast in /24) shall be skipped
|
||||||
|
skip255 = 1;
|
||||||
|
|
||||||
// Name of the project
|
// Name of the project
|
||||||
strncpy(name, "Modbus", elCount(name));
|
strncpy(name, "Modbus", elCount(name));
|
||||||
|
@ -48,7 +55,7 @@ on preStart
|
||||||
strncpy(fnSysvar, "include/SysVars/generated.vsysvar", elCount(fnSysvar));
|
strncpy(fnSysvar, "include/SysVars/generated.vsysvar", elCount(fnSysvar));
|
||||||
strncpy(fnDbc, "include/DBC/generated.dbc", elCount(fnDbc));
|
strncpy(fnDbc, "include/DBC/generated.dbc", elCount(fnDbc));
|
||||||
|
|
||||||
OutputDebugLevel = Debug;//Error;
|
OutputDebugLevel = Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
on start
|
on start
|
||||||
|
@ -87,7 +94,7 @@ void PutString(byte d)
|
||||||
/// <Step1>
|
/// <Step1>
|
||||||
void DetectDevices()
|
void DetectDevices()
|
||||||
{
|
{
|
||||||
write("Scanning from %s to %s with timeout of %d ms", gScanFirstIp, gScanLastIp, @sysvar::Config::Modbus::RequestTimeout);
|
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
|
gScanFirst = ipGetAddressAsNumber(gScanFirstIp); // We have to use big endian here
|
||||||
gScanLast = swapDWord(ipGetAddressAsNumber(gScanLastIp)); // But not here :)
|
gScanLast = swapDWord(ipGetAddressAsNumber(gScanLastIp)); // But not here :)
|
||||||
|
@ -102,11 +109,15 @@ void DetectDevicesNext()
|
||||||
{
|
{
|
||||||
gScanFirst = swapDWord(gScanFirst);
|
gScanFirst = swapDWord(gScanFirst);
|
||||||
gScanFirst++;
|
gScanFirst++;
|
||||||
if ((gScanFirst & 0xFF) == 0xFF) // skip .255
|
if (skip255 && (gScanFirst & 0xFF) == 0xFF) // skip .255
|
||||||
{
|
{
|
||||||
gScanFirst++;
|
gScanFirst++;
|
||||||
writeLineEx(0, 0, "%d.%d.%d.%d ", gScanFirst >> 24, (gScanFirst >> 16) & 0xFF, (gScanFirst >> 8) & 0xFF, gScanFirst & 0xFF);
|
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 (gScanFirst > gScanLast)
|
if (gScanFirst > gScanLast)
|
||||||
{
|
{
|
||||||
|
@ -124,12 +135,7 @@ void DetectDevicesNext()
|
||||||
/// <Step1>
|
/// <Step1>
|
||||||
void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException ex, struct ModbusApHeader mbap)
|
||||||
{
|
{
|
||||||
switch (error)
|
DetectDevicesNext(); // Timeout, NotSent, Exception! We will go to the next device
|
||||||
{
|
|
||||||
case FinalTimeout:
|
|
||||||
case Exception:
|
|
||||||
DetectDevicesNext(); // Timeout! We will go to the next device
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/// <Step1>
|
/// <Step1>
|
||||||
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
|
void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq)
|
||||||
|
@ -238,6 +244,9 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep
|
||||||
case FinalTimeout:
|
case FinalTimeout:
|
||||||
writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP);
|
writeLineEx(0, 3, "Error while analyzing %s! The device did not respond! Ignoring...", gIpsSorted[ips[ADi]].IP);
|
||||||
break;
|
break;
|
||||||
|
case NotSent:
|
||||||
|
writeLineEx(0, 3, "Error while analyzing %s! The device was not available! Ignoring...", gIpsSorted[ips[ADi]].IP);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
gQueueAck.Clear(); // Clear all queues
|
gQueueAck.Clear(); // Clear all queues
|
||||||
gQueuePending.Clear();
|
gQueuePending.Clear();
|
||||||
|
@ -317,8 +326,11 @@ void GenSysvars()
|
||||||
DeviceInit(gIpsSorted[ipN].Vendor);
|
DeviceInit(gIpsSorted[ipN].Vendor);
|
||||||
|
|
||||||
PutString(" <namespace name=\"Client_");
|
PutString(" <namespace name=\"Client_");
|
||||||
//PutString(netS);
|
if (useThirdIpByteForNames)
|
||||||
//PutString("_");
|
{
|
||||||
|
PutString(gIpsSorted[ipN].IpNet);
|
||||||
|
PutString("_");
|
||||||
|
}
|
||||||
PutString(gIpsSorted[ipN].IpLsb);
|
PutString(gIpsSorted[ipN].IpLsb);
|
||||||
PutString("\" comment=\"Server with ip address '");
|
PutString("\" comment=\"Server with ip address '");
|
||||||
PutString(gIpsSorted[ipN].Ip);
|
PutString(gIpsSorted[ipN].Ip);
|
||||||
|
@ -466,8 +478,11 @@ void GenDbc()
|
||||||
for (long ipN : gIpsSorted)
|
for (long ipN : gIpsSorted)
|
||||||
{
|
{
|
||||||
PutString(" Client_");
|
PutString(" Client_");
|
||||||
//PutString(gIpsSorted[ipN].IpNet);
|
if (useThirdIpByteForNames)
|
||||||
//PutString("_");
|
{
|
||||||
|
PutString(gIpsSorted[ipN].IpNet);
|
||||||
|
PutString("_");
|
||||||
|
}
|
||||||
PutString(gIpsSorted[ipN].IpLsb);
|
PutString(gIpsSorted[ipN].IpLsb);
|
||||||
}
|
}
|
||||||
PutString("\n\n\n\n");
|
PutString("\n\n\n\n");
|
||||||
|
|
|
@ -38,7 +38,7 @@ variables
|
||||||
|
|
||||||
enum Vendor // The Vendor enum. All Vendors have to listed here and all listed vendors have to be implemented in this file
|
enum Vendor // The Vendor enum. All Vendors have to listed here and all listed vendors have to be implemented in this file
|
||||||
{
|
{
|
||||||
All = 0xFFFF,
|
All = 0xFF,
|
||||||
Wago = 23, // Wago
|
Wago = 23, // Wago
|
||||||
BuR = 2 // B&R
|
BuR = 2 // B&R
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,7 @@ variables
|
||||||
{
|
{
|
||||||
word TimeoutTicks; // Time counter [ms]. Used to watch for timeouts (see gRequestTimeout)
|
word TimeoutTicks; // Time counter [ms]. Used to watch for timeouts (see gRequestTimeout)
|
||||||
byte Timeouts;
|
byte Timeouts;
|
||||||
|
byte SendTries;
|
||||||
word Length;
|
word Length;
|
||||||
byte Buffer[gModbusMaxTelegramSize];
|
byte Buffer[gModbusMaxTelegramSize];
|
||||||
};
|
};
|
||||||
|
@ -157,6 +158,7 @@ void _ModbusReadBits(enum ModbusFuncCode funcCode, word address, long count)
|
||||||
OnModbusClientPanics(AddressFailure);
|
OnModbusClientPanics(AddressFailure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FC1: Read Coils (DO), FC2: Read Discret Inputs (DI)
|
// FC1: Read Coils (DO), FC2: Read Discret Inputs (DI)
|
||||||
while (count > 0 && address < devEndAddr)
|
while (count > 0 && address < devEndAddr)
|
||||||
{
|
{
|
||||||
|
@ -279,7 +281,7 @@ void _ModbusReadRegisters(enum ModbusFuncCode funcCode, word address, long count
|
||||||
writeDbg(MbWarning, "_ModbusReadBits: Impossible to read %d bits at 0x%04X. Changed count to %d.", curCount, address, devEndAddr - address);
|
writeDbg(MbWarning, "_ModbusReadBits: Impossible to read %d bits at 0x%04X. Changed count to %d.", curCount, address, devEndAddr - address);
|
||||||
curCount = devEndAddr - address;
|
curCount = devEndAddr - address;
|
||||||
}
|
}
|
||||||
write("address = 0x%04X, count = %d, curCount = %d, devStartAddr = 0x%04X, devEndAddr = 0x%04X", address, count, curCount, devStartAddr, devEndAddr);
|
//write("address = 0x%04X, count = %d, curCount = %d, devStartAddr = 0x%04X, devEndAddr = 0x%04X", address, count, curCount, devStartAddr, devEndAddr);
|
||||||
|
|
||||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
|
@ -440,6 +442,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
long offset;
|
long offset;
|
||||||
|
|
||||||
// FC15: Write Multiple Bits (DOs)
|
// FC15: Write Multiple Bits (DOs)
|
||||||
|
offset = 0;
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
if (count > gMaxBitsPerWrite)
|
if (count > gMaxBitsPerWrite)
|
||||||
|
@ -463,7 +466,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
for (i = 0; i < dataLength; i++) // [264] Byte status, 8 per byte
|
for (i = 0; i < dataLength; i++) // [264] Byte status, 8 per byte
|
||||||
mbreq.Data[i] = values[i+offset/8];
|
mbreq.Data[i] = values[i+offset/8];
|
||||||
|
|
||||||
writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address, curCount);
|
writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address+offset, curCount);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||||
|
@ -955,7 +958,6 @@ void _ModbusStartQueue()
|
||||||
// The pending packets may be sent when there is free space in the sending window
|
// The pending packets may be sent when there is free space in the sending window
|
||||||
on timer gtModbusRobin
|
on timer gtModbusRobin
|
||||||
{
|
{
|
||||||
struct ModbusApHeader mbap;
|
|
||||||
enum ModbusRequestError reqError;
|
enum ModbusRequestError reqError;
|
||||||
|
|
||||||
writeDbg(ConnDebug, "gtModbusRobin: Queue Sent: %d, Queue Pending: %d, Queue Ack: %d", gQueueSent.Size(), gQueuePending.Size(), gQueueAck.Size());
|
writeDbg(ConnDebug, "gtModbusRobin: Queue Sent: %d, Queue Pending: %d, Queue Ack: %d", gQueueSent.Size(), gQueuePending.Size(), gQueueAck.Size());
|
||||||
|
@ -968,7 +970,7 @@ on timer gtModbusRobin
|
||||||
// timed out!
|
// timed out!
|
||||||
if (++gQueueSent[TxID].Timeouts < gMaxTransmissionCount) // if we may resend it
|
if (++gQueueSent[TxID].Timeouts < gMaxTransmissionCount) // if we may resend it
|
||||||
{
|
{
|
||||||
writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID);
|
writeDbg(ConnInfo, "gtModbusRobin: Packet 0x%04X timed out! Retrying...", TxID);
|
||||||
gQueueSent[TxID].TimeoutTicks = 0;
|
gQueueSent[TxID].TimeoutTicks = 0;
|
||||||
_ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it
|
_ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it
|
||||||
reqError = Timeout;
|
reqError = Timeout;
|
||||||
|
@ -976,43 +978,14 @@ on timer gtModbusRobin
|
||||||
}
|
}
|
||||||
else // we will NOT resend it
|
else // we will NOT resend it
|
||||||
{
|
{
|
||||||
writeDbg(ConnWarning, "Packet 0x%04X timed out! Giving up", TxID);
|
writeDbg(ConnWarning, "gtModbusRobin: Packet 0x%04X timed out! Giving up", TxID);
|
||||||
reqError = FinalTimeout;
|
reqError = FinalTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy_n2h(mbap, gQueueSent[TxID].Buffer);
|
_ModbusSendTimerError(gQueueSent[TxID].Buffer, reqError); // throw an "error" in each case
|
||||||
switch(mbap.FuncCode) // throw an "error" in each case
|
|
||||||
{
|
|
||||||
case ReadBitsOut:
|
|
||||||
case ReadBitsIn:
|
|
||||||
OnModbusReadBitsFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case ReadRegistersOut:
|
|
||||||
case ReadRegistersIn:
|
|
||||||
OnModbusReadRegistersFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case WriteBit:
|
|
||||||
OnModbusWriteBitFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case WriteRegister:
|
|
||||||
OnModbusWriteRegisterFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case WriteBits:
|
|
||||||
OnModbusWriteBitsFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case WriteRegisters:
|
|
||||||
OnModbusWriteRegistersFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case MaskRegister:
|
|
||||||
OnModbusWriteMasksFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
case ReadWriteRegisters:
|
|
||||||
OnModbusReadWriteRegistersFailed(reqError, None, mbap);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reqError == FinalTimeout) // remove the packet from queue
|
if (reqError == FinalTimeout) // remove the packet from queue
|
||||||
gQueueSent.Remove(TxID); // wait until here to let the methods above access the request
|
gQueueSent.Remove(TxID); // wait until here to let the methods above access the request
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second: send new packets
|
// Second: send new packets
|
||||||
|
@ -1025,16 +998,59 @@ on timer gtModbusRobin
|
||||||
// if packet was sent or the socket is not currently being opened
|
// if packet was sent or the socket is not currently being opened
|
||||||
if (_ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0)
|
if (_ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0)
|
||||||
{
|
{
|
||||||
memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue
|
memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue
|
||||||
|
gQueuePending.Remove(TxID);
|
||||||
|
_ModbusRecv(); // wait for new packets
|
||||||
|
}
|
||||||
|
else if (gQueuePending[TxID].SendTries++ > 10) // We have tried to send this packet too often. Something is wrong!?
|
||||||
|
{
|
||||||
|
writeDbg(ConnError, "gtModbusRobin: The packet 0x%04X could not be sent, _ModbusSnd() rejected it several times", TxID);
|
||||||
|
_ModbusSendTimerError(gQueuePending[TxID].Buffer, NotSent);
|
||||||
gQueuePending.Remove(TxID);
|
gQueuePending.Remove(TxID);
|
||||||
_ModbusRecv(); // wait for new packets
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop timer to reduce load and latency of first new packet
|
// Stop timer to reduce load and latency of first new packet
|
||||||
if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)
|
if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)
|
||||||
{
|
{
|
||||||
writeDbg(ConnDebug, "Stopping Timer gtModbusRobin");
|
writeDbg(ConnDebug, "gtModbusRobin: Stopping Timer");
|
||||||
this.Cancel();
|
this.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <-ModbusSend>
|
||||||
|
// This method will give an Error
|
||||||
|
void _ModbusSendTimerError(byte buffer[], enum ModbusRequestError reqError)
|
||||||
|
{
|
||||||
|
struct ModbusApHeader mbap;
|
||||||
|
memcpy_n2h(mbap, buffer);
|
||||||
|
switch(mbap.FuncCode)
|
||||||
|
{
|
||||||
|
case ReadBitsOut:
|
||||||
|
case ReadBitsIn:
|
||||||
|
OnModbusReadBitsFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case ReadRegistersOut:
|
||||||
|
case ReadRegistersIn:
|
||||||
|
OnModbusReadRegistersFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case WriteBit:
|
||||||
|
OnModbusWriteBitFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case WriteRegister:
|
||||||
|
OnModbusWriteRegisterFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case WriteBits:
|
||||||
|
OnModbusWriteBitsFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case WriteRegisters:
|
||||||
|
OnModbusWriteRegistersFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case MaskRegister:
|
||||||
|
OnModbusWriteMasksFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
case ReadWriteRegisters:
|
||||||
|
OnModbusReadWriteRegistersFailed(reqError, None, mbap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ variables
|
||||||
word Protocol;
|
word Protocol;
|
||||||
word Length;
|
word Length;
|
||||||
byte UnitID;
|
byte UnitID;
|
||||||
/*enum ModbusFuncCode*/ byte FuncCode;
|
byte FuncCode;
|
||||||
};
|
};
|
||||||
// Read Data from the host. We only need the start address and the number of bits/registers we want to read
|
// 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
|
_align(1) struct ModbusReqRead
|
||||||
|
@ -95,7 +95,7 @@ variables
|
||||||
{
|
{
|
||||||
struct ModbusApHeader Header;
|
struct ModbusApHeader Header;
|
||||||
byte ByteCount;
|
byte ByteCount;
|
||||||
word Data[gMaxRegsPerRead]; // Max length: 125 registers
|
word Data[gMaxRegsPerRead]; // Max length: 125 registers
|
||||||
};
|
};
|
||||||
// Confirm the write of a single bit/register
|
// Confirm the write of a single bit/register
|
||||||
_align(1) struct ModbusResConfirmSingle
|
_align(1) struct ModbusResConfirmSingle
|
||||||
|
@ -127,7 +127,8 @@ variables
|
||||||
{
|
{
|
||||||
Exception,
|
Exception,
|
||||||
Timeout,
|
Timeout,
|
||||||
FinalTimeout
|
FinalTimeout,
|
||||||
|
NotSent
|
||||||
};
|
};
|
||||||
enum ModbusException
|
enum ModbusException
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ NS_ :
|
||||||
|
|
||||||
BS_:
|
BS_:
|
||||||
|
|
||||||
BU_: Client_ Client_100 Client_101
|
BU_: Client_2 Client_3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue