Prefixed "private" functions with underscore
This commit is contained in:
parent
bf03b46d34
commit
b6f211d5d3
6 changed files with 230 additions and 173 deletions
|
@ -31,7 +31,7 @@ on start
|
||||||
DeviceInit(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::Vendor); // Set all device specific parameters (Wago / B&R)
|
DeviceInit(@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::Vendor); // Set all device specific parameters (Wago / B&R)
|
||||||
|
|
||||||
writeDbg(MbInfo, "Connecting to %s:%d", ip, @sysvar::Config::Modbus::Port);
|
writeDbg(MbInfo, "Connecting to %s:%d", ip, @sysvar::Config::Modbus::Port);
|
||||||
ModbusInit(ip, @sysvar::Config::Modbus::Port); // Connect to device. Opens socket and connection or what ever
|
ModbusInit(ip, @sysvar::Config::Modbus::Port); // 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
|
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
|
ModbusReadOutRegisters(gDevOutputRegAddrR, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters); // Read the start status of the output registers
|
||||||
|
|
|
@ -86,7 +86,7 @@ void DeviceInit(byte vendor)
|
||||||
// This function parses the received device code/module code received from the device and writes it to struct deviceIO.Modules.
|
// This function parses the received device code/module code received from the device and writes it to struct deviceIO.Modules.
|
||||||
// The quantity of IO does not have to be parsed here because it is extracted from extra registers
|
// The quantity of IO does not have to be parsed here because it is extracted from extra registers
|
||||||
/// <MakeConfig>
|
/// <MakeConfig>
|
||||||
void DeviceParseCode(word dev, enum Vendor vendor, struct deviceIOs dios)
|
void _DeviceParseCode(word dev, enum Vendor vendor, struct deviceIOs dios)
|
||||||
{
|
{
|
||||||
byte input;
|
byte input;
|
||||||
byte numChannels;
|
byte numChannels;
|
||||||
|
@ -207,7 +207,7 @@ void DeviceParseCode(word dev, enum Vendor vendor, struct deviceIOs dios)
|
||||||
// Requested information has to be: Count of AOs, AIs, DOs, DIs
|
// Requested information has to be: Count of AOs, AIs, DOs, DIs
|
||||||
// Additionaly information can be: Serial Code, Device/Product Code, Codes of connected modules
|
// Additionaly information can be: Serial Code, Device/Product Code, Codes of connected modules
|
||||||
/// <MakeConfig>
|
/// <MakeConfig>
|
||||||
byte DeviceGetInformation(enum Vendor vendor)
|
byte _DeviceGetInformation(enum Vendor vendor)
|
||||||
{
|
{
|
||||||
switch (vendor)
|
switch (vendor)
|
||||||
{
|
{
|
||||||
|
@ -240,7 +240,7 @@ byte DeviceGetInformation(enum Vendor vendor)
|
||||||
// This function parses the received registers (requested by DeviceGetInformation())
|
// This function parses the received registers (requested by DeviceGetInformation())
|
||||||
// It is called in the callback OnModbusReadRegistersSuccess() to fill the 'device' structure
|
// It is called in the callback OnModbusReadRegistersSuccess() to fill the 'device' structure
|
||||||
/// <MakeConfig>
|
/// <MakeConfig>
|
||||||
void DeviceParseRegister(struct device device, word address, word data[], word count)
|
void _DeviceParseRegister(struct device device, word address, word data[], word count)
|
||||||
{
|
{
|
||||||
byte i;
|
byte i;
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ void DeviceParseRegister(struct device device, word address, word data[], word c
|
||||||
{
|
{
|
||||||
if (data[i] == 0x0000) // No more devices --> end
|
if (data[i] == 0x0000) // No more devices --> end
|
||||||
break;
|
break;
|
||||||
DeviceParseCode(data[i], device.Vendor, device.DeviceIOs);
|
_DeviceParseCode(data[i], device.Vendor, device.DeviceIOs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,12 +76,12 @@ variables
|
||||||
// It has to be called by the user/modbus client at the beginning with IP and Port of the Modbus server
|
// It has to be called by the user/modbus client at the beginning with IP and Port of the Modbus server
|
||||||
void ModbusInit(char Remote_IP[], word remotePort)
|
void ModbusInit(char Remote_IP[], word remotePort)
|
||||||
{
|
{
|
||||||
ModbusConnectTo(ip, @sysvar::Config::Modbus::Port);
|
_ModbusConnectTo(Remote_IP, remotePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method fills the ModbusApHeader structure 'mbap'.
|
// This method fills the ModbusApHeader structure 'mbap'.
|
||||||
// It gets called by the Modbus request methods
|
// It gets called by the Modbus request methods
|
||||||
void ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode)
|
void _ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode)
|
||||||
{
|
{
|
||||||
mbap.TxID = gTxID++; // [2] Transaction ID
|
mbap.TxID = gTxID++; // [2] Transaction ID
|
||||||
mbap.Protocol = 0x0000; // [2] Protocol ID = 0 = Modbus
|
mbap.Protocol = 0x0000; // [2] Protocol ID = 0 = Modbus
|
||||||
|
@ -94,23 +94,26 @@ void ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode)
|
||||||
|
|
||||||
// REGION: ModbusReadBits -------------------------------------------------------------
|
// REGION: ModbusReadBits -------------------------------------------------------------
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
// This method will submit a request to the Modbus server to read
|
// This method will submit a request to the Modbus server to read discrete inputs
|
||||||
void ModbusReadInBits(word address, long count)
|
void ModbusReadInBits(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadBits(0x02, address, count);
|
_ModbusReadBits(0x02, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
|
// This method will submit a request to the Modbus server to read coils
|
||||||
void ModbusReadBits(word address, long count)
|
void ModbusReadBits(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadBits(0x02, address, count);
|
_ModbusReadBits(0x02, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
|
// This method will submit a request to the Modbus server to read coils
|
||||||
void ModbusReadOutBits(word address, long count)
|
void ModbusReadOutBits(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadBits(0x01, address, count);
|
_ModbusReadBits(0x01, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
void ModbusReadBits(byte funcCode, word address, long 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)
|
||||||
{
|
{
|
||||||
const byte length = __size_of(struct ModbusReqRead);
|
const byte length = __size_of(struct ModbusReqRead);
|
||||||
byte buffer[length];
|
byte buffer[length];
|
||||||
|
@ -121,7 +124,7 @@ void ModbusReadBits(byte funcCode, word address, long count)
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
curCount = count > gMaxBitsPerRead ? gMaxBitsPerRead : count;
|
curCount = count > gMaxBitsPerRead ? gMaxBitsPerRead : count;
|
||||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Start address
|
mbreq.Address = address; // [2] Start address
|
||||||
mbreq.Count = curCount; // [2] Number of items; 1:max 2000=0x7D0
|
mbreq.Count = curCount; // [2] Number of items; 1:max 2000=0x7D0
|
||||||
|
@ -129,7 +132,7 @@ void ModbusReadBits(byte funcCode, word address, long count)
|
||||||
writeDbg(MbDebug, "Sending 'Read Bits' (0x01) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address, curCount);
|
writeDbg(MbDebug, "Sending 'Read Bits' (0x01) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address, curCount);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||||
|
|
||||||
count -= gMaxBitsPerRead;
|
count -= gMaxBitsPerRead;
|
||||||
address += gMaxBitsPerRead;
|
address += gMaxBitsPerRead;
|
||||||
|
@ -137,7 +140,8 @@ void ModbusReadBits(byte funcCode, word address, long count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
void OnModbusReceiveBits(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when receiving data
|
||||||
|
void _OnModbusReceiveBits(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResReceiveBits mbres;
|
struct ModbusResReceiveBits mbres;
|
||||||
struct ModbusReqRead mbreq;
|
struct ModbusReqRead mbreq;
|
||||||
|
@ -161,7 +165,8 @@ void OnModbusReceiveBits(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadBits>
|
/// <ModbusReadBits>
|
||||||
void OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while reading bits: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while reading bits: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusReadBitsFailed(Exception, ex, mbap);
|
OnModbusReadBitsFailed(Exception, ex, mbap);
|
||||||
|
@ -173,22 +178,26 @@ void OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusExcepti
|
||||||
|
|
||||||
// REGION: ModbusReadRegisters -------------------------------------------------------
|
// REGION: ModbusReadRegisters -------------------------------------------------------
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
|
// This method will submit a request to the Modbus server to read input registers
|
||||||
void ModbusReadInRegisters(word address, long count)
|
void ModbusReadInRegisters(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadRegisters(0x04, address, count);
|
_ModbusReadRegisters(0x04, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
|
// This method will submit a request to the Modbus server to read holding registers
|
||||||
void ModbusReadRegisters(word address, long count)
|
void ModbusReadRegisters(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadRegisters(0x04, address, count);
|
_ModbusReadRegisters(0x04, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
|
// This method will submit a request to the Modbus server to read holding registers
|
||||||
void ModbusReadOutRegisters(word address, long count)
|
void ModbusReadOutRegisters(word address, long count)
|
||||||
{
|
{
|
||||||
ModbusReadRegisters(0x03, address, count);
|
_ModbusReadRegisters(0x03, address, count);
|
||||||
}
|
}
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
void ModbusReadRegisters(byte funcCode, word address, long 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)
|
||||||
{
|
{
|
||||||
const byte length = __size_of(struct ModbusReqRead);
|
const byte length = __size_of(struct ModbusReqRead);
|
||||||
byte buffer[length];
|
byte buffer[length];
|
||||||
|
@ -199,7 +208,7 @@ void ModbusReadRegisters(byte funcCode, word address, long count)
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
curCount = count > gMaxRegsPerRead ? gMaxRegsPerRead : count;
|
curCount = count > gMaxRegsPerRead ? gMaxRegsPerRead : count;
|
||||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Start address
|
mbreq.Address = address; // [2] Start address
|
||||||
mbreq.Count = curCount; // [2] Number of items; 1:max 125=0x7D
|
mbreq.Count = curCount; // [2] Number of items; 1:max 125=0x7D
|
||||||
|
@ -207,7 +216,7 @@ void ModbusReadRegisters(byte funcCode, word address, long count)
|
||||||
writeDbg(MbDebug, "Sending 'Read Registers' (0x03) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address, curCount);
|
writeDbg(MbDebug, "Sending 'Read Registers' (0x03) command. TxID: 0x%04X, Addr: 0x%04X, Count: %d", mbreq.Header.TxID, address, curCount);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||||
|
|
||||||
count -= gMaxRegsPerRead;
|
count -= gMaxRegsPerRead;
|
||||||
address += gMaxRegsPerRead;
|
address += gMaxRegsPerRead;
|
||||||
|
@ -215,7 +224,8 @@ void ModbusReadRegisters(byte funcCode, word address, long count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
void OnModbusReceiveRegisters(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when receiving data
|
||||||
|
void _OnModbusReceiveRegisters(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResReceiveRegisters mbres;
|
struct ModbusResReceiveRegisters mbres;
|
||||||
struct ModbusReqRead mbreq;
|
struct ModbusReqRead mbreq;
|
||||||
|
@ -229,7 +239,8 @@ void OnModbusReceiveRegisters(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadRegisters>
|
/// <ModbusReadRegisters>
|
||||||
void OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while reading registers: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while reading registers: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusReadRegistersFailed(Exception, ex, mbap);
|
OnModbusReadRegistersFailed(Exception, ex, mbap);
|
||||||
|
@ -241,6 +252,7 @@ void OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusEx
|
||||||
|
|
||||||
// REGION: ModbusWriteBit -------------------------------------------------------------
|
// REGION: ModbusWriteBit -------------------------------------------------------------
|
||||||
/// <ModbusWriteBit>
|
/// <ModbusWriteBit>
|
||||||
|
// This method will submit a request to the Modbus server to set a coil
|
||||||
void ModbusWriteBit(word address, byte value)
|
void ModbusWriteBit(word address, byte value)
|
||||||
{
|
{
|
||||||
const byte length = __size_of(struct ModbusReqWriteSingle);
|
const byte length = __size_of(struct ModbusReqWriteSingle);
|
||||||
|
@ -252,7 +264,7 @@ void ModbusWriteBit(word address, byte value)
|
||||||
value = 0xFF;
|
value = 0xFF;
|
||||||
|
|
||||||
// FC5: Write Single Coil (DO)
|
// FC5: Write Single Coil (DO)
|
||||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Output address
|
mbreq.Address = address; // [2] Output address
|
||||||
mbreq.Value = value << 8; // [2] Output value (0x0000: Off, 0xFF00: On)
|
mbreq.Value = value << 8; // [2] Output value (0x0000: Off, 0xFF00: On)
|
||||||
|
@ -260,11 +272,12 @@ void ModbusWriteBit(word address, byte value)
|
||||||
writeDbg(Debug, "Sending 'Write Bit' (0x05) command. TxID: 0x%04X, Addr: 0x%04X, Value: %d", mbreq.Header.TxID, address, value);
|
writeDbg(Debug, "Sending 'Write Bit' (0x05) command. TxID: 0x%04X, Addr: 0x%04X, Value: %d", mbreq.Header.TxID, address, value);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteBit>
|
/// <ModbusWriteBit>
|
||||||
void OnModbusConfirmBit(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusConfirmBit(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResConfirmSingle mbc;
|
struct ModbusResConfirmSingle mbc;
|
||||||
|
|
||||||
|
@ -276,7 +289,8 @@ void OnModbusConfirmBit(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteBit>
|
/// <ModbusWriteBit>
|
||||||
void OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while writing bit: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while writing bit: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteBitFailed(Exception, ex, mbap);
|
OnModbusWriteBitFailed(Exception, ex, mbap);
|
||||||
|
@ -286,8 +300,10 @@ void OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusExceptio
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// REGION: ModbusWriteRegister ------------------------------------------------------
|
// REGION: ModbusWriteRegister ------------------------------------------------------
|
||||||
/// <ModbusWriteRegister>
|
/// <ModbusWriteRegister>
|
||||||
|
// This method will submit a request to the Modbus server to a holding register
|
||||||
void ModbusWriteRegister(word address, word value)
|
void ModbusWriteRegister(word address, word value)
|
||||||
{
|
{
|
||||||
const byte length = __size_of(struct ModbusReqWriteSingle);
|
const byte length = __size_of(struct ModbusReqWriteSingle);
|
||||||
|
@ -296,7 +312,7 @@ void ModbusWriteRegister(word address, word value)
|
||||||
struct ModbusReqWriteSingle mbreq;
|
struct ModbusReqWriteSingle mbreq;
|
||||||
|
|
||||||
// 5: Write Single Register (AO)
|
// 5: Write Single Register (AO)
|
||||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Output address
|
mbreq.Address = address; // [2] Output address
|
||||||
mbreq.Value = value; // [2] Output value
|
mbreq.Value = value; // [2] Output value
|
||||||
|
@ -304,11 +320,12 @@ void ModbusWriteRegister(word address, word value)
|
||||||
writeDbg(MbDebug, "Sending 'Write Register' (0x06) command. TxID: 0x%04X, Addr: 0x%04X, Value: %d", mbreq.Header.TxID, address, value);
|
writeDbg(MbDebug, "Sending 'Write Register' (0x06) command. TxID: 0x%04X, Addr: 0x%04X, Value: %d", mbreq.Header.TxID, address, value);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteRegister>
|
/// <ModbusWriteRegister>
|
||||||
void OnModbusConfirmRegister(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusConfirmRegister(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResConfirmSingle mbc;
|
struct ModbusResConfirmSingle mbc;
|
||||||
|
|
||||||
|
@ -320,7 +337,8 @@ void OnModbusConfirmRegister(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteRegister>
|
/// <ModbusWriteRegister>
|
||||||
void OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while writing register: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while writing register: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteRegisterFailed(Exception, ex, mbap);
|
OnModbusWriteRegisterFailed(Exception, ex, mbap);
|
||||||
|
@ -334,6 +352,8 @@ void OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusExc
|
||||||
|
|
||||||
// REGION: ModbusWriteBits ----------------------------------------------------------
|
// REGION: ModbusWriteBits ----------------------------------------------------------
|
||||||
/// <ModbusWriteBits>
|
/// <ModbusWriteBits>
|
||||||
|
// This method will submit a request to the Modbus server to set several coils
|
||||||
|
// It will not encode the 'values'
|
||||||
void ModbusWriteBits(word address, long count, byte values[])
|
void ModbusWriteBits(word address, long count, byte values[])
|
||||||
{
|
{
|
||||||
const word maxLength = __size_of(struct ModbusReqWriteBits);
|
const word maxLength = __size_of(struct ModbusReqWriteBits);
|
||||||
|
@ -360,7 +380,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
dataLength = _ceil(curCount / 8.0);
|
dataLength = _ceil(curCount / 8.0);
|
||||||
overallLength = maxLength - gMaxBitsPerWrite/8 + dataLength;
|
overallLength = maxLength - gMaxBitsPerWrite/8 + dataLength;
|
||||||
}
|
}
|
||||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Output address
|
mbreq.Address = address; // [2] Output address
|
||||||
mbreq.Count = curCount; // [2] Number of items; 1:max 1968=0x7B0
|
mbreq.Count = curCount; // [2] Number of items; 1:max 1968=0x7B0
|
||||||
|
@ -370,7 +390,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. Addr: 0x%04X, Count: %d", address, curCount);
|
writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. Addr: 0x%04X, Count: %d", address, curCount);
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||||
|
|
||||||
count -= gMaxBitsPerWrite;
|
count -= gMaxBitsPerWrite;
|
||||||
address += gMaxBitsPerWrite;
|
address += gMaxBitsPerWrite;
|
||||||
|
@ -378,6 +398,9 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteBits>
|
/// <ModbusWriteBits>
|
||||||
|
// This method will submit a request to the Modbus server to set several coils
|
||||||
|
// It additionally encodes the bit 'values' to bytes. This means that 8 bytes of 'values' are stacked into one byte.
|
||||||
|
// Use this when you simply have 1s and 0s
|
||||||
void ModbusWriteBitsB(word address, long count, byte values[])
|
void ModbusWriteBitsB(word address, long count, byte values[])
|
||||||
{
|
{
|
||||||
byte buffer[gMaxBitsPerWrite/8]; // length
|
byte buffer[gMaxBitsPerWrite/8]; // length
|
||||||
|
@ -417,7 +440,8 @@ void ModbusWriteBitsB(word address, long count, byte values[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteBits>
|
/// <ModbusWriteBits>
|
||||||
void OnModbusConfirmBits(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusConfirmBits(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResConfirmMultiple mbc;
|
struct ModbusResConfirmMultiple mbc;
|
||||||
|
|
||||||
|
@ -429,7 +453,8 @@ void OnModbusConfirmBits(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteBits>
|
/// <ModbusWriteBits>
|
||||||
void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while writing bits: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while writing bits: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteBitsFailed(Exception, ex, mbap);
|
OnModbusWriteBitsFailed(Exception, ex, mbap);
|
||||||
|
@ -442,6 +467,7 @@ void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusExcepti
|
||||||
|
|
||||||
// REGION: ModbusWriteRegisters -------------------------------------------------------
|
// REGION: ModbusWriteRegisters -------------------------------------------------------
|
||||||
/// <ModbusWriteRegisters>
|
/// <ModbusWriteRegisters>
|
||||||
|
// This method will submit a request to the Modbus server to set several holding registers
|
||||||
void ModbusWriteRegisters(word address, long count, word values[])
|
void ModbusWriteRegisters(word address, long count, word values[])
|
||||||
{
|
{
|
||||||
const word maxLength = __size_of(struct ModbusReqWriteRegisters);
|
const word maxLength = __size_of(struct ModbusReqWriteRegisters);
|
||||||
|
@ -460,7 +486,7 @@ void ModbusWriteRegisters(word address, long count, word values[])
|
||||||
dataLength = 2 * curCount;
|
dataLength = 2 * curCount;
|
||||||
overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength;
|
overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength;
|
||||||
|
|
||||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Output address
|
mbreq.Address = address; // [2] Output address
|
||||||
mbreq.Count = curCount; // [2] Number of items; 1:max 123=0x7B
|
mbreq.Count = curCount; // [2] Number of items; 1:max 123=0x7B
|
||||||
|
@ -472,12 +498,13 @@ void ModbusWriteRegisters(word address, long count, word values[])
|
||||||
mbreq.Data[i] = 0;
|
mbreq.Data[i] = 0;
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteRegisters>
|
/// <ModbusWriteRegisters>
|
||||||
void OnModbusConfirmRegisters(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusConfirmRegisters(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResConfirmMultiple mbc;
|
struct ModbusResConfirmMultiple mbc;
|
||||||
|
|
||||||
|
@ -489,7 +516,8 @@ void OnModbusConfirmRegisters(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteRegisters>
|
/// <ModbusWriteRegisters>
|
||||||
void OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while writing registers: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while writing registers: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
||||||
|
@ -502,6 +530,7 @@ void OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusEx
|
||||||
|
|
||||||
// REGION: ModbusWriteMasks ------------------------------------------------------------
|
// REGION: ModbusWriteMasks ------------------------------------------------------------
|
||||||
/// <ModbusWriteMasks>
|
/// <ModbusWriteMasks>
|
||||||
|
// This method will submit a request to the Modbus server to mask a holding registers
|
||||||
void ModbusWriteMasks(word address, word and, word or)
|
void ModbusWriteMasks(word address, word and, word or)
|
||||||
{
|
{
|
||||||
const word length = __size_of(struct ModbusReqWriteMasks);
|
const word length = __size_of(struct ModbusReqWriteMasks);
|
||||||
|
@ -510,18 +539,19 @@ void ModbusWriteMasks(word address, word and, word or)
|
||||||
struct ModbusReqWriteMasks mbreq;
|
struct ModbusReqWriteMasks mbreq;
|
||||||
|
|
||||||
// FC22: Mask Write Registers (AO)
|
// FC22: Mask Write Registers (AO)
|
||||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||||
|
|
||||||
mbreq.Address = address; // [2] Output address
|
mbreq.Address = address; // [2] Output address
|
||||||
mbreq.And = and; // [2] AND mask
|
mbreq.And = and; // [2] AND mask
|
||||||
mbreq.Or = or; // [2] OR mask
|
mbreq.Or = or; // [2] OR mask
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteMasks>
|
/// <ModbusWriteMasks>
|
||||||
void OnModbusConfirmMasks(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusConfirmMasks(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResConfirmMasks mbc;
|
struct ModbusResConfirmMasks mbc;
|
||||||
|
|
||||||
|
@ -533,7 +563,8 @@ void OnModbusConfirmMasks(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusWriteMasks>
|
/// <ModbusWriteMasks>
|
||||||
void OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while applying masks: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while applying masks: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteMasksFailed(Exception, ex, mbap);
|
OnModbusWriteMasksFailed(Exception, ex, mbap);
|
||||||
|
@ -545,6 +576,7 @@ void OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusExcept
|
||||||
|
|
||||||
// REGION: ModbusReadWriteRegisters -------------------------------------------------------
|
// REGION: ModbusReadWriteRegisters -------------------------------------------------------
|
||||||
/// <ModbusReadWriteRegisters>
|
/// <ModbusReadWriteRegisters>
|
||||||
|
// This method will submit a request to the Modbus server to first set several holding registers and afterwards read (different) registers
|
||||||
void ModbusReadWriteRegisters(word readAddress, long readCount, word writeAddress, long writeCount, word values[])
|
void ModbusReadWriteRegisters(word readAddress, long readCount, word writeAddress, long writeCount, word values[])
|
||||||
{
|
{
|
||||||
const word maxLength = __size_of(struct ModbusReqReadWriteRegisters);
|
const word maxLength = __size_of(struct ModbusReqReadWriteRegisters);
|
||||||
|
@ -574,7 +606,7 @@ void ModbusReadWriteRegisters(word readAddress, long readCount, word writeAddres
|
||||||
overallLength = maxLength - 2*(gMaxRegsPerWrite-2) + dataLength;
|
overallLength = maxLength - 2*(gMaxRegsPerWrite-2) + dataLength;
|
||||||
|
|
||||||
// FC16: Write Multiple Registers (AOs)
|
// FC16: Write Multiple Registers (AOs)
|
||||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||||
|
|
||||||
mbreq.ReadAddress = readAddress; // [2] Input address
|
mbreq.ReadAddress = readAddress; // [2] Input address
|
||||||
mbreq.ReadCount = readCount; // [2] Number of items; 1:max 125=0x7D
|
mbreq.ReadCount = readCount; // [2] Number of items; 1:max 125=0x7D
|
||||||
|
@ -586,11 +618,12 @@ void ModbusReadWriteRegisters(word readAddress, long readCount, word writeAddres
|
||||||
mbreq.Data[i] = values[i + offset];
|
mbreq.Data[i] = values[i + offset];
|
||||||
|
|
||||||
memcpy_h2n(buffer, mbreq);
|
memcpy_h2n(buffer, mbreq);
|
||||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadWriteRegisters>
|
/// <ModbusReadWriteRegisters>
|
||||||
void OnModbusReceiveConfirmRegisters(byte buffer[])
|
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||||
|
void _OnModbusReceiveConfirmRegisters(byte buffer[])
|
||||||
{
|
{
|
||||||
struct ModbusResReceiveRegisters mbres;
|
struct ModbusResReceiveRegisters mbres;
|
||||||
struct ModbusReqRead mbreq;
|
struct ModbusReqRead mbreq;
|
||||||
|
@ -604,7 +637,8 @@ void OnModbusReceiveConfirmRegisters(byte buffer[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <ModbusReadWriteRegisters>
|
/// <ModbusReadWriteRegisters>
|
||||||
void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
// This method will be called by _OnModbusReceive2Exceptions() when an exception occured
|
||||||
|
void _OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex)
|
||||||
{
|
{
|
||||||
writeDbg(MbError, "Received an Exception while reading and writing registers: %s", ModbusExceptions[ex-1]);
|
writeDbg(MbError, "Received an Exception while reading and writing registers: %s", ModbusExceptions[ex-1]);
|
||||||
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
||||||
|
@ -619,7 +653,9 @@ void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum M
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// REGION: OnModbusReceive ------------------------------------------------------------
|
// REGION: OnModbusReceive ------------------------------------------------------------
|
||||||
/// <-OnModbusReceive>
|
/// <-OnModbusReceive>
|
||||||
void OnModbusReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
// This method parses the received data. It checks for network errors
|
||||||
|
// It gets called by the network layer (TCP, UDP, EIL) receive function (OnTcpReceive(),...)
|
||||||
|
void _OnModbusReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
||||||
{
|
{
|
||||||
writeDbg(ConnDebug, "OnModbusReceive: Received %d bytes", size);
|
writeDbg(ConnDebug, "OnModbusReceive: Received %d bytes", size);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
|
@ -628,24 +664,26 @@ void OnModbusReceive(dword socket, long result, dword address, dword port, byte
|
||||||
{
|
{
|
||||||
// Size of zero indicates that the socket was closed by the communication peer.
|
// Size of zero indicates that the socket was closed by the communication peer.
|
||||||
writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer");
|
writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer");
|
||||||
ModbusDisconnect();
|
_ModbusDisconnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sucessfully received some bytes over the TCP/IP connection.
|
// Sucessfully received some bytes over the TCP/IP connection.
|
||||||
OnModbusReceive2(buffer, size);
|
_OnModbusReceive2(buffer, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gIpLastErr = ModbusGetLastConnectionError(gIpLastErrStr);
|
gIpLastErr = _ModbusGetLastConnectionError(gIpLastErrStr);
|
||||||
writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr);
|
writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr);
|
||||||
ModbusDisconnect();
|
_ModbusDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <-OnModbusReceive>
|
/// <-OnModbusReceive>
|
||||||
void OnModbusReceive2(byte buffer[], dword size)
|
// This method continues with parsing the received data. It tries to separate several packets in the buffer
|
||||||
|
// It gets called by _OnModbusReceive()
|
||||||
|
void _OnModbusReceive2(byte buffer[], dword size)
|
||||||
{
|
{
|
||||||
struct ModbusApHeader mbap;
|
struct ModbusApHeader mbap;
|
||||||
long offset;
|
long offset;
|
||||||
|
@ -659,7 +697,7 @@ void OnModbusReceive2(byte buffer[], dword size)
|
||||||
{
|
{
|
||||||
writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset);
|
writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset);
|
||||||
memcpy_n2h(mbap, buffer, offset);
|
memcpy_n2h(mbap, buffer, offset);
|
||||||
OnModbusReceive2OnePacket(buffer, offset, mbap);
|
_OnModbusReceive2OnePacket(buffer, offset, mbap);
|
||||||
|
|
||||||
offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
|
offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
|
||||||
writeDbg(ConnDebug, "OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8);
|
writeDbg(ConnDebug, "OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8);
|
||||||
|
@ -676,13 +714,15 @@ void OnModbusReceive2(byte buffer[], dword size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <-OnModbusReceive>
|
/// <-OnModbusReceive>
|
||||||
void OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader mbap)
|
// This method continues with parsing the received packet.
|
||||||
|
// It checks whether it is a modbus packet and then hands it to _OnModbusReceive2Exceptions() or to the Success() function of the request
|
||||||
|
// It gets called by _OnModbusReceive2()
|
||||||
|
void _OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader mbap)
|
||||||
{
|
{
|
||||||
// Test transaction identifier?
|
// Test transaction identifier?
|
||||||
// Test unit/device identifier?
|
// Test unit/device identifier?
|
||||||
word i; // counter
|
word i; // counter
|
||||||
word length; // length of current packet
|
word length; // length of current packet
|
||||||
byte mbuffer[gModbusMaxTelegramSize]; // second buffer where we copy the message. This way the user won't overwrite other packages.
|
|
||||||
|
|
||||||
length = __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
|
length = __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
|
||||||
// We cannot check this properly anymore. We have to trust the TCP/UDP stack and the sender... *sigh*
|
// We cannot check this properly anymore. We have to trust the TCP/UDP stack and the sender... *sigh*
|
||||||
|
@ -708,95 +748,102 @@ void OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader
|
||||||
gQueueSent.Remove(mbap.TxID);
|
gQueueSent.Remove(mbap.TxID);
|
||||||
|
|
||||||
if (mbap.FuncCode > 0x80) // Oh no, we got a exception!
|
if (mbap.FuncCode > 0x80) // Oh no, we got a exception!
|
||||||
{
|
_OnModbusReceive2Exceptions(buffer[offset+08], mbap);
|
||||||
OnModbusReceive2Exceptions(buffer[offset+08], mbap);
|
else // Ok, everything is alright
|
||||||
|
_OnModbusReceive2Success(buffer, mbap);
|
||||||
gQueueAck.Remove(mbap.TxID); // Remove from acknowledge queue
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the message
|
|
||||||
memcpy_off(mbuffer, 0, buffer, offset, length);
|
|
||||||
|
|
||||||
// Let's give the PDU to the corresponding function
|
|
||||||
switch (mbap.FuncCode)
|
|
||||||
{
|
|
||||||
case 0x01:
|
|
||||||
case 0x02:
|
|
||||||
OnModbusReceiveBits(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
case 0x04:
|
|
||||||
OnModbusReceiveRegisters(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
OnModbusConfirmBit(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
OnModbusConfirmRegister(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x0F:
|
|
||||||
OnModbusConfirmBits(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x10:
|
|
||||||
OnModbusConfirmRegisters(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x16:
|
|
||||||
OnModbusConfirmMasks(mbuffer);
|
|
||||||
break;
|
|
||||||
case 0x17:
|
|
||||||
OnModbusReceiveConfirmRegisters(mbuffer);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
writeDbg(MbError, "OnModbusReceive2OnePacket: We received funcCode 0x%X!?", mbap.FuncCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
gQueueAck.Remove(mbap.TxID); // Remove from acknowledge queue
|
gQueueAck.Remove(mbap.TxID); // Remove from acknowledge queue
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <-OnModbusReceive>
|
/// <-OnModbusReceive>
|
||||||
void OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap)
|
// This method will hand the exception code to the correct Exception() function
|
||||||
|
// It gets called by _OnModbusReceive2OnePacket()
|
||||||
|
void _OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap)
|
||||||
{
|
{
|
||||||
enum ModbusException ex;
|
enum ModbusException ex;
|
||||||
ex = (enum ModbusException)exCode;
|
ex = (enum ModbusException)exCode;
|
||||||
|
|
||||||
switch (mbap.FuncCode)
|
switch (mbap.FuncCode)
|
||||||
{
|
{
|
||||||
case 0x81:
|
case 0x80+ReadBits1:
|
||||||
case 0x82:
|
case 0x80+ReadBits2:
|
||||||
OnModbusReceiveBitsException(mbap, ex);
|
_OnModbusReceiveBitsException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x83:
|
case 0x80+ReadRegisters1:
|
||||||
case 0x84:
|
case 0x80+ReadRegisters2:
|
||||||
OnModbusReceiveRegistersException(mbap, ex);
|
_OnModbusReceiveRegistersException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x85:
|
case 0x80+WriteBit:
|
||||||
OnModbusConfirmBitException(mbap, ex);
|
_OnModbusConfirmBitException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x86:
|
case 0x80+WriteRegister:
|
||||||
OnModbusConfirmRegisterException(mbap, ex);
|
_OnModbusConfirmRegisterException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x8F:
|
case 0x80+WriteBits:
|
||||||
OnModbusConfirmBitsException(mbap, ex);
|
_OnModbusConfirmBitsException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x90:
|
case 0x80+WriteRegisters:
|
||||||
OnModbusConfirmRegistersException(mbap, ex);
|
_OnModbusConfirmRegistersException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x96:
|
case 0x80+MaskRegister:
|
||||||
OnModbusConfirmMasksException(mbap, ex);
|
_OnModbusConfirmMasksException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
case 0x97:
|
case 0x80+ReadWriteRegisters:
|
||||||
OnModbusReceiveConfirmRegistersException(mbap, ex);
|
_OnModbusReceiveConfirmRegistersException(mbap, ex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <-OnModbusReceive>
|
||||||
|
// This method will hand the received data to the correct Success() function
|
||||||
|
// It gets called by _OnModbusReceive2OnePacket()
|
||||||
|
void _OnModbusReceive2Success(byte exCode, struct ModbusApHeader mbap)
|
||||||
|
{
|
||||||
|
byte mbuffer[gModbusMaxTelegramSize]; // second buffer where we copy the message. This way the user won't overwrite other packages.
|
||||||
|
// Copy the message
|
||||||
|
memcpy_off(mbuffer, 0, buffer, offset, length);
|
||||||
|
|
||||||
|
// Let's give the PDU to the corresponding function
|
||||||
|
switch (mbap.FuncCode)
|
||||||
|
{
|
||||||
|
case ReadBits1:
|
||||||
|
case ReadBits2:
|
||||||
|
_OnModbusReceiveBits(mbuffer);
|
||||||
|
break;
|
||||||
|
case ReadRegisters1:
|
||||||
|
case ReadRegisters2:
|
||||||
|
_OnModbusReceiveRegisters(mbuffer);
|
||||||
|
break;
|
||||||
|
case WriteBit:
|
||||||
|
_OnModbusConfirmBit(mbuffer);
|
||||||
|
break;
|
||||||
|
case WriteRegister:
|
||||||
|
_OnModbusConfirmRegister(mbuffer);
|
||||||
|
break;
|
||||||
|
case WriteBits:
|
||||||
|
_OnModbusConfirmBits(mbuffer);
|
||||||
|
break;
|
||||||
|
case WriteRegisters:
|
||||||
|
_OnModbusConfirmRegisters(mbuffer);
|
||||||
|
break;
|
||||||
|
case MaskRegister:
|
||||||
|
_OnModbusConfirmMasks(mbuffer);
|
||||||
|
break;
|
||||||
|
case ReadWriteRegisters:
|
||||||
|
_OnModbusReceiveConfirmRegisters(mbuffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
writeDbg(MbError, "OnModbusReceive2Success: We received funcCode 0x%X!?", mbap.FuncCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// REGION: ModbusSend -----------------------------------------------------------------
|
// REGION: ModbusSend -----------------------------------------------------------------
|
||||||
/// <-ModbusSend>
|
/// <-ModbusSend>
|
||||||
void ModbusSend(byte buffer[], word length, word TxID)
|
// This method will enqueue the data in gQueuePending and start gtModbusRobin if appropriate
|
||||||
|
// It will get called by the Modbus request functions
|
||||||
|
void _ModbusSend(byte buffer[], word length, word TxID)
|
||||||
{
|
{
|
||||||
struct QueueElement qe;
|
struct QueueElement qe;
|
||||||
|
|
||||||
|
@ -807,16 +854,22 @@ void ModbusSend(byte buffer[], word length, word TxID)
|
||||||
writeDbg(ConnDebug, "Appended packet 0x%04X to pending queue", TxID);
|
writeDbg(ConnDebug, "Appended packet 0x%04X to pending queue", TxID);
|
||||||
|
|
||||||
if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0 && gSocketState == OK) // start timer if connection established
|
if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0 && gSocketState == OK) // start timer if connection established
|
||||||
ModbusStartQueue();
|
_ModbusStartQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusStartQueue()
|
// This method will start the timer. Nothing special :)
|
||||||
|
// It is seperate because the network layer may want to start it when it delayed some messages (e.g. while waiting for an ARP response)
|
||||||
|
// It gets called by _ModbusSend() and OnEthReceivePacket() in ModbusEil.cin
|
||||||
|
void _ModbusStartQueue()
|
||||||
{
|
{
|
||||||
writeDbg(ConnDebug, "Starting Timer gtModbusRobin");
|
writeDbg(ConnDebug, "Starting Timer gtModbusRobin");
|
||||||
setTimerCyclic(gtModbusRobin, 1);
|
setTimerCyclic(gtModbusRobin, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <-ModbusSend>
|
/// <-ModbusSend>
|
||||||
|
// This timer will handle the pending and sent queues.
|
||||||
|
// The sent packets will be checked for timeouts (.TimeoutTicks) and may be resent
|
||||||
|
// The pending packets may be sent when there is free space in the sending window
|
||||||
on timer gtModbusRobin
|
on timer gtModbusRobin
|
||||||
{
|
{
|
||||||
struct ModbusApHeader mbap;
|
struct ModbusApHeader mbap;
|
||||||
|
@ -834,9 +887,9 @@ on timer gtModbusRobin
|
||||||
{
|
{
|
||||||
writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID);
|
writeDbg(ConnInfo, "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;
|
||||||
ModbusRecv();
|
_ModbusRecv();
|
||||||
}
|
}
|
||||||
else // we will NOT resend it
|
else // we will NOT resend it
|
||||||
{
|
{
|
||||||
|
@ -876,25 +929,28 @@ on timer gtModbusRobin
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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
|
||||||
for (long TxID : gQueuePending)
|
for (long TxID : gQueuePending)
|
||||||
{
|
{
|
||||||
if (gQueueSent.Size() >= gDevReceiveWindow) // Device cannot handle many messages at a time
|
if (gQueueSent.Size() >= gDevReceiveWindow) // Device cannot handle that many messages at a time
|
||||||
break;
|
break; // Wait for the next turn
|
||||||
|
|
||||||
|
// Now send the packet
|
||||||
// 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 || gSocketState != NULL)
|
// what was that thing with the socket state? Somehow it was neccessary...
|
||||||
|
if (_ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0 || gSocketState != NULL)
|
||||||
{
|
{
|
||||||
memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue
|
memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue
|
||||||
gQueuePending.Remove(TxID);
|
gQueuePending.Remove(TxID);
|
||||||
ModbusRecv();
|
_ModbusRecv(); // wait for new packets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0) // Stop timer to reduce latency of first packet
|
// Stop timer to reduce load and latency of first new packet
|
||||||
|
if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0)
|
||||||
{
|
{
|
||||||
writeDbg(ConnDebug, "Stopping Timer gtModbusRobin");
|
writeDbg(ConnDebug, "Stopping Timer gtModbusRobin");
|
||||||
this.Cancel();
|
this.Cancel();
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
// This file contains functions that abstract the Ethernet Interaction Layer
|
// This file contains functions that abstract the Ethernet Interaction Layer
|
||||||
/// It provides following methods
|
/// It provides following methods
|
||||||
/// - ModbusConnectTo() Prepare anything that sending works. Here: Create a new packet
|
/// - _ModbusConnectTo() Prepare anything that sending works. Here: Create a new packet
|
||||||
/// - ModbusDisconnect() Gracefully disconnect from the device. Here: Invalidate the existing packet
|
/// - _ModbusDisconnect() Gracefully disconnect from the device. Here: Invalidate the existing packet
|
||||||
/// - ModbusRecv() Receive data from the device. Here: Does nothing, receiving takes place automatically
|
/// - _ModbusRecv() Receive data from the device. Here: Does nothing, receiving takes place automatically
|
||||||
/// - ModbusSnd() Send data to the device. Here: Fills the packet with payload data and sends it
|
/// - _ModbusSnd() Send data to the device. Here: Fills the packet with payload data and sends it
|
||||||
/// - Some function that received packets
|
/// - Some function that receives packets and hands them to _OnModbusReceive()
|
||||||
|
|
||||||
includes
|
includes
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ variables
|
||||||
|
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// 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 Remote_IP
|
// Here: The method will create an ARP telegram to get the MAC address of the device with the specified Remote_IP
|
||||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
{
|
{
|
||||||
dword remoteIp;
|
dword remoteIp;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
}
|
}
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// 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
|
// Here: The method will create an ARP telegram to get the MAC address of the device with the specified remoteIp
|
||||||
word ModbusConnectTo(dword remoteIp, word remotePort)
|
word _ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
{
|
{
|
||||||
long error;
|
long error;
|
||||||
byte broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
byte broadcastMac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
@ -97,7 +97,7 @@ word ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
}
|
}
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
||||||
// Here: The method will be called after an ARP telegram was received and set up the EthernetIL packet.
|
// Here: The method will be called after an ARP telegram was received and set up the EthernetIL packet.
|
||||||
void ModbusConnectTo2()
|
void _ModbusConnectTo2()
|
||||||
{
|
{
|
||||||
gPacket = EthInitPacket("udp");
|
gPacket = EthInitPacket("udp");
|
||||||
if (gPacket == 0)
|
if (gPacket == 0)
|
||||||
|
@ -120,7 +120,7 @@ void ModbusConnectTo2()
|
||||||
|
|
||||||
// This method will gracefully disconnect from the remote device.
|
// This method will gracefully disconnect from the remote device.
|
||||||
// Here: The method will invalidate the packet 'gPacket'
|
// Here: The method will invalidate the packet 'gPacket'
|
||||||
void ModbusDisconnect()
|
void _ModbusDisconnect()
|
||||||
{
|
{
|
||||||
if (gPacket != 0)
|
if (gPacket != 0)
|
||||||
{
|
{
|
||||||
|
@ -132,13 +132,13 @@ void ModbusDisconnect()
|
||||||
|
|
||||||
// This method will wait for data from the remote device.
|
// This method will wait for data from the remote device.
|
||||||
// Here: Nothing has to be done, EthernetIL is waiting for packets all the time
|
// Here: Nothing has to be done, EthernetIL is waiting for packets all the time
|
||||||
void ModbusRecv()
|
void _ModbusRecv()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method will send the payload 'buffer' to the device.
|
// This method will send the payload 'buffer' to the device.
|
||||||
// Here: It fills the packet 'gPacket' and sends it
|
// Here: It fills the packet 'gPacket' and sends it
|
||||||
byte ModbusSnd(byte buffer[], word length)
|
byte _ModbusSnd(byte buffer[], word length)
|
||||||
{
|
{
|
||||||
char str[20*3];
|
char str[20*3];
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ byte ModbusSnd(byte buffer[], word length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This Method simply combines the two EthGetLastError functions
|
// This Method simply combines the two EthGetLastError functions
|
||||||
long ModbusGetLastConnectionError(char string[])
|
long _ModbusGetLastConnectionError(char string[])
|
||||||
{
|
{
|
||||||
EthGetLastErrorText(elCount(string), string);
|
EthGetLastErrorText(elCount(string), string);
|
||||||
return EthGetLastError();
|
return EthGetLastError();
|
||||||
|
@ -200,8 +200,8 @@ void OnEthReceivePacket(long channel, long dir, long packet)
|
||||||
{
|
{
|
||||||
gtModbusArp.Cancel();
|
gtModbusArp.Cancel();
|
||||||
writeDbg(ConnDebug, "Remote Mac: %02X:%02X:%02X:%02X:%02X:%02X", gRemoteMac[0], gRemoteMac[1], gRemoteMac[2], gRemoteMac[3], gRemoteMac[4], gRemoteMac[5]);
|
writeDbg(ConnDebug, "Remote Mac: %02X:%02X:%02X:%02X:%02X:%02X", gRemoteMac[0], gRemoteMac[1], gRemoteMac[2], gRemoteMac[3], gRemoteMac[4], gRemoteMac[5]);
|
||||||
ModbusConnectTo2(); // create the UDP package
|
_ModbusConnectTo2(); // create the UDP package
|
||||||
ModbusStartQueue();
|
_ModbusStartQueue();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +209,6 @@ void OnEthReceivePacket(long channel, long dir, long packet)
|
||||||
if (EthGetTokenInt(packet, "ipv4", "protocol") == 0x11 && EthGetTokenInt(packet, "ipv4", "source") == gRemoteIP) // if this is a UDP package from our server
|
if (EthGetTokenInt(packet, "ipv4", "protocol") == 0x11 && EthGetTokenInt(packet, "ipv4", "source") == gRemoteIP) // if this is a UDP package from our server
|
||||||
{
|
{
|
||||||
size = EthGetThisData(0, gModbusMaxTelegramSize, buffer);
|
size = EthGetThisData(0, gModbusMaxTelegramSize, buffer);
|
||||||
OnModbusReceive(0, 0, EthGetTokenInt(packet, "ipv4", "source"), gRemoteIP, buffer, size); // Hand to Modbus Layer
|
_OnModbusReceive(0, 0, EthGetTokenInt(packet, "ipv4", "source"), gRemoteIP, buffer, size); // Hand to Modbus Layer
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
// This file connected functions that abstract the UDP/IP API
|
// This file connected functions that abstract the UDP/IP API
|
||||||
/// It provides following methods
|
/// It provides following methods
|
||||||
/// - ModbusConnectTo() Prepare anything that sending works. Here: Open a TCP socket and connection
|
/// - _ModbusConnectTo() Prepare anything that sending works. Here: Open a TCP socket and connection
|
||||||
/// - ModbusDisconnect() Gracefully disconnect from the device. Here: Close the TCP connection and socket
|
/// - _ModbusDisconnect() Gracefully disconnect from the device. Here: Close the TCP connection and socket
|
||||||
/// - ModbusRecv() Receive data from the device. Here: Wait for a TCP packet on the connection
|
/// - _ModbusRecv() Receive data from the device. Here: Wait for a TCP packet on the connection
|
||||||
/// - ModbusSnd() Send data to the device. Here: Send a packet on the TCP connection
|
/// - _ModbusSnd() Send data to the device. Here: Send a packet on the TCP connection
|
||||||
|
/// - Some function that receives packets and hands them to _OnModbusReceive()
|
||||||
|
|
||||||
includes
|
includes
|
||||||
{
|
{
|
||||||
|
@ -19,7 +20,7 @@ variables
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method opens an TCP socket. It has to check for several errors.
|
// This method opens an TCP socket. It has to check for several errors.
|
||||||
word TcpOpenSocket()
|
word _TcpOpenSocket()
|
||||||
{
|
{
|
||||||
byte i;
|
byte i;
|
||||||
char errorText[200];
|
char errorText[200];
|
||||||
|
@ -51,7 +52,7 @@ word TcpOpenSocket()
|
||||||
|
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
||||||
// Here: The method will open a TCP socket and connect to the remote device
|
// Here: The method will open a TCP socket and connect to the remote device
|
||||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
{
|
{
|
||||||
dword remoteIp;
|
dword remoteIp;
|
||||||
|
|
||||||
|
@ -64,12 +65,12 @@ word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ModbusConnectTo(remoteIp, remotePort);
|
return _ModbusConnectTo(remoteIp, remotePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
||||||
// Here: The method will open a TCP socket and connect to the remote device
|
// Here: The method will open a TCP socket and connect to the remote device
|
||||||
word ModbusConnectTo(dword remoteIp, word remotePort)
|
word _ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
{
|
{
|
||||||
long fehler;
|
long fehler;
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ word ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
|
|
||||||
// This method will be called when TcpSocket.Connect() had to defer the result (and returned WSAEWOULDBLOCK).
|
// 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
|
// 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)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +130,7 @@ void OnTcpConnect(dword socket, long result)
|
||||||
|
|
||||||
// This method will gracefully disconnect from the remote device.
|
// This method will gracefully disconnect from the remote device.
|
||||||
// Here: Simply close the socket. This will also disconnect the remote device
|
// Here: Simply close the socket. This will also disconnect the remote device
|
||||||
void ModbusDisconnect()
|
void _ModbusDisconnect()
|
||||||
{
|
{
|
||||||
gSocket.Close();
|
gSocket.Close();
|
||||||
gSocketState = CLOSED;
|
gSocketState = CLOSED;
|
||||||
|
@ -137,7 +138,7 @@ void ModbusDisconnect()
|
||||||
|
|
||||||
// This method will check for data from the remote device.
|
// This method will check for data from the remote device.
|
||||||
// Here: Tell the API to check for new TCP telegrams. When data arrived OnTcpReceive() will be called by the API
|
// Here: Tell the API to check for new TCP telegrams. When data arrived OnTcpReceive() will be called by the API
|
||||||
void ModbusRecv()
|
void _ModbusRecv()
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -167,14 +168,14 @@ void ModbusRecv()
|
||||||
|
|
||||||
// This method will send the payload 'buffer' to the device.
|
// This method will send the payload 'buffer' to the device.
|
||||||
// Here: Call the appropriate API function
|
// Here: Call the appropriate API function
|
||||||
word ModbusSnd(byte buffer[], word length)
|
word _ModbusSnd(byte buffer[], word length)
|
||||||
{
|
{
|
||||||
char str[20*3];
|
char str[20*3];
|
||||||
|
|
||||||
switch (gSocketState)
|
switch (gSocketState)
|
||||||
{
|
{
|
||||||
case CLOSED: // If the connection is closed
|
case CLOSED: // If the connection is closed
|
||||||
ModbusConnectTo(gRemoteIP, gRemotePort); // Try to (re)connect
|
_ModbusConnectTo(gRemoteIP, gRemotePort); // Try to (re)connect
|
||||||
if (gSocketState != OK) // If this didn't work
|
if (gSocketState != OK) // If this didn't work
|
||||||
{
|
{
|
||||||
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
||||||
|
@ -209,7 +210,7 @@ word ModbusSnd(byte buffer[], word length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method simply combines the two EthGetLastError functions
|
// This method simply combines the two EthGetLastError functions
|
||||||
long ModbusGetLastConnectionError(char string[])
|
long _ModbusGetLastConnectionError(char string[])
|
||||||
{
|
{
|
||||||
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
||||||
return gSocket.GetLastSocketError();
|
return gSocket.GetLastSocketError();
|
||||||
|
@ -218,5 +219,5 @@ long ModbusGetLastConnectionError(char string[])
|
||||||
// This method receives telegrams (from the TCP/IP API). ModbusRecv() has to be called first
|
// This method receives telegrams (from the TCP/IP API). ModbusRecv() has to be called first
|
||||||
void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
void OnTcpReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
||||||
{
|
{
|
||||||
OnModbusReceive(socket, result, address, port, buffer, size); // Hand to Modbus layer
|
_OnModbusReceive(socket, result, address, port, buffer, size); // Hand to Modbus layer
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ variables
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method opens an UDP socket. It has to check for several errors.
|
// This method opens an UDP socket. It has to check for several errors.
|
||||||
word UdpOpenSocket()
|
word _UdpOpenSocket()
|
||||||
{
|
{
|
||||||
byte i;
|
byte i;
|
||||||
char errorText[200];
|
char errorText[200];
|
||||||
|
@ -51,7 +51,7 @@ word UdpOpenSocket()
|
||||||
|
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
||||||
// Here: The method will open a UDP socket and save the IP and Port in global variables so they can be used when sending
|
// Here: The method will open a UDP socket and save the IP and Port in global variables so they can be used when sending
|
||||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
{
|
{
|
||||||
dword remoteIp;
|
dword remoteIp;
|
||||||
|
|
||||||
|
@ -64,17 +64,17 @@ word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ModbusConnectTo(remoteIp, remotePort);
|
return _ModbusConnectTo(remoteIp, remotePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
// This method prepares anything in a way that sending with ModbusSnd() is possible.
|
||||||
// Here: The method will open a UDP socket and save the IP and Port in global variables so they can be used when sending
|
// Here: The method will open a UDP socket and save the IP and Port in global variables so they can be used when sending
|
||||||
word ModbusConnectTo(dword remoteIp, word remotePort)
|
word _ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
{
|
{
|
||||||
long fehler;
|
long fehler;
|
||||||
|
|
||||||
// Try to open a socket
|
// Try to open a socket
|
||||||
fehler = UdpOpenSocket();
|
fehler = _UdpOpenSocket();
|
||||||
if (fehler != 0)
|
if (fehler != 0)
|
||||||
{
|
{
|
||||||
gSocketState = ERROR;
|
gSocketState = ERROR;
|
||||||
|
@ -89,7 +89,7 @@ word ModbusConnectTo(dword remoteIp, word remotePort)
|
||||||
|
|
||||||
// This method will gracefully disconnect from the remote device.
|
// This method will gracefully disconnect from the remote device.
|
||||||
// Here: Simply close the socket
|
// Here: Simply close the socket
|
||||||
void ModbusDisconnect()
|
void _ModbusDisconnect()
|
||||||
{
|
{
|
||||||
gSocket.Close();
|
gSocket.Close();
|
||||||
gSocketState = CLOSED;
|
gSocketState = CLOSED;
|
||||||
|
@ -97,7 +97,7 @@ void ModbusDisconnect()
|
||||||
|
|
||||||
// This method will check for data from the remote device.
|
// This method will check for data from the remote device.
|
||||||
// Here: Tell the API to check for new UDP datagrams. When data arrived OnUdpReceiveFrom() will be called by the API
|
// Here: Tell the API to check for new UDP datagrams. When data arrived OnUdpReceiveFrom() will be called by the API
|
||||||
void ModbusRecv()
|
void _ModbusRecv()
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ void ModbusRecv()
|
||||||
{
|
{
|
||||||
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elCount(gIpLastErrStr));
|
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elCount(gIpLastErrStr));
|
||||||
writeDbg(ConnError, "UdpReceiveFrom: (%d) %s", gIpLastErr, gIpLastErrStr);
|
writeDbg(ConnError, "UdpReceiveFrom: (%d) %s", gIpLastErr, gIpLastErrStr);
|
||||||
ModbusDisconnect();
|
_ModbusDisconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,14 +127,14 @@ void ModbusRecv()
|
||||||
|
|
||||||
// This method will send the payload 'buffer' to the device.
|
// This method will send the payload 'buffer' to the device.
|
||||||
// Here: Call the appropriate API function
|
// Here: Call the appropriate API function
|
||||||
byte ModbusSnd(byte buffer[], word length)
|
byte _ModbusSnd(byte buffer[], word length)
|
||||||
{
|
{
|
||||||
char str[20*3];
|
char str[20*3];
|
||||||
|
|
||||||
switch (gSocketState)
|
switch (gSocketState)
|
||||||
{
|
{
|
||||||
case CLOSED: // If the connection is closed
|
case CLOSED: // If the connection is closed
|
||||||
ModbusConnectTo(gRemoteIP, gRemotePort); // Try to (re)connect
|
_ModbusConnectTo(gRemoteIP, gRemotePort); // Try to (re)connect
|
||||||
if (gSocketState != OK) // If this didn't work
|
if (gSocketState != OK) // If this didn't work
|
||||||
{
|
{
|
||||||
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
||||||
|
@ -160,7 +160,7 @@ byte ModbusSnd(byte buffer[], word length)
|
||||||
{
|
{
|
||||||
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
|
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
|
||||||
writeDbg(ConnError, "ModbusSnd error (%d): %s", gIpLastErr, gIpLastErrStr);
|
writeDbg(ConnError, "ModbusSnd error (%d): %s", gIpLastErr, gIpLastErrStr);
|
||||||
ModbusDisconnect();
|
_ModbusDisconnect();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// else: tough luck!
|
// else: tough luck!
|
||||||
|
@ -169,7 +169,7 @@ byte ModbusSnd(byte buffer[], word length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method simply combines the two EthGetLastError functions
|
// This method simply combines the two EthGetLastError functions
|
||||||
long ModbusGetLastConnectionError(char string[])
|
long _ModbusGetLastConnectionError(char string[])
|
||||||
{
|
{
|
||||||
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
||||||
return gSocket.GetLastSocketError();
|
return gSocket.GetLastSocketError();
|
||||||
|
@ -178,5 +178,5 @@ long ModbusGetLastConnectionError(char string[])
|
||||||
// This method receives datagrams (from the UDP/IP API). ModbusRecv() has to be called first
|
// This method receives datagrams (from the UDP/IP API). ModbusRecv() has to be called first
|
||||||
void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
void OnUdpReceiveFrom(dword socket, long result, dword address, dword port, byte buffer[], dword size)
|
||||||
{
|
{
|
||||||
OnModbusReceive(socket, result, address, port, buffer, size); // Hand to Modbus layer
|
_OnModbusReceive(socket, result, address, port, buffer, size); // Hand to Modbus layer
|
||||||
}
|
}
|
Loading…
Reference in a new issue