Commit 55343f6e authored by Pavel Vainerman's avatar Pavel Vainerman

(MBSlave): исправлена ошибка в initItem() и работе с std::move().

parent 67691e43
...@@ -79,9 +79,9 @@ MBSlave::MBSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, cons ...@@ -79,9 +79,9 @@ MBSlave::MBSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, cons
// int recv_timeout = conf->getArgParam("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"))); // int recv_timeout = conf->getArgParam("--" + prefix + "-recv-timeout",it.getProp("recv_timeout")));
addr = ModbusRTU::str2mbAddr(conf->getArg2Param("--" + prefix + "-my-addr", it.getProp("addr"),"0x01")); addr = ModbusRTU::str2mbAddr(conf->getArg2Param("--" + prefix + "-my-addr", it.getProp("addr"), "0x01"));
default_mbfunc = conf->getArgPInt("--" + prefix + "-default-mbfunc", it.getProp("default_mbfunc"),0); default_mbfunc = conf->getArgPInt("--" + prefix + "-default-mbfunc", it.getProp("default_mbfunc"), 0);
mbregFromID = conf->getArgInt("--" + prefix + "-reg-from-id", it.getProp("reg_from_id")); mbregFromID = conf->getArgInt("--" + prefix + "-reg-from-id", it.getProp("reg_from_id"));
checkMBFunc = conf->getArgInt("--" + prefix + "-check-mbfunc", it.getProp("check_mbfunc")); checkMBFunc = conf->getArgInt("--" + prefix + "-check-mbfunc", it.getProp("check_mbfunc"));
...@@ -90,7 +90,7 @@ MBSlave::MBSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, cons ...@@ -90,7 +90,7 @@ MBSlave::MBSlave( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, cons
respond_id = conf->getSensorID(conf->getArgParam("--" + prefix + "-respond-id", it.getProp("respond_id"))); respond_id = conf->getSensorID(conf->getArgParam("--" + prefix + "-respond-id", it.getProp("respond_id")));
respond_invert = conf->getArgInt("--" + prefix + "-respond-invert", it.getProp("respond_invert")); respond_invert = conf->getArgInt("--" + prefix + "-respond-invert", it.getProp("respond_invert"));
timeout_t reply_tout = conf->getArgPInt("--" + prefix + "-reply-timeout", it.getProp("replyTimeout"),3000); timeout_t reply_tout = conf->getArgPInt("--" + prefix + "-reply-timeout", it.getProp("replyTimeout"), 3000);
timeout_t aftersend_pause = conf->getArgInt("--" + prefix + "-aftersend-pause", it.getProp("afterSendPause")); timeout_t aftersend_pause = conf->getArgInt("--" + prefix + "-aftersend-pause", it.getProp("afterSendPause"));
...@@ -899,7 +899,7 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -899,7 +899,7 @@ bool MBSlave::initItem( UniXML::iterator& it )
int mbfunc = IOBase::initIntProp(it, "mbfunc", prop_prefix, false, default_mbfunc); int mbfunc = IOBase::initIntProp(it, "mbfunc", prop_prefix, false, default_mbfunc);
p.regID = ModbusRTU::genRegID(p.mbreg,mbfunc); p.regID = ModbusRTU::genRegID(p.mbreg, mbfunc);
p.amode = MBSlave::amRW; p.amode = MBSlave::amRW;
string am(IOBase::initProp(it, "accessmode", prop_prefix, false)); string am(IOBase::initProp(it, "accessmode", prop_prefix, false));
...@@ -958,18 +958,37 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -958,18 +958,37 @@ bool MBSlave::initItem( UniXML::iterator& it )
IOProperty p_dummy; IOProperty p_dummy;
p_dummy.bitreg = make_shared<BitRegProperty>(); p_dummy.bitreg = make_shared<BitRegProperty>();
p_dummy.bitreg->mbreg = mbreg; p_dummy.bitreg->mbreg = mbreg;
p_dummy.regID = p.regID;
p.vtype = VTypes::vtUnknown; p.vtype = VTypes::vtUnknown;
p.wnum = 0; p.wnum = 0;
p_dummy.bitreg->bvec[nbit] = std::move(p); p_dummy.bitreg->bvec[nbit] = std::move(p); // после этого p использовать нельзя!
dinfo << myname << "(initItem): add bit register: " << p_dummy.bitreg.get() << endl; dinfo << myname << "(initItem): add bit register: " << p_dummy.bitreg.get() << endl;
iomap[p.regID] = std::move(p_dummy); iomap[p_dummy.regID] = std::move(p_dummy);
} }
return true; return true;
} }
auto i = iomap.find(p.regID);
if( i != iomap.end() )
{
ostringstream err;
err << myname << "(initItem): FAIL ADD sid='" << it.getProp("name") << "'(" << p.si.id << ")"
<< " reg='" << ModbusRTU::dat2str(p.mbreg) << "(" << (int)p.mbreg << ")"
<< " mbfunc=" << mbfunc << " --> regID=" << p.regID
<< " ALREADY ADDED! for sid='" << uniset_conf()->oind->getMapName(i->second.si.id) << "'("
<< i->second.si.id << ") regID=" << i->first
<< " reg='" << ModbusRTU::dat2str(i->second.mbreg) << "(" << (int)i->second.mbreg << ")"
<< " wnum=" << i->second.wnum;
dcrit << err.str() << endl;
//throw SystemError( err.str() );
abort();
}
string vt(IOBase::initProp(it, "vtype", prop_prefix, false)); string vt(IOBase::initProp(it, "vtype", prop_prefix, false));
if( vt.empty() ) if( vt.empty() )
...@@ -1015,13 +1034,37 @@ bool MBSlave::initItem( UniXML::iterator& it ) ...@@ -1015,13 +1034,37 @@ bool MBSlave::initItem( UniXML::iterator& it )
p.vtype = v; p.vtype = v;
p.wnum = 0; p.wnum = 0;
for( auto i = 0; i < VTypes::wsize(p.vtype); i++ ) // копируем минимум полей, который нужен для обработки.. т.к. нам другие не понадобятся..
int p_wnum = 0;
ModbusData p_mbreg = p.mbreg;
IOController_i::SensorInfo p_si = p.si;
UniversalIO::IOType p_stype = p.stype;
VTypes::VType p_vtype = p.vtype;
int wsz = VTypes::wsize(p_vtype );
int p_regID = p.regID;
// после std::move p - использовать нельзя!
dinfo << myname << "(initItem): add " << p << endl;
iomap[p_regID] = std::move(p);
if( wsz > 1 )
{ {
p.mbreg += i; for( int i = 1; i < wsz; i++ )
p.wnum += i; {
dinfo << myname << "(initItem): add " << p << endl; IOProperty p_dummy;
p.regID = genRegID(p.mbreg,mbfunc); p_dummy.mbreg = p_mbreg + i;
iomap[p.regID] = std::move(p); p_dummy.wnum = p_wnum + i;
p_dummy.si = p_si;
p_dummy.stype = p_stype;
p_dummy.vtype = p_vtype;
p_regID = genRegID(p_dummy.mbreg, mbfunc);
p_dummy.regID = p_regID;
dinfo << myname << "(initItem): add " << p_dummy << endl;
iomap[p_regID] = std::move(p_dummy);
}
} }
} }
...@@ -1232,7 +1275,7 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( const ModbusRTU::ModbusData reg, ...@@ -1232,7 +1275,7 @@ ModbusRTU::mbErrCode MBSlave::much_real_write( const ModbusRTU::ModbusData reg,
auto it = iomap.end(); auto it = iomap.end();
int mbfunc = checkMBFunc ? fn : default_mbfunc; int mbfunc = checkMBFunc ? fn : default_mbfunc;
ModbusRTU::RegID regID = genRegID(reg,mbfunc); ModbusRTU::RegID regID = genRegID(reg, mbfunc);
for( ; i < count; i++ ) for( ; i < count; i++ )
{ {
...@@ -1277,7 +1320,7 @@ ModbusRTU::mbErrCode MBSlave::real_write( const ModbusRTU::ModbusData reg, Modbu ...@@ -1277,7 +1320,7 @@ ModbusRTU::mbErrCode MBSlave::real_write( const ModbusRTU::ModbusData reg, Modbu
<< " data=" << ModbusRTU::dat2str(mbval) << " data=" << ModbusRTU::dat2str(mbval)
<< "(" << (int)mbval << ")" << endl; << "(" << (int)mbval << ")" << endl;
ModbusRTU::RegID regID = checkMBFunc ? genRegID(reg,fn) : genRegID(reg,default_mbfunc); ModbusRTU::RegID regID = checkMBFunc ? genRegID(reg, fn) : genRegID(reg, default_mbfunc);
auto it = iomap.find(regID); auto it = iomap.find(regID);
return real_write_it(it, dat, i, count); return real_write_it(it, dat, i, count);
...@@ -1439,6 +1482,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1439,6 +1482,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
VTypes::F2 f2(d, VTypes::F2::wsize()); VTypes::F2 f2(d, VTypes::F2::wsize());
delete[] d; delete[] d;
IOBase::processingFasAI( p, (float)f2, shm, force ); IOBase::processingFasAI( p, (float)f2, shm, force );
} }
else if( p->vtype == VTypes::vtF2r ) else if( p->vtype == VTypes::vtF2r )
...@@ -1473,6 +1517,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD ...@@ -1473,6 +1517,7 @@ ModbusRTU::mbErrCode MBSlave::real_write_prop( IOProperty* p, ModbusRTU::ModbusD
VTypes::F4 f4(d, VTypes::F4::wsize()); VTypes::F4 f4(d, VTypes::F4::wsize());
delete[] d; delete[] d;
IOBase::processingFasAI( p, (float)f4, shm, force ); IOBase::processingFasAI( p, (float)f4, shm, force );
} }
else if( p->vtype == VTypes::vtByte ) else if( p->vtype == VTypes::vtByte )
...@@ -1539,11 +1584,12 @@ ModbusRTU::mbErrCode MBSlave::much_real_read( const ModbusRTU::ModbusData reg, M ...@@ -1539,11 +1584,12 @@ ModbusRTU::mbErrCode MBSlave::much_real_read( const ModbusRTU::ModbusData reg, M
auto it = iomap.end(); auto it = iomap.end();
int i = 0; int i = 0;
ModbusRTU::RegID regID = genRegID(reg,mbfunc); ModbusRTU::RegID regID = genRegID(reg, mbfunc);
for( ; i < count; i++ ) for( ; i < count; i++ )
{ {
it = iomap.find(regID+i); it = iomap.find(regID + i);
if( it != iomap.end() ) if( it != iomap.end() )
{ {
regID += i; regID += i;
...@@ -1588,7 +1634,7 @@ ModbusRTU::mbErrCode MBSlave::real_read( const ModbusRTU::ModbusData reg, Modbus ...@@ -1588,7 +1634,7 @@ ModbusRTU::mbErrCode MBSlave::real_read( const ModbusRTU::ModbusData reg, Modbus
dinfo << myname << "(real_read): read mbID=" dinfo << myname << "(real_read): read mbID="
<< ModbusRTU::dat2str(reg) << "(" << (int)reg << ")" << " fn=" << fn << endl; << ModbusRTU::dat2str(reg) << "(" << (int)reg << ")" << " fn=" << fn << endl;
ModbusRTU::RegID regID = checkMBFunc ? genRegID(reg,fn) : genRegID(reg,default_mbfunc); ModbusRTU::RegID regID = checkMBFunc ? genRegID(reg, fn) : genRegID(reg, default_mbfunc);
auto it = iomap.find(regID); auto it = iomap.find(regID);
return real_read_it(it, val); return real_read_it(it, val);
...@@ -1779,7 +1825,7 @@ mbErrCode MBSlave::readInputRegisters( ReadInputMessage& query, ReadInputRetMess ...@@ -1779,7 +1825,7 @@ mbErrCode MBSlave::readInputRegisters( ReadInputMessage& query, ReadInputRetMess
if( query.count <= 1 ) if( query.count <= 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(query.start, d,query.func); ModbusRTU::mbErrCode ret = real_read(query.start, d, query.func);
if( ret == ModbusRTU::erNoError ) if( ret == ModbusRTU::erNoError )
reply.addData(d); reply.addData(d);
...@@ -1838,7 +1884,7 @@ ModbusRTU::mbErrCode MBSlave::readCoilStatus( ReadCoilMessage& query, ...@@ -1838,7 +1884,7 @@ ModbusRTU::mbErrCode MBSlave::readCoilStatus( ReadCoilMessage& query,
if( query.count <= 1 ) if( query.count <= 1 )
{ {
ModbusRTU::ModbusData d = 0; ModbusRTU::ModbusData d = 0;
ModbusRTU::mbErrCode ret = real_read(query.start, d,query.func); ModbusRTU::mbErrCode ret = real_read(query.start, d, query.func);
reply.addData(0); reply.addData(0);
if( ret == ModbusRTU::erNoError ) if( ret == ModbusRTU::erNoError )
......
...@@ -127,6 +127,12 @@ ...@@ -127,6 +127,12 @@
- 1 - в качестве регистра использовать идентификатор датчика - 1 - в качестве регистра использовать идентификатор датчика
- 0 - регистр брать из поля tcp_mbreg - 0 - регистр брать из поля tcp_mbreg
\b --xxx-default-mbfunc или \b default_mbfunc [0...255] - Функция подставляемая по умолчанию, если не указан параметр mbfunc. Действует только если включён контроль функций (check-mbfunc).
\b --xxx-check-mbfunc [0|1] -
- 1 - включить контроль (обработку) свойства mbfunc. По умолчанию: отключёна. Если контроль включён то разрешено
использовать один и тот же регистр но \b для \b разных \b функций.
- 0 - игнорировать свойство mbfunc..
\b --xxx-heartbeat-id или \b heartbeat_id ID - идентификатор датчика "сердцебиения" (см. \ref sec_SM_HeartBeat) \b --xxx-heartbeat-id или \b heartbeat_id ID - идентификатор датчика "сердцебиения" (см. \ref sec_SM_HeartBeat)
\b --xxx-heartbeat-max или \b heartbeat_max val - сохраняемое значение счётчика "сердцебиения". \b --xxx-heartbeat-max или \b heartbeat_max val - сохраняемое значение счётчика "сердцебиения".
...@@ -415,7 +421,7 @@ class MBSlave: ...@@ -415,7 +421,7 @@ class MBSlave:
xmlNode* cnode; xmlNode* cnode;
std::string s_field; std::string s_field;
std::string s_fvalue; std::string s_fvalue;
int default_mbfunc={0}; // функция по умолчанию, для вычисления RegID int default_mbfunc = {0}; // функция по умолчанию, для вычисления RegID
std::shared_ptr<SMInterface> shm; std::shared_ptr<SMInterface> shm;
...@@ -440,11 +446,11 @@ class MBSlave: ...@@ -440,11 +446,11 @@ class MBSlave:
void readConfiguration(); void readConfiguration();
bool check_item( UniXML::iterator& it ); bool check_item( UniXML::iterator& it );
ModbusRTU::mbErrCode real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData val, const int fn=0 ); ModbusRTU::mbErrCode real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData val, const int fn = 0 );
ModbusRTU::mbErrCode real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int& i, int count, const int fn=0 ); ModbusRTU::mbErrCode real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int& i, int count, const int fn = 0 );
ModbusRTU::mbErrCode real_read( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData& val, const int fn=0 ); ModbusRTU::mbErrCode real_read( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData& val, const int fn = 0 );
ModbusRTU::mbErrCode much_real_read( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count, const int fn=0 ); ModbusRTU::mbErrCode much_real_read( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count, const int fn = 0 );
ModbusRTU::mbErrCode much_real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count, const int fn=0 ); ModbusRTU::mbErrCode much_real_write( const ModbusRTU::ModbusData reg, ModbusRTU::ModbusData* dat, int count, const int fn = 0 );
ModbusRTU::mbErrCode real_read_it( IOMap::iterator& it, ModbusRTU::ModbusData& val ); ModbusRTU::mbErrCode real_read_it( IOMap::iterator& it, ModbusRTU::ModbusData& val );
ModbusRTU::mbErrCode real_bitreg_read_it( std::shared_ptr<BitRegProperty>& bp, ModbusRTU::ModbusData& val ); ModbusRTU::mbErrCode real_bitreg_read_it( std::shared_ptr<BitRegProperty>& bp, ModbusRTU::ModbusData& val );
...@@ -484,8 +490,8 @@ class MBSlave: ...@@ -484,8 +490,8 @@ class MBSlave:
timeout_t wait_msec; timeout_t wait_msec;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */ bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool mbregFromID={0}; bool mbregFromID = {0};
bool checkMBFunc={0}; bool checkMBFunc = {0};
typedef std::unordered_map<int, std::string> FileList; typedef std::unordered_map<int, std::string> FileList;
FileList flist; FileList flist;
......
...@@ -146,7 +146,7 @@ ...@@ -146,7 +146,7 @@
<item id="2009" default="250000" precision="5" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/> <item id="2009" default="250000" precision="5" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/>
<item default="-100" id="2011" mbs="1" mbreg="118" iotype="AI" vtype="signed" name="TestVtype11" textname="Тестовый регистр для проверки vtype"/> <item default="-100" id="2011" mbs="1" mbreg="118" iotype="AI" vtype="signed" name="TestVtype11" textname="Тестовый регистр для проверки vtype"/>
<item default="65534" id="2012" mbs="1" mbreg="119" iotype="AI" vtype="unsigned" name="TestVtype12" textname="Тестовый регистр для проверки vtype"/> <item default="65534" id="2012" mbs="1" mbreg="119" iotype="AI" vtype="unsigned" name="TestVtype12" textname="Тестовый регистр для проверки vtype"/>
<item id="2013" rawdata="1" mbs="1" mbreg="120" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/> <item id="2013" rawdata="1" mbs="1" mbreg="120" iotype="AI" vtype="F4" name="TestVtype13" textname="Тестовый регистр для проверки записи vtype"/>
<!-- access mode test --> <!-- access mode test -->
<item id="2014" default="1002" accessmode="ro" mbs="1" mbreg="124" iotype="AI" name="TestAccessMode1" textname="Тестовый регистр для проверки access mode"/> <item id="2014" default="1002" accessmode="ro" mbs="1" mbreg="124" iotype="AI" name="TestAccessMode1" textname="Тестовый регистр для проверки access mode"/>
......
...@@ -1030,6 +1030,13 @@ TEST_CASE("Write(0x06,0x10): nbit", "[modbus][mbslave][mbtcpslave][writenbit]") ...@@ -1030,6 +1030,13 @@ TEST_CASE("Write(0x06,0x10): nbit", "[modbus][mbslave][mbtcpslave][writenbit]")
} }
} }
} }
// -------------------------------------------------------------
TEST_CASE("check-mbfunc", "[modbus][mbslave][mbtcpslave][mbfunc]")
{
using namespace VTypes;
InitTest();
//...
}
// ------------------------------------------------------------- // -------------------------------------------------------------
/*! \todo Доделать тесты на считывание с разными prop_prefix.. */ /*! \todo Доделать тесты на считывание с разными prop_prefix.. */
...@@ -11,5 +11,6 @@ cd - ...@@ -11,5 +11,6 @@ cd -
./uniset2-start.sh -f ./tests-with-sm $* -- --confile mbslave-test-configure.xml --e-startup-pause 10 \ ./uniset2-start.sh -f ./tests-with-sm $* -- --confile mbslave-test-configure.xml --e-startup-pause 10 \
--mbs-name MBSlave1 --mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 20048 --mbs-my-addr 0x01 \ --mbs-name MBSlave1 --mbs-type TCP --mbs-inet-addr 127.0.0.1 --mbs-inet-port 20048 --mbs-my-addr 0x01 \
--mbs-askcount-id SVU_AskCount_AS --mbs-respond-id RespondRTU_S --mbs-respond-invert 1 \ --mbs-askcount-id SVU_AskCount_AS --mbs-respond-id RespondRTU_S --mbs-respond-invert 1 \
--mbs-filter-field mbs --mbs-filter-value 1 --mbs-filter-field mbs --mbs-filter-value 1 --dlog-add-levels any
#--mbs-check-mbfunc 1
#--dlog-add-levels any #--dlog-add-levels any
...@@ -82,7 +82,7 @@ namespace VTypes ...@@ -82,7 +82,7 @@ namespace VTypes
return "vtUnknown"; return "vtUnknown";
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
int wsize( VType t ) int wsize( const VType t )
{ {
if( t == vtByte ) if( t == vtByte )
return Byte::wsize(); return Byte::wsize();
......
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