Implemented checks in ModbusWriteRegisters so that the upper bound of process image is not exceeded.
This commit is contained in:
parent
608ec48e47
commit
2d26d89db0
1 changed files with 26 additions and 7 deletions
|
@ -441,7 +441,7 @@ void ModbusWriteBits(word address, long count, byte values[])
|
||||||
long offset;
|
long offset;
|
||||||
word devStartAddr, devEndAddr;
|
word devStartAddr, devEndAddr;
|
||||||
|
|
||||||
devStartAddr = funcCode == thisDev.Addr.Write.OutputBits; // The start address of the bits
|
devStartAddr = thisDev.Addr.Write.OutputBits; // The start address of the bits
|
||||||
devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit
|
devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit
|
||||||
if (address < devStartAddr) // Oh, reading at the wrong address?
|
if (address < devStartAddr) // Oh, reading at the wrong address?
|
||||||
{
|
{
|
||||||
|
@ -567,23 +567,42 @@ void ModbusWriteRegisters(word address, long count, word values[])
|
||||||
enum ModbusFuncCode funcCode = WriteRegisters;
|
enum ModbusFuncCode funcCode = WriteRegisters;
|
||||||
byte buffer[maxLength];
|
byte buffer[maxLength];
|
||||||
struct ModbusReqWriteRegisters mbreq;
|
struct ModbusReqWriteRegisters mbreq;
|
||||||
word curCount;
|
word overallLength, curCount, addressO;
|
||||||
byte dataLength;
|
byte dataLength;
|
||||||
word overallLength;
|
|
||||||
word i;
|
word i;
|
||||||
long offset;
|
long offset;
|
||||||
|
word devStartAddr, devEndAddr;
|
||||||
|
|
||||||
|
devStartAddr = thisDev.Addr.Write.OutputRegisters; // The start address of the bits
|
||||||
|
devEndAddr = devStartAddr + thisDev.MaxRegisterCount; // The address behind the last bit
|
||||||
|
if (address >= devEndAddr)
|
||||||
|
devEndAddr = 0xFFFF;
|
||||||
|
if (address < devStartAddr) // Oh, reading at the wrong address?
|
||||||
|
{
|
||||||
|
writeDbg(MbError, "ModbusWriteRegisters: The given start address 0x%04X is smaller than the obligatory start address 0x%04X", address, devStartAddr);
|
||||||
|
OnModbusClientPanics(AddressFailure);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// FC16: Write Multiple Registers (AOs)
|
// FC16: Write Multiple Registers (AOs)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
while (count > 0)
|
while (count > 0 && (address + offset) < devEndAddr)
|
||||||
{
|
{
|
||||||
|
addressO = address + offset;
|
||||||
curCount = count > gMaxRegsPerWrite ? gMaxRegsPerWrite : count;
|
curCount = count > gMaxRegsPerWrite ? gMaxRegsPerWrite : count;
|
||||||
|
|
||||||
|
if (addressO + curCount > devEndAddr) // upper bound in process image
|
||||||
|
{
|
||||||
|
writeDbg(MbWarning, "ModbusWriteRegisters: Impossible to write %d bits at 0x%04X. Changed count to %d.", curCount, addressO, devEndAddr - addressO);
|
||||||
|
curCount = devEndAddr - addressO;
|
||||||
|
}
|
||||||
|
|
||||||
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+offset; // [2] Output address
|
mbreq.Address = addressO; // [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
|
||||||
mbreq.ByteCount = dataLength; // [1] Number of bytes; = 2 * count
|
mbreq.ByteCount = dataLength; // [1] Number of bytes; = 2 * count
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue