Prefixed "private" functions with underscore

This commit is contained in:
Jonny007-MKD 2014-07-04 10:59:58 +00:00
parent bf03b46d34
commit b6f211d5d3
6 changed files with 230 additions and 173 deletions

View file

@ -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;
} }

View file

@ -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();

View file

@ -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
} }
} }

View file

@ -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
} }

View file

@ -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
} }