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)
|
||||
|
||||
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
|
||||
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.
|
||||
// The quantity of IO does not have to be parsed here because it is extracted from extra registers
|
||||
/// <MakeConfig>
|
||||
void DeviceParseCode(word dev, enum Vendor vendor, struct deviceIOs dios)
|
||||
void _DeviceParseCode(word dev, enum Vendor vendor, struct deviceIOs dios)
|
||||
{
|
||||
byte input;
|
||||
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
|
||||
// Additionaly information can be: Serial Code, Device/Product Code, Codes of connected modules
|
||||
/// <MakeConfig>
|
||||
byte DeviceGetInformation(enum Vendor vendor)
|
||||
byte _DeviceGetInformation(enum Vendor vendor)
|
||||
{
|
||||
switch (vendor)
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ byte DeviceGetInformation(enum Vendor vendor)
|
|||
// This function parses the received registers (requested by DeviceGetInformation())
|
||||
// It is called in the callback OnModbusReadRegistersSuccess() to fill the 'device' structure
|
||||
/// <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;
|
||||
|
||||
|
@ -276,7 +276,7 @@ void DeviceParseRegister(struct device device, word address, word data[], word c
|
|||
{
|
||||
if (data[i] == 0x0000) // No more devices --> end
|
||||
break;
|
||||
DeviceParseCode(data[i], device.Vendor, device.DeviceIOs);
|
||||
_DeviceParseCode(data[i], device.Vendor, device.DeviceIOs);
|
||||
}
|
||||
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
|
||||
void ModbusInit(char Remote_IP[], word remotePort)
|
||||
{
|
||||
ModbusConnectTo(ip, @sysvar::Config::Modbus::Port);
|
||||
_ModbusConnectTo(Remote_IP, remotePort);
|
||||
}
|
||||
|
||||
// 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, byte funcCode)
|
||||
{
|
||||
mbap.TxID = gTxID++; // [2] Transaction ID
|
||||
mbap.Protocol = 0x0000; // [2] Protocol ID = 0 = Modbus
|
||||
|
@ -94,23 +94,26 @@ void ModbusMakeHeader(struct ModbusApHeader mbap, word length, byte funcCode)
|
|||
|
||||
// REGION: 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)
|
||||
{
|
||||
ModbusReadBits(0x02, address, count);
|
||||
_ModbusReadBits(0x02, address, count);
|
||||
}
|
||||
/// <ModbusReadBits>
|
||||
// This method will submit a request to the Modbus server to read coils
|
||||
void ModbusReadBits(word address, long count)
|
||||
{
|
||||
ModbusReadBits(0x02, address, count);
|
||||
_ModbusReadBits(0x02, address, count);
|
||||
}
|
||||
/// <ModbusReadBits>
|
||||
// This method will submit a request to the Modbus server to read coils
|
||||
void ModbusReadOutBits(word address, long count)
|
||||
{
|
||||
ModbusReadBits(0x01, address, count);
|
||||
_ModbusReadBits(0x01, address, count);
|
||||
}
|
||||
/// <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);
|
||||
byte buffer[length];
|
||||
|
@ -121,7 +124,7 @@ void ModbusReadBits(byte funcCode, word address, long count)
|
|||
while (count > 0)
|
||||
{
|
||||
curCount = count > gMaxBitsPerRead ? gMaxBitsPerRead : count;
|
||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Start address
|
||||
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);
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
|
||||
count -= gMaxBitsPerRead;
|
||||
address += gMaxBitsPerRead;
|
||||
|
@ -137,7 +140,8 @@ void ModbusReadBits(byte funcCode, word address, long count)
|
|||
}
|
||||
|
||||
/// <ModbusReadBits>
|
||||
void OnModbusReceiveBits(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when receiving data
|
||||
void _OnModbusReceiveBits(byte buffer[])
|
||||
{
|
||||
struct ModbusResReceiveBits mbres;
|
||||
struct ModbusReqRead mbreq;
|
||||
|
@ -161,7 +165,8 @@ void OnModbusReceiveBits(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusReadBitsFailed(Exception, ex, mbap);
|
||||
|
@ -173,22 +178,26 @@ void OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusExcepti
|
|||
|
||||
// REGION: ModbusReadRegisters -------------------------------------------------------
|
||||
/// <ModbusReadRegisters>
|
||||
// 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(0x04, address, count);
|
||||
}
|
||||
/// <ModbusReadRegisters>
|
||||
// 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(0x04, address, count);
|
||||
}
|
||||
/// <ModbusReadRegisters>
|
||||
// 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(0x03, address, count);
|
||||
}
|
||||
/// <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);
|
||||
byte buffer[length];
|
||||
|
@ -199,7 +208,7 @@ void ModbusReadRegisters(byte funcCode, word address, long count)
|
|||
while (count > 0)
|
||||
{
|
||||
curCount = count > gMaxRegsPerRead ? gMaxRegsPerRead : count;
|
||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Start address
|
||||
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);
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
|
||||
count -= gMaxRegsPerRead;
|
||||
address += gMaxRegsPerRead;
|
||||
|
@ -215,7 +224,8 @@ void ModbusReadRegisters(byte funcCode, word address, long count)
|
|||
}
|
||||
|
||||
/// <ModbusReadRegisters>
|
||||
void OnModbusReceiveRegisters(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when receiving data
|
||||
void _OnModbusReceiveRegisters(byte buffer[])
|
||||
{
|
||||
struct ModbusResReceiveRegisters mbres;
|
||||
struct ModbusReqRead mbreq;
|
||||
|
@ -229,7 +239,8 @@ void OnModbusReceiveRegisters(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusReadRegistersFailed(Exception, ex, mbap);
|
||||
|
@ -241,6 +252,7 @@ void OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusEx
|
|||
|
||||
// REGION: ModbusWriteBit -------------------------------------------------------------
|
||||
/// <ModbusWriteBit>
|
||||
// This method will submit a request to the Modbus server to set a coil
|
||||
void ModbusWriteBit(word address, byte value)
|
||||
{
|
||||
const byte length = __size_of(struct ModbusReqWriteSingle);
|
||||
|
@ -252,7 +264,7 @@ void ModbusWriteBit(word address, byte value)
|
|||
value = 0xFF;
|
||||
|
||||
// FC5: Write Single Coil (DO)
|
||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Output address
|
||||
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);
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
}
|
||||
|
||||
/// <ModbusWriteBit>
|
||||
void OnModbusConfirmBit(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusConfirmBit(byte buffer[])
|
||||
{
|
||||
struct ModbusResConfirmSingle mbc;
|
||||
|
||||
|
@ -276,7 +289,8 @@ void OnModbusConfirmBit(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteBitFailed(Exception, ex, mbap);
|
||||
|
@ -286,8 +300,10 @@ void OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusExceptio
|
|||
|
||||
|
||||
|
||||
|
||||
// REGION: ModbusWriteRegister ------------------------------------------------------
|
||||
/// <ModbusWriteRegister>
|
||||
// This method will submit a request to the Modbus server to a holding register
|
||||
void ModbusWriteRegister(word address, word value)
|
||||
{
|
||||
const byte length = __size_of(struct ModbusReqWriteSingle);
|
||||
|
@ -296,7 +312,7 @@ void ModbusWriteRegister(word address, word value)
|
|||
struct ModbusReqWriteSingle mbreq;
|
||||
|
||||
// 5: Write Single Register (AO)
|
||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Output address
|
||||
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);
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
}
|
||||
|
||||
/// <ModbusWriteRegister>
|
||||
void OnModbusConfirmRegister(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusConfirmRegister(byte buffer[])
|
||||
{
|
||||
struct ModbusResConfirmSingle mbc;
|
||||
|
||||
|
@ -320,7 +337,8 @@ void OnModbusConfirmRegister(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteRegisterFailed(Exception, ex, mbap);
|
||||
|
@ -334,6 +352,8 @@ void OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusExc
|
|||
|
||||
// REGION: 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[])
|
||||
{
|
||||
const word maxLength = __size_of(struct ModbusReqWriteBits);
|
||||
|
@ -360,7 +380,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
|||
dataLength = _ceil(curCount / 8.0);
|
||||
overallLength = maxLength - gMaxBitsPerWrite/8 + dataLength;
|
||||
}
|
||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Output address
|
||||
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);
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
|
||||
count -= gMaxBitsPerWrite;
|
||||
address += gMaxBitsPerWrite;
|
||||
|
@ -378,6 +398,9 @@ void ModbusWriteBits(word address, long count, byte values[])
|
|||
}
|
||||
|
||||
/// <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[])
|
||||
{
|
||||
byte buffer[gMaxBitsPerWrite/8]; // length
|
||||
|
@ -417,7 +440,8 @@ void ModbusWriteBitsB(word address, long count, byte values[])
|
|||
}
|
||||
|
||||
/// <ModbusWriteBits>
|
||||
void OnModbusConfirmBits(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusConfirmBits(byte buffer[])
|
||||
{
|
||||
struct ModbusResConfirmMultiple mbc;
|
||||
|
||||
|
@ -429,7 +453,8 @@ void OnModbusConfirmBits(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteBitsFailed(Exception, ex, mbap);
|
||||
|
@ -442,6 +467,7 @@ void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusExcepti
|
|||
|
||||
// REGION: 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[])
|
||||
{
|
||||
const word maxLength = __size_of(struct ModbusReqWriteRegisters);
|
||||
|
@ -460,7 +486,7 @@ void ModbusWriteRegisters(word address, long count, word values[])
|
|||
dataLength = 2 * curCount;
|
||||
overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength;
|
||||
|
||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Output address
|
||||
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;
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <ModbusWriteRegisters>
|
||||
void OnModbusConfirmRegisters(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusConfirmRegisters(byte buffer[])
|
||||
{
|
||||
struct ModbusResConfirmMultiple mbc;
|
||||
|
||||
|
@ -489,7 +516,8 @@ void OnModbusConfirmRegisters(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
||||
|
@ -502,6 +530,7 @@ void OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusEx
|
|||
|
||||
// REGION: 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)
|
||||
{
|
||||
const word length = __size_of(struct ModbusReqWriteMasks);
|
||||
|
@ -510,18 +539,19 @@ void ModbusWriteMasks(word address, word and, word or)
|
|||
struct ModbusReqWriteMasks mbreq;
|
||||
|
||||
// FC22: Mask Write Registers (AO)
|
||||
ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, length, funcCode);
|
||||
|
||||
mbreq.Address = address; // [2] Output address
|
||||
mbreq.And = and; // [2] AND mask
|
||||
mbreq.Or = or; // [2] OR mask
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, length, mbreq.Header.TxID);
|
||||
}
|
||||
|
||||
/// <ModbusWriteMasks>
|
||||
void OnModbusConfirmMasks(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusConfirmMasks(byte buffer[])
|
||||
{
|
||||
struct ModbusResConfirmMasks mbc;
|
||||
|
||||
|
@ -533,7 +563,8 @@ void OnModbusConfirmMasks(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteMasksFailed(Exception, ex, mbap);
|
||||
|
@ -545,6 +576,7 @@ void OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusExcept
|
|||
|
||||
// REGION: 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[])
|
||||
{
|
||||
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;
|
||||
|
||||
// FC16: Write Multiple Registers (AOs)
|
||||
ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
|
||||
|
||||
mbreq.ReadAddress = readAddress; // [2] Input address
|
||||
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];
|
||||
|
||||
memcpy_h2n(buffer, mbreq);
|
||||
ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
_ModbusSend(buffer, overallLength, mbreq.Header.TxID);
|
||||
}
|
||||
|
||||
/// <ModbusReadWriteRegisters>
|
||||
void OnModbusReceiveConfirmRegisters(byte buffer[])
|
||||
// This method will be called by _OnModbusReceive2OnePacket() when confirming the request
|
||||
void _OnModbusReceiveConfirmRegisters(byte buffer[])
|
||||
{
|
||||
struct ModbusResReceiveRegisters mbres;
|
||||
struct ModbusReqRead mbreq;
|
||||
|
@ -604,7 +637,8 @@ void OnModbusReceiveConfirmRegisters(byte buffer[])
|
|||
}
|
||||
|
||||
/// <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]);
|
||||
OnModbusWriteRegistersFailed(Exception, ex, mbap);
|
||||
|
@ -619,7 +653,9 @@ void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum M
|
|||
// ------------------------------------------------------------------------------------
|
||||
// REGION: 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);
|
||||
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.
|
||||
writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer");
|
||||
ModbusDisconnect();
|
||||
_ModbusDisconnect();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sucessfully received some bytes over the TCP/IP connection.
|
||||
OnModbusReceive2(buffer, size);
|
||||
_OnModbusReceive2(buffer, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gIpLastErr = ModbusGetLastConnectionError(gIpLastErrStr);
|
||||
gIpLastErr = _ModbusGetLastConnectionError(gIpLastErrStr);
|
||||
writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr);
|
||||
ModbusDisconnect();
|
||||
_ModbusDisconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/// <-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;
|
||||
long offset;
|
||||
|
@ -659,7 +697,7 @@ void OnModbusReceive2(byte buffer[], dword size)
|
|||
{
|
||||
writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset);
|
||||
memcpy_n2h(mbap, buffer, offset);
|
||||
OnModbusReceive2OnePacket(buffer, offset, mbap);
|
||||
_OnModbusReceive2OnePacket(buffer, offset, mbap);
|
||||
|
||||
offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length;
|
||||
writeDbg(ConnDebug, "OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8);
|
||||
|
@ -676,13 +714,15 @@ void OnModbusReceive2(byte buffer[], dword size)
|
|||
}
|
||||
|
||||
/// <-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 unit/device identifier?
|
||||
word i; // counter
|
||||
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;
|
||||
// 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);
|
||||
|
||||
if (mbap.FuncCode > 0x80) // Oh no, we got a exception!
|
||||
{
|
||||
OnModbusReceive2Exceptions(buffer[offset+08], 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);
|
||||
}
|
||||
_OnModbusReceive2Exceptions(buffer[offset+08], mbap);
|
||||
else // Ok, everything is alright
|
||||
_OnModbusReceive2Success(buffer, mbap);
|
||||
|
||||
gQueueAck.Remove(mbap.TxID); // Remove from acknowledge queue
|
||||
}
|
||||
|
||||
/// <-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;
|
||||
ex = (enum ModbusException)exCode;
|
||||
|
||||
switch (mbap.FuncCode)
|
||||
{
|
||||
case 0x81:
|
||||
case 0x82:
|
||||
OnModbusReceiveBitsException(mbap, ex);
|
||||
case 0x80+ReadBits1:
|
||||
case 0x80+ReadBits2:
|
||||
_OnModbusReceiveBitsException(mbap, ex);
|
||||
break;
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
OnModbusReceiveRegistersException(mbap, ex);
|
||||
case 0x80+ReadRegisters1:
|
||||
case 0x80+ReadRegisters2:
|
||||
_OnModbusReceiveRegistersException(mbap, ex);
|
||||
break;
|
||||
case 0x85:
|
||||
OnModbusConfirmBitException(mbap, ex);
|
||||
case 0x80+WriteBit:
|
||||
_OnModbusConfirmBitException(mbap, ex);
|
||||
break;
|
||||
case 0x86:
|
||||
OnModbusConfirmRegisterException(mbap, ex);
|
||||
case 0x80+WriteRegister:
|
||||
_OnModbusConfirmRegisterException(mbap, ex);
|
||||
break;
|
||||
case 0x8F:
|
||||
OnModbusConfirmBitsException(mbap, ex);
|
||||
case 0x80+WriteBits:
|
||||
_OnModbusConfirmBitsException(mbap, ex);
|
||||
break;
|
||||
case 0x90:
|
||||
OnModbusConfirmRegistersException(mbap, ex);
|
||||
case 0x80+WriteRegisters:
|
||||
_OnModbusConfirmRegistersException(mbap, ex);
|
||||
break;
|
||||
case 0x96:
|
||||
OnModbusConfirmMasksException(mbap, ex);
|
||||
case 0x80+MaskRegister:
|
||||
_OnModbusConfirmMasksException(mbap, ex);
|
||||
break;
|
||||
case 0x97:
|
||||
OnModbusReceiveConfirmRegistersException(mbap, ex);
|
||||
case 0x80+ReadWriteRegisters:
|
||||
_OnModbusReceiveConfirmRegistersException(mbap, ex);
|
||||
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 -----------------------------------------------------------------
|
||||
/// <-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;
|
||||
|
||||
|
@ -807,16 +854,22 @@ void ModbusSend(byte buffer[], word length, word 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
|
||||
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");
|
||||
setTimerCyclic(gtModbusRobin, 1);
|
||||
}
|
||||
|
||||
/// <-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
|
||||
{
|
||||
struct ModbusApHeader mbap;
|
||||
|
@ -834,9 +887,9 @@ on timer gtModbusRobin
|
|||
{
|
||||
writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID);
|
||||
gQueueSent[TxID].TimeoutTicks = 0;
|
||||
ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it
|
||||
_ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it
|
||||
reqError = Timeout;
|
||||
ModbusRecv();
|
||||
_ModbusRecv();
|
||||
}
|
||||
else // we will NOT resend it
|
||||
{
|
||||
|
@ -876,25 +929,28 @@ on timer gtModbusRobin
|
|||
}
|
||||
|
||||
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
|
||||
for (long TxID : gQueuePending)
|
||||
{
|
||||
if (gQueueSent.Size() >= gDevReceiveWindow) // Device cannot handle many messages at a time
|
||||
break;
|
||||
if (gQueueSent.Size() >= gDevReceiveWindow) // 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
|
||||
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
|
||||
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");
|
||||
this.Cancel();
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
// This file contains functions that abstract the Ethernet Interaction Layer
|
||||
/// It provides following methods
|
||||
/// - ModbusConnectTo() Prepare anything that sending works. Here: Create a new 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
|
||||
/// - ModbusSnd() Send data to the device. Here: Fills the packet with payload data and sends it
|
||||
/// - Some function that received packets
|
||||
/// - _ModbusConnectTo() Prepare anything that sending works. Here: Create a new 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
|
||||
/// - _ModbusSnd() Send data to the device. Here: Fills the packet with payload data and sends it
|
||||
/// - Some function that receives packets and hands them to _OnModbusReceive()
|
||||
|
||||
includes
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ variables
|
|||
|
||||
// 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
|
||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
{
|
||||
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.
|
||||
// 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;
|
||||
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.
|
||||
// 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");
|
||||
if (gPacket == 0)
|
||||
|
@ -120,7 +120,7 @@ void ModbusConnectTo2()
|
|||
|
||||
// This method will gracefully disconnect from the remote device.
|
||||
// Here: The method will invalidate the packet 'gPacket'
|
||||
void ModbusDisconnect()
|
||||
void _ModbusDisconnect()
|
||||
{
|
||||
if (gPacket != 0)
|
||||
{
|
||||
|
@ -132,13 +132,13 @@ void ModbusDisconnect()
|
|||
|
||||
// This method will wait for data from the remote device.
|
||||
// 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.
|
||||
// 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];
|
||||
|
||||
|
@ -171,7 +171,7 @@ byte ModbusSnd(byte buffer[], word length)
|
|||
}
|
||||
|
||||
// This Method simply combines the two EthGetLastError functions
|
||||
long ModbusGetLastConnectionError(char string[])
|
||||
long _ModbusGetLastConnectionError(char string[])
|
||||
{
|
||||
EthGetLastErrorText(elCount(string), string);
|
||||
return EthGetLastError();
|
||||
|
@ -200,8 +200,8 @@ void OnEthReceivePacket(long channel, long dir, long packet)
|
|||
{
|
||||
gtModbusArp.Cancel();
|
||||
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
|
||||
ModbusStartQueue();
|
||||
_ModbusConnectTo2(); // create the UDP package
|
||||
_ModbusStartQueue();
|
||||
}
|
||||
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
|
||||
{
|
||||
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
|
||||
/// It provides following methods
|
||||
/// - 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
|
||||
/// - 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
|
||||
/// - _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
|
||||
/// - _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
|
||||
/// - Some function that receives packets and hands them to _OnModbusReceive()
|
||||
|
||||
includes
|
||||
{
|
||||
|
@ -19,7 +20,7 @@ variables
|
|||
}
|
||||
|
||||
// This method opens an TCP socket. It has to check for several errors.
|
||||
word TcpOpenSocket()
|
||||
word _TcpOpenSocket()
|
||||
{
|
||||
byte i;
|
||||
char errorText[200];
|
||||
|
@ -51,7 +52,7 @@ word TcpOpenSocket()
|
|||
|
||||
// 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
|
||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
{
|
||||
dword remoteIp;
|
||||
|
||||
|
@ -64,12 +65,12 @@ word ModbusConnectTo(char Remote_IP[], word remotePort)
|
|||
return 1;
|
||||
}
|
||||
|
||||
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 open a TCP socket and connect to the remote device
|
||||
word ModbusConnectTo(dword remoteIp, word remotePort)
|
||||
word _ModbusConnectTo(dword remoteIp, word remotePort)
|
||||
{
|
||||
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).
|
||||
// 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)
|
||||
{
|
||||
|
@ -129,7 +130,7 @@ void OnTcpConnect(dword socket, long result)
|
|||
|
||||
// This method will gracefully disconnect from the remote device.
|
||||
// Here: Simply close the socket. This will also disconnect the remote device
|
||||
void ModbusDisconnect()
|
||||
void _ModbusDisconnect()
|
||||
{
|
||||
gSocket.Close();
|
||||
gSocketState = CLOSED;
|
||||
|
@ -137,7 +138,7 @@ void ModbusDisconnect()
|
|||
|
||||
// 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
|
||||
void ModbusRecv()
|
||||
void _ModbusRecv()
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -167,14 +168,14 @@ void ModbusRecv()
|
|||
|
||||
// This method will send the payload 'buffer' to the device.
|
||||
// Here: Call the appropriate API function
|
||||
word ModbusSnd(byte buffer[], word length)
|
||||
word _ModbusSnd(byte buffer[], word length)
|
||||
{
|
||||
char str[20*3];
|
||||
|
||||
switch (gSocketState)
|
||||
{
|
||||
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
|
||||
{
|
||||
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
||||
|
@ -209,7 +210,7 @@ word ModbusSnd(byte buffer[], word length)
|
|||
}
|
||||
|
||||
// This method simply combines the two EthGetLastError functions
|
||||
long ModbusGetLastConnectionError(char string[])
|
||||
long _ModbusGetLastConnectionError(char string[])
|
||||
{
|
||||
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
||||
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
|
||||
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.
|
||||
word UdpOpenSocket()
|
||||
word _UdpOpenSocket()
|
||||
{
|
||||
byte i;
|
||||
char errorText[200];
|
||||
|
@ -51,7 +51,7 @@ word UdpOpenSocket()
|
|||
|
||||
// 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
|
||||
word ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
word _ModbusConnectTo(char Remote_IP[], word remotePort)
|
||||
{
|
||||
dword remoteIp;
|
||||
|
||||
|
@ -64,17 +64,17 @@ word ModbusConnectTo(char Remote_IP[], word remotePort)
|
|||
return 1;
|
||||
}
|
||||
|
||||
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 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;
|
||||
|
||||
// Try to open a socket
|
||||
fehler = UdpOpenSocket();
|
||||
fehler = _UdpOpenSocket();
|
||||
if (fehler != 0)
|
||||
{
|
||||
gSocketState = ERROR;
|
||||
|
@ -89,7 +89,7 @@ word ModbusConnectTo(dword remoteIp, word remotePort)
|
|||
|
||||
// This method will gracefully disconnect from the remote device.
|
||||
// Here: Simply close the socket
|
||||
void ModbusDisconnect()
|
||||
void _ModbusDisconnect()
|
||||
{
|
||||
gSocket.Close();
|
||||
gSocketState = CLOSED;
|
||||
|
@ -97,7 +97,7 @@ void ModbusDisconnect()
|
|||
|
||||
// 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
|
||||
void ModbusRecv()
|
||||
void _ModbusRecv()
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -118,7 +118,7 @@ void ModbusRecv()
|
|||
{
|
||||
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elCount(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.
|
||||
// Here: Call the appropriate API function
|
||||
byte ModbusSnd(byte buffer[], word length)
|
||||
byte _ModbusSnd(byte buffer[], word length)
|
||||
{
|
||||
char str[20*3];
|
||||
|
||||
switch (gSocketState)
|
||||
{
|
||||
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
|
||||
{
|
||||
writeDbg(ConnError, "ModbusSnd: Reconnecting failed!");
|
||||
|
@ -160,7 +160,7 @@ byte ModbusSnd(byte buffer[], word length)
|
|||
{
|
||||
gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr));
|
||||
writeDbg(ConnError, "ModbusSnd error (%d): %s", gIpLastErr, gIpLastErrStr);
|
||||
ModbusDisconnect();
|
||||
_ModbusDisconnect();
|
||||
return 1;
|
||||
}
|
||||
// else: tough luck!
|
||||
|
@ -169,7 +169,7 @@ byte ModbusSnd(byte buffer[], word length)
|
|||
}
|
||||
|
||||
// This method simply combines the two EthGetLastError functions
|
||||
long ModbusGetLastConnectionError(char string[])
|
||||
long _ModbusGetLastConnectionError(char string[])
|
||||
{
|
||||
gSocket.GetLastSocketErrorAsString(string, elCount(string));
|
||||
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
|
||||
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