Commit 835659aa authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusMaster): исправлена ошибка начальной инициализации (setbug# 5583)

parent 0668dbc7
...@@ -413,6 +413,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -413,6 +413,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
- codegen: set default argprefix=myname (object name) - codegen: set default argprefix=myname (object name)
- codegen: fixed minor bug in mylog.. - codegen: fixed minor bug in mylog..
- refactoring IORFile interface - refactoring IORFile interface
- (modbusmaster): fixed bug (setbug #5583) in initialization..
* Sat Feb 21 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt17 * Sat Feb 21 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt17
- use omni_options[] argument for ORB_init(). - use omni_options[] argument for ORB_init().
......
...@@ -244,6 +244,7 @@ ...@@ -244,6 +244,7 @@
<item id="62" iotype="AI" name="LogLevel_S" textname="LogLevel control"/> <item id="62" iotype="AI" name="LogLevel_S" textname="LogLevel control"/>
<item id="63" iotype="AI" name="SVU_AskCount_AS" textname="svu asl count"/> <item id="63" iotype="AI" name="SVU_AskCount_AS" textname="svu asl count"/>
<item id="64" iotype="AI" name="AI64_AS" textname="AI64" mbaddr="0x01" mbfunc="0x03" mbreg="64" mbtype="rtu" rs="5"/> <item id="64" iotype="AI" name="AI64_AS" textname="AI64" mbaddr="0x01" mbfunc="0x03" mbreg="64" mbtype="rtu" rs="5"/>
<item id="66" iotype="DI" name="DI66_AS" textname="DI66" mbaddr="0x01" mbfunc="0x01" mbreg="66" mbtype="rtu" rs="5"/>
<item id="65" iotype="DI" name="D65_S" textname="D65" threshold_aid="AI64_AS" lowlimit="3" hilimit="5" threshold_invert="1" rs="5" /> <item id="65" iotype="DI" name="D65_S" textname="D65" threshold_aid="AI64_AS" lowlimit="3" hilimit="5" threshold_invert="1" rs="5" />
</sensors> </sensors>
<thresholds name="thresholds"> <thresholds name="thresholds">
......
...@@ -86,6 +86,8 @@ pollActivated(false) ...@@ -86,6 +86,8 @@ pollActivated(false)
defaultMBtype = conf->getArg2Param("--" + prefix + "-default-mbtype",it.getProp("default_mbtype"),"rtu"); defaultMBtype = conf->getArg2Param("--" + prefix + "-default-mbtype",it.getProp("default_mbtype"),"rtu");
defaultMBaddr = conf->getArg2Param("--" + prefix + "-default-mbaddr",it.getProp("default_mbaddr"),""); defaultMBaddr = conf->getArg2Param("--" + prefix + "-default-mbaddr",it.getProp("default_mbaddr"),"");
defaultMBinitOK = conf->getArgPInt("--" + prefix + "-default-mbinit-ok",it.getProp("default_mbinitOK"), 0);
// ********** HEARTBEAT ************* // ********** HEARTBEAT *************
string heart = conf->getArgParam("--" + prefix + "-heartbeat-id",it.getProp("heartbeat_id")); string heart = conf->getArgParam("--" + prefix + "-heartbeat-id",it.getProp("heartbeat_id"));
if( !heart.empty() ) if( !heart.empty() )
...@@ -162,6 +164,7 @@ void MBExchange::help_print( int argc, const char* const* argv ) ...@@ -162,6 +164,7 @@ void MBExchange::help_print( int argc, const char* const* argv )
cout << "--prefix-set-prop-prefix val - Использовать для свойств указанный или пустой префикс." << endl; cout << "--prefix-set-prop-prefix val - Использовать для свойств указанный или пустой префикс." << endl;
cout << "--prefix-default-mbtype [rtu|rtu188|mtr] - У датчиков которых не задан 'mbtype' использовать данный. По умолчанию: 'rtu'" << endl; cout << "--prefix-default-mbtype [rtu|rtu188|mtr] - У датчиков которых не задан 'mbtype' использовать данный. По умолчанию: 'rtu'" << endl;
cout << "--prefix-default-mbadd addr - У датчиков которых не задан 'mbaddr' использовать данный. По умолчанию: ''" << endl; cout << "--prefix-default-mbadd addr - У датчиков которых не задан 'mbaddr' использовать данный. По умолчанию: ''" << endl;
cout << "--prefix-default-mbinit-ok 0,1 - Флаг инициализации. 1 - не ждать первого обмена с устройством, а сохранить при старте в SM значение 'default'" << endl;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
MBExchange::~MBExchange() MBExchange::~MBExchange()
...@@ -336,6 +339,27 @@ void MBExchange::initIterators() ...@@ -336,6 +339,27 @@ void MBExchange::initIterators()
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void MBExchange::initValues()
{
for( auto it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
for( auto it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
for( auto it2=it->second->slst.begin();it2!=it->second->slst.end(); ++it2 )
{
it2->value = shm->localGetValue(it2->ioit,it2->si.id);
}
it->second->sm_initOK = true;
}
}
for( auto t=thrlist.begin(); t!=thrlist.end(); ++t )
{
t->value = shm->localGetValue(t->ioit,t->si.id);
}
}
// -----------------------------------------------------------------------------
bool MBExchange::checkUpdateSM( bool wrFunc, long mdev ) bool MBExchange::checkUpdateSM( bool wrFunc, long mdev )
{ {
if( exchangeMode == emSkipExchange || mdev == emSkipExchange ) if( exchangeMode == emSkipExchange || mdev == emSkipExchange )
...@@ -660,7 +684,7 @@ bool MBExchange::preInitRead( InitList::iterator& p ) ...@@ -660,7 +684,7 @@ bool MBExchange::preInitRead( InitList::iterator& p )
// выставляем флаг принудительного обновления // выставляем флаг принудительного обновления
force_out = true; force_out = true;
p->ri->mb_initOK = true; p->ri->mb_initOK = true;
p->ri->sm_initOK = false; // p->ri->sm_initOK = false;
updateRTU(p->ri->rit); updateRTU(p->ri->rit);
force_out = f_out; force_out = f_out;
} }
...@@ -854,8 +878,12 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -854,8 +878,12 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{ {
ModbusRTU::ReadInputRetMessage ret = mb->read04(dev->mbaddr,p->mbreg,p->q_count); ModbusRTU::ReadInputRetMessage ret = mb->read04(dev->mbaddr,p->mbreg,p->q_count);
for( unsigned int i=0; i<p->q_count; i++,it++ ) for( unsigned int i=0; i<p->q_count; i++,it++ )
{
it->second->mbval = ret.data[i]; it->second->mbval = ret.data[i];
it->second->mb_initOK = true;
}
it--; it--;
} }
break; break;
...@@ -863,7 +891,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -863,7 +891,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{ {
ModbusRTU::ReadOutputRetMessage ret = mb->read03(dev->mbaddr,p->mbreg,p->q_count); ModbusRTU::ReadOutputRetMessage ret = mb->read03(dev->mbaddr,p->mbreg,p->q_count);
for( unsigned int i=0; i<p->q_count; i++,it++ ) for( unsigned int i=0; i<p->q_count; i++,it++ )
{
it->second->mbval = ret.data[i]; it->second->mbval = ret.data[i];
it->second->mb_initOK = true;
}
it--; it--;
} }
break; break;
...@@ -876,7 +907,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -876,7 +907,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{ {
ModbusRTU::DataBits b(ret.data[i]); ModbusRTU::DataBits b(ret.data[i]);
for( unsigned int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ ) for( unsigned int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
{
it->second->mbval = b[k]; it->second->mbval = b[k];
it->second->mb_initOK = true;
}
} }
it--; it--;
} }
...@@ -890,7 +924,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it ) ...@@ -890,7 +924,10 @@ bool MBExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{ {
ModbusRTU::DataBits b(ret.data[i]); ModbusRTU::DataBits b(ret.data[i]);
for( unsigned int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ ) for( unsigned int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
{
it->second->mbval = b[k] ? 1 : 0; it->second->mbval = b[k] ? 1 : 0;
it->second->mb_initOK = true;
}
} }
it--; it--;
} }
...@@ -1104,9 +1141,8 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only ) ...@@ -1104,9 +1141,8 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
if( !checkUpdateSM(save,r->dev->mode) ) if( !checkUpdateSM(save,r->dev->mode) )
return; return;
// если требуется инициализация и она ещё не произведена, // если ещё не обменивались ни разу с устройством, то ингнорируем (не обновляем значение в SM)
// то игнорируем if( !r->mb_initOK )
if( save && !r->mb_initOK )
return; return;
dlog3 << myname << "(updateP): sid=" << p->si.id dlog3 << myname << "(updateP): sid=" << p->si.id
...@@ -1252,7 +1288,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only ) ...@@ -1252,7 +1288,7 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
return; return;
} }
if( save && r->sm_initOK ) if( save )
{ {
if( r->mb_initOK ) if( r->mb_initOK )
{ {
...@@ -1329,6 +1365,8 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only ) ...@@ -1329,6 +1365,8 @@ void MBExchange::updateRSProperty( RSProperty* p, bool write_only )
VTypes::F4 f4(f); VTypes::F4 f4(f);
for( int k=0; k<VTypes::F4::wsize(); k++, i++ ) for( int k=0; k<VTypes::F4::wsize(); k++, i++ )
i->second->mbval = f4.raw.v[k]; i->second->mbval = f4.raw.v[k];
r->sm_initOK = true;
} }
} }
else else
...@@ -2195,14 +2233,12 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2195,14 +2233,12 @@ bool MBExchange::initItem( UniXML::iterator& it )
// Раз это регистр для записи, то как минимум надо сперва // Раз это регистр для записи, то как минимум надо сперва
// инициализировать значением из SM // инициализировать значением из SM
ri->sm_initOK = IOBase::initIntProp(it,"sm_initOK",prop_prefix,false); ri->sm_initOK = IOBase::initIntProp(it,"sm_initOK",prop_prefix,false);
ri->mb_initOK = true; // может быть переопределён если будет указан tcp_preinit="1" (см. ниже) ri->mb_initOK = true;
} }
else else
{ {
// Если это регистр для чтения, то сразу можно работать ri->mb_initOK = defaultMBinitOK;
// инициализировать не надо ri->sm_initOK = false;
ri->mb_initOK = true;
ri->sm_initOK = true;
} }
...@@ -2224,8 +2260,8 @@ bool MBExchange::initItem( UniXML::iterator& it ) ...@@ -2224,8 +2260,8 @@ bool MBExchange::initItem( UniXML::iterator& it )
r->q_num=i+1; r->q_num=i+1;
r->q_count=1; r->q_count=1;
r->mbfunc = ri->mbfunc; r->mbfunc = ri->mbfunc;
r->mb_initOK = true; r->mb_initOK = defaultMBinitOK;
r->sm_initOK = true; r->sm_initOK = false;
if( ModbusRTU::isWriteFunction(ri->mbfunc) ) if( ModbusRTU::isWriteFunction(ri->mbfunc) )
{ {
// Если занимает несколько регистров, а указана функция записи "одного", // Если занимает несколько регистров, а указана функция записи "одного",
...@@ -2534,7 +2570,7 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -2534,7 +2570,7 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
initOutput(); initOutput();
} }
initValues();
updateSM(); updateSM();
askTimer(tmExchange,polltime); askTimer(tmExchange,polltime);
break; break;
...@@ -2557,6 +2593,7 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm ) ...@@ -2557,6 +2593,7 @@ void MBExchange::sysCommand( const UniSetTypes::SystemMessage *sm )
askSensors(UniversalIO::UIONotify); askSensors(UniversalIO::UIONotify);
initOutput(); initOutput();
initValues();
if( !force ) if( !force )
{ {
......
...@@ -110,7 +110,7 @@ class MBExchange: ...@@ -110,7 +110,7 @@ class MBExchange:
id(0),dev(0), id(0),dev(0),
rtuJack(RTUStorage::nUnknown),rtuChan(0), rtuJack(RTUStorage::nUnknown),rtuChan(0),
mtrType(MTR::mtUnknown), mtrType(MTR::mtUnknown),
q_num(0),q_count(1),mb_initOK(true),sm_initOK(true) q_num(0),q_count(1),mb_initOK(false),sm_initOK(false)
{} {}
ModbusRTU::ModbusData mbval; ModbusRTU::ModbusData mbval;
...@@ -223,6 +223,7 @@ class MBExchange: ...@@ -223,6 +223,7 @@ class MBExchange:
virtual void sigterm( int signo ) override; virtual void sigterm( int signo ) override;
virtual bool activateObject() override; virtual bool activateObject() override;
virtual void initIterators(); virtual void initIterators();
virtual void initValues();
struct InitRegInfo struct InitRegInfo
{ {
...@@ -344,6 +345,7 @@ class MBExchange: ...@@ -344,6 +345,7 @@ class MBExchange:
std::string defaultMBtype; std::string defaultMBtype;
std::string defaultMBaddr; std::string defaultMBaddr;
bool defaultMBinitOK; // флаг определяющий нужно ли ждать "первого обмена" или при запуске сохранять в SM значение default.
private: private:
MBExchange(); MBExchange();
......
...@@ -15,7 +15,9 @@ cd - ...@@ -15,7 +15,9 @@ cd -
--mbtcp-filter-value 1 \ --mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr localhost \ --mbtcp-gateway-iaddr localhost \
--mbtcp-gateway-port 20048 \ --mbtcp-gateway-port 20048 \
--mbtcp-polltime 50 --mbtcp-recv-timeout 500 --mbtcp-polltime 50 --mbtcp-recv-timeout 500 \
$*
#--mbtcp-default-mbinit-ok 1
#--dlog-add-levels any #--dlog-add-levels any
#--mbtcp-force-out 1 #--mbtcp-force-out 1
......
...@@ -38,6 +38,7 @@ static void InitTest() ...@@ -38,6 +38,7 @@ static void InitTest()
if( !mbs ) if( !mbs )
{ {
mbs = make_shared<MBTCPTestServer>(slaveADDR,addr,port,false); mbs = make_shared<MBTCPTestServer>(slaveADDR,addr,port,false);
//mbs->setVerbose(true);
CHECK( mbs!= nullptr ); CHECK( mbs!= nullptr );
mbs->runThread(); mbs->runThread();
for( int i=0; !mbs->isRunning() && i<10; i++ ) for( int i=0; !mbs->isRunning() && i<10; i++ )
......
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