Commit 4881c356 authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusSlave): исправлена ошибка обработки запросов на запись нескольких регистров

parent e58ccc56
...@@ -1215,7 +1215,7 @@ std::ostream& operator<<( std::ostream& os, MBSlave::BitRegProperty& p ) ...@@ -1215,7 +1215,7 @@ std::ostream& operator<<( std::ostream& os, MBSlave::BitRegProperty& p )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, MBSlave::IOProperty& p ) std::ostream& operator<<( std::ostream& os, MBSlave::IOProperty& p )
{ {
os << " reg=" << ModbusRTU::dat2str(p.mbreg) << "(" << (int)p.mbreg << ")" os << "reg=" << ModbusRTU::dat2str(p.mbreg) << "(" << (int)p.mbreg << ")"
<< " sid=" << p.si.id << " sid=" << p.si.id
<< " stype=" << p.stype << " stype=" << p.stype
<< " wnum=" << p.wnum << " wnum=" << p.wnum
...@@ -1321,13 +1321,28 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( const ModbusRTU::ModbusData reg, ...@@ -1321,13 +1321,28 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( const ModbusRTU::ModbusData reg,
if( it == iomap.end() ) if( it == iomap.end() )
return ModbusRTU::erBadDataAddress; return ModbusRTU::erBadDataAddress;
for( ; (it != iomap.end()) && (i < count); i++, regID++ ) int prev_i = i;
int sub = 0;
for( ; (it != iomap.end()) && (i < count); )
{ {
if( it->first == regID ) if( it->first == regID )
{ {
prev_i = i;
real_write_it(it, dat, i, count); real_write_it(it, dat, i, count);
--i; // т.к. внутри real_write_it будет сделан ++
++it; sub = (i-prev_i);
// если при обработке i не сдвигали..
// значит сами делаем ++
if( sub == 0 )
{
sub = 1;
i++;
}
std::advance(it,sub);
regID += sub;
} }
} }
...@@ -1364,7 +1379,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod ...@@ -1364,7 +1379,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_it( IOMap::iterator& it, ModbusRTU::Mod
IOProperty* p(&it->second); IOProperty* p(&it->second);
if( p->bitreg ) if( p->bitreg )
return real_bitreg_write_it(p->bitreg, dat[i++]); return real_bitreg_write_it(p->bitreg, dat[i]);
return real_write_prop(p, dat, i, count); return real_write_prop(p, dat, i, count);
} }
...@@ -1397,7 +1412,9 @@ ModbusRTU::mbErrCode MBSlave::real_bitreg_write_it( std::shared_ptr<BitRegProper ...@@ -1397,7 +1412,9 @@ ModbusRTU::mbErrCode MBSlave::real_bitreg_write_it( std::shared_ptr<BitRegProper
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusData* dat, int& i, int count ) ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusData* dat, int& i, int count )
{ {
ModbusRTU::ModbusData mbval = dat[i++]; ModbusRTU::ModbusData mbval = dat[i];
dinfo << myname << "(real_write_prop): val=" << mbval << " " << (*p) << endl;
try try
{ {
...@@ -1431,7 +1448,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1431,7 +1448,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtI2 ) else if( p->vtype == VTypes::vtI2 )
{ {
if( (i + VTypes::I2::wsize() - 1) > count ) if( (i + VTypes::I2::wsize()) > count )
{ {
i += VTypes::I2::wsize(); i += VTypes::I2::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1440,7 +1457,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1440,7 +1457,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2::wsize()];
for( int k = 0; k < VTypes::I2::wsize(); k++, i++ ) for( int k = 0; k < VTypes::I2::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::I2 i2(d, VTypes::I2::wsize()); VTypes::I2 i2(d, VTypes::I2::wsize());
delete[] d; delete[] d;
...@@ -1448,7 +1465,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1448,7 +1465,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtI2r ) else if( p->vtype == VTypes::vtI2r )
{ {
if( (i + VTypes::I2r::wsize() - 1) > count ) if( (i + VTypes::I2r::wsize()) > count )
{ {
i += VTypes::I2r::wsize(); i += VTypes::I2r::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1457,7 +1474,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1457,7 +1474,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2r::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::I2r::wsize()];
for( int k = 0; k < VTypes::I2r::wsize(); k++, i++ ) for( int k = 0; k < VTypes::I2r::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::I2r i2r(d, VTypes::I2r::wsize()); VTypes::I2r i2r(d, VTypes::I2r::wsize());
delete[] d; delete[] d;
...@@ -1465,7 +1482,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1465,7 +1482,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtU2 ) else if( p->vtype == VTypes::vtU2 )
{ {
if( (i + VTypes::U2::wsize() - 1) > count ) if( (i + VTypes::U2::wsize()) > count )
{ {
i += VTypes::U2::wsize(); i += VTypes::U2::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1474,7 +1491,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1474,7 +1491,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2::wsize()];
for( int k = 0; k < VTypes::U2::wsize(); k++, i++ ) for( int k = 0; k < VTypes::U2::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::U2 u2(d, VTypes::U2::wsize()); VTypes::U2 u2(d, VTypes::U2::wsize());
delete[] d; delete[] d;
...@@ -1482,7 +1499,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1482,7 +1499,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtU2r ) else if( p->vtype == VTypes::vtU2r )
{ {
if( (i + VTypes::U2r::wsize() - 1) > count ) if( (i + VTypes::U2r::wsize()) > count )
{ {
i += VTypes::U2r::wsize(); i += VTypes::U2r::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1491,7 +1508,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1491,7 +1508,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2r::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::U2r::wsize()];
for( int k = 0; k < VTypes::U2r::wsize(); k++, i++ ) for( int k = 0; k < VTypes::U2r::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::U2r u2r(d, VTypes::U2r::wsize()); VTypes::U2r u2r(d, VTypes::U2r::wsize());
delete[] d; delete[] d;
...@@ -1499,7 +1516,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1499,7 +1516,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtF2 ) else if( p->vtype == VTypes::vtF2 )
{ {
if( (i + VTypes::F2::wsize() - 1) > count ) if( (i + VTypes::F2::wsize()) > count )
{ {
i += VTypes::F2::wsize(); i += VTypes::F2::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1508,7 +1525,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1508,7 +1525,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2::wsize()];
for( int k = 0; k < VTypes::F2::wsize(); k++, i++ ) for( int k = 0; k < VTypes::F2::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::F2 f2(d, VTypes::F2::wsize()); VTypes::F2 f2(d, VTypes::F2::wsize());
delete[] d; delete[] d;
...@@ -1517,7 +1534,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1517,7 +1534,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtF2r ) else if( p->vtype == VTypes::vtF2r )
{ {
if( (i + VTypes::F2r::wsize() - 1) > count ) if( (i + VTypes::F2r::wsize()) > count )
{ {
i += VTypes::F2r::wsize(); i += VTypes::F2r::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1526,7 +1543,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1526,7 +1543,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2r::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F2r::wsize()];
for( int k = 0; k < VTypes::F2r::wsize(); k++, i++ ) for( int k = 0; k < VTypes::F2r::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::F2r f2r(d, VTypes::F2r::wsize()); VTypes::F2r f2r(d, VTypes::F2r::wsize());
delete[] d; delete[] d;
...@@ -1534,7 +1551,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1534,7 +1551,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
} }
else if( p->vtype == VTypes::vtF4 ) else if( p->vtype == VTypes::vtF4 )
{ {
if( (i + VTypes::F4::wsize() - 1) > count ) if( (i + VTypes::F4::wsize()) > count )
{ {
i += VTypes::F4::wsize(); i += VTypes::F4::wsize();
return ModbusRTU::erInvalidFormat; return ModbusRTU::erInvalidFormat;
...@@ -1543,7 +1560,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1543,7 +1560,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F4::wsize()]; ModbusRTU::ModbusData* d = new ModbusRTU::ModbusData[VTypes::F4::wsize()];
for( int k = 0; k < VTypes::F4::wsize(); k++, i++ ) for( int k = 0; k < VTypes::F4::wsize(); k++, i++ )
d[k] = dat[i - 1]; d[k] = dat[i];
VTypes::F4 f4(d, VTypes::F4::wsize()); VTypes::F4 f4(d, VTypes::F4::wsize());
delete[] d; delete[] d;
......
#!/bin/sh #!/bin/sh
uniset2-start.sh -f ./uniset2-mbslave --confile test.xml --dlog-add-levels info,crit,warn \ uniset2-start.sh -f ./uniset2-mbslave --confile test.xml --dlog-add-levels any \
--mbs-name MBSlave1 \ --mbs-name MBSlave1 \
--mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 2048 --mbs-my-addr 0x01 \ --mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 2048 --mbs-my-addr 0x01 \
--mbs-askcount-id SVU_AskCount_AS \ --mbs-askcount-id SVU_AskCount_AS \
--mbs-filter-field mbtcp --mbs-filter-value 2 --mbs-filter-field mbtcp --mbs-filter-value 2 $*
\ No newline at end of file \ No newline at end of file
...@@ -193,10 +193,10 @@ ...@@ -193,10 +193,10 @@
<item id="2046" mbs="1" mbreg="158" iotype="AO" name="Test_CountWrite10_9" textname="Тестовый регистр для 0x10"/> <item id="2046" mbs="1" mbreg="158" iotype="AO" name="Test_CountWrite10_9" textname="Тестовый регистр для 0x10"/>
<item id="2047" mbs="1" mbreg="159" iotype="AO" name="Test_CountWrite10_10" textname="Тестовый регистр для 0x10"/> <item id="2047" mbs="1" mbreg="159" iotype="AO" name="Test_CountWrite10_10" textname="Тестовый регистр для 0x10"/>
<!-- ещё тест --> <!-- ещё тест -->
<item id="2048" mbs="1" mbreg="258" iotype="AO" name="Test_CountWrite10_11" textname="Тестовый регистр для 0x10"/> <item id="2048" mbs="1" mbreg="258" iotype="AO" name="Test_CountWrite10_11" textname="Тестовый регистр для 0x10"/>
<item id="2049" mbs="1" mbreg="257" iotype="AO" name="Test_CountWrite10_12" textname="Тестовый регистр для 0x10"/> <item id="2049" mbs="1" mbreg="257" iotype="AO" name="Test_CountWrite10_12" textname="Тестовый регистр для 0x10"/>
<item id="2050" mbs="1" mbreg="259" iotype="AO" vtype="F2" name="Test_CountWrite10_F2" textname="Тестовый регистр для 0x10(F2)"/>
<item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/> <item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/>
......
...@@ -1124,4 +1124,25 @@ TEST_CASE("write10: more..", "[modbus][mbslave][mbtcpslave][write10]") ...@@ -1124,4 +1124,25 @@ TEST_CASE("write10: more..", "[modbus][mbslave][mbtcpslave][write10]")
REQUIRE( (signed short)ui->getValue(2049) == 10 ); REQUIRE( (signed short)ui->getValue(2049) == 10 );
} }
// ------------------------------------------------------------- // -------------------------------------------------------------
TEST_CASE("(0x10): write register outputs or memories [F2]", "[modbus][mbslave][F2][mbtcpslave]")
{
InitTest();
ObjectId tID = 2050;
ModbusRTU::ModbusData tREG = 259;
using namespace VTypes;
float f = 200.0;
F2 f2(f);
ModbusRTU::WriteOutputMessage msg(slaveaddr, tREG);
msg.addData(f2.raw.v[0]);
msg.addData(f2.raw.v[1]);
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == 2 );
REQUIRE( ui->getValue(tID) == 200 );
}
// -------------------------------------------------------------
/*! \todo Доделать тесты на считывание с разными prop_prefix.. */ /*! \todo Доделать тесты на считывание с разными prop_prefix.. */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment