Commit 9eda8e40 authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusMultiMaster): переделана обработка timeout-а переключения на запасные каналы.

parent 3cebcf9c
...@@ -488,6 +488,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -488,6 +488,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%changelog %changelog
* Wed Mar 23 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt31 * Wed Mar 23 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt31
- IONotifyContoller: fixed bug in depend (notify)(setbug #9302) - IONotifyContoller: fixed bug in depend (notify)(setbug #9302)
- ModbusMultiMaster: fixed bug for change channel (timeout)
* Tue Mar 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt30 * Tue Mar 22 2016 Pavel Vainerman <pv@altlinux.ru> 2.2-alt30
- minor fixes in DealyTimer and MBExchange (not respond logic) - minor fixes in DealyTimer and MBExchange (not respond logic)
......
...@@ -78,13 +78,13 @@ ...@@ -78,13 +78,13 @@
<item addr="0x01" invert="1" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/> <item addr="0x01" invert="1" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/>
</DeviceList> </DeviceList>
</MBMaster1> </MBMaster1>
<MBMultiMaster1 levels="info,warn,crit" name="MBMaster1" polltime="200"> <MBMultiMaster1 name="MBMaster1" polltime="200" timeout="4800" checktime="2000" channelTimeout="2000">
<DeviceList> <DeviceList>
<item addr="0x01" invert="1" force="0" respondSensor="RespondRTU_S" timeout="1000" modeSensor="MB1_Mode_AS"/> <item addr="0x01" invert="1" force="0" respondSensor="RespondRTU_S" timeout="5000" modeSensor="MB1_Mode_AS"/>
</DeviceList> </DeviceList>
<GateList> <GateList>
<item ip="localhost" port="2048" recv_timeout="800" invert="1" respondSensor="MM1_Not_Respond_S"/> <item ip="localhost" port="2048" timeout="1000" recv_timeout="800" invert="1" respondSensor="MM1_Not_Respond_S"/>
<item ip="localhost" port="2049" recv_timeout="800" invert="1" respondSensor="MM2_Not_Respond_S"/> <item ip="localhost" port="2049" timeout="1000" recv_timeout="800" invert="1" respondSensor="MM2_Not_Respond_S"/>
</GateList> </GateList>
</MBMultiMaster1> </MBMultiMaster1>
......
...@@ -104,12 +104,13 @@ MBExchange::MBExchange(UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, ...@@ -104,12 +104,13 @@ MBExchange::MBExchange(UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId,
ptStatistic.setTiming(stat_time * 1000); ptStatistic.setTiming(stat_time * 1000);
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout", it.getProp("recv_timeout"), 500); recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout", it.getProp("recv_timeout"), 500);
vmonit(recv_timeout);
default_timeout = conf->getArgPInt("--" + prefix + "-timeout", it.getProp("timeout"), 5000); default_timeout = conf->getArgPInt("--" + prefix + "-timeout", it.getProp("timeout"), 5000);
vmonit(default_timeout);
int tout = conf->getArgPInt("--" + prefix + "-reopen-timeout", it.getProp("reopen_timeout"), default_timeout * 2); int tout = conf->getArgPInt("--" + prefix + "-reopen-timeout", it.getProp("reopen_timeout"), default_timeout * 2);
ptReopen.setTiming(tout); ptReopen.setTiming(tout);
vmonit(recv_timeout);
int reinit_tout = conf->getArgPInt("--" + prefix + "-reinit-timeout", it.getProp("reinit_timeout"), default_timeout); int reinit_tout = conf->getArgPInt("--" + prefix + "-reinit-timeout", it.getProp("reinit_timeout"), default_timeout);
ptInitChannel.setTiming(reinit_tout); ptInitChannel.setTiming(reinit_tout);
...@@ -3179,7 +3180,7 @@ bool MBExchange::RTUDevice::checkRespond( std::shared_ptr<DebugStream>& mblog ) ...@@ -3179,7 +3180,7 @@ bool MBExchange::RTUDevice::checkRespond( std::shared_ptr<DebugStream>& mblog )
mblog4 << "(checkRespond): addr=" << ModbusRTU::addr2str(mbaddr) mblog4 << "(checkRespond): addr=" << ModbusRTU::addr2str(mbaddr)
<< " respond_id=" << resp_id << " respond_id=" << resp_id
<< " state=" << resp_state << " state=" << resp_state
<< " current=" << resp_Delay.getCurrent() << " check=" << (prev_numreply != numreply)
<< " delay_check=" << resp_Delay.get() << " delay_check=" << resp_Delay.get()
<< " [ timeout=" << resp_Delay.getOffDelay() << " [ timeout=" << resp_Delay.getOffDelay()
<< " numreply=" << numreply << " numreply=" << numreply
...@@ -3213,7 +3214,7 @@ void MBExchange::updateRespondSensors() ...@@ -3213,7 +3214,7 @@ void MBExchange::updateRespondSensors()
<< " respond_id=" << d->resp_id << " respond_id=" << d->resp_id
<< " state=" << d->resp_state << " state=" << d->resp_state
<< " [ invert=" << d->resp_invert << " [ invert=" << d->resp_invert
<< " timeout=" << d->resp_Delay.getOnDelay() << " timeout=" << d->resp_Delay.getOffDelay()
<< " numreply=" << d->numreply << " numreply=" << d->numreply
<< " prev_numreply=" << d->prev_numreply << " prev_numreply=" << d->prev_numreply
<< " ]" << " ]"
...@@ -3291,9 +3292,10 @@ UniSetTypes::SimpleInfo* MBExchange::getInfo( CORBA::Long userparam ) ...@@ -3291,9 +3292,10 @@ UniSetTypes::SimpleInfo* MBExchange::getInfo( CORBA::Long userparam )
inf << i->info << endl; inf << i->info << endl;
inf << vmon.pretty_str() << endl; inf << vmon.pretty_str() << endl;
inf << "LogServer: " << logserv_host << ":" << logserv_port << endl; inf << "LogServer: " << logserv_host << ":" << logserv_port << endl;
inf << "Parameters: reopenTimeout=" << ptReopen.getInterval()
<< endl;
inf << "Devices:" << endl; inf << "Devices: " << endl;
for( const auto& it : devices ) for( const auto& it : devices )
inf << " " << it.second->getShortInfo() << endl; inf << " " << it.second->getShortInfo() << endl;
......
...@@ -49,6 +49,11 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob ...@@ -49,6 +49,11 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
int ignore_timeout = conf->getArgPInt("--" + prefix + "-ignore-timeout", it.getProp("ignore_timeout"), ptReopen.getInterval()); int ignore_timeout = conf->getArgPInt("--" + prefix + "-ignore-timeout", it.getProp("ignore_timeout"), ptReopen.getInterval());
// Т.к. при "многоканальном" доступе к slave, смена канала должна происходит сразу после
// неудачной попытки запросов по одному из каналов, то ПЕРЕОПРЕДЕЛЯЕМ reopen, на channel-timeout..
int channelTimeout = conf->getArgPInt("--" + prefix + "-default-channel-timeout", it.getProp("channelTimeout"),default_timeout);
ptReopen.setTiming(channelTimeout);
UniXML::iterator it1(it); UniXML::iterator it1(it);
if( !it1.find("GateList") ) if( !it1.find("GateList") )
...@@ -118,10 +123,12 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob ...@@ -118,10 +123,12 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
sinf.sleepPause_usec = it1.getPIntProp("sleepPause_usec", sleepPause_usec); sinf.sleepPause_usec = it1.getPIntProp("sleepPause_usec", sleepPause_usec);
sinf.respond_invert = it1.getPIntProp("invert", 0); sinf.respond_invert = it1.getPIntProp("invert", 0);
sinf.respond_force = it1.getPIntProp("force", 0); sinf.respond_force = it1.getPIntProp("force", 0);
int tout = it1.getPIntProp("timeout", default_timeout);
int tout = it1.getPIntProp("timeout", channelTimeout);
sinf.channel_timeout = (tout >= 0 ? tout : channelTimeout);
// делаем только задержку на отпускание.. // делаем только задержку на отпускание..
sinf.respondDelay.set(0, (tout >= 0 ? tout : default_timeout)); sinf.respondDelay.set(0, sinf.channel_timeout);
sinf.force_disconnect = it.getPIntProp("persistent_connection", !force_disconnect) ? false : true; sinf.force_disconnect = it.getPIntProp("persistent_connection", !force_disconnect) ? false : true;
...@@ -165,10 +172,10 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob ...@@ -165,10 +172,10 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
checkThread = make_shared<ThreadCreator<MBTCPMultiMaster>>(this, &MBTCPMultiMaster::check_thread); checkThread = make_shared<ThreadCreator<MBTCPMultiMaster>>(this, &MBTCPMultiMaster::check_thread);
checkThread->setFinalAction(this, &MBTCPMultiMaster::final_thread); checkThread->setFinalAction(this, &MBTCPMultiMaster::final_thread);
// Т.к. при "многоканальном" доступе к slave, смена канала должна происходит сразу после // Т.к. при "многоканальном" доступе к slave, смена канала должна происходит сразу после
// неудачной попытки запросов по одному из каналов, то ПЕРЕОПРЕДЕЛЯЕМ reopen, на timeout.. // неудачной попытки запросов по одному из каналов, то ПЕРЕОПРЕДЕЛЯЕМ reopen, на channel-timeout..
ptReopen.setTiming(default_timeout); int tout = conf->getArgPInt("--" + prefix + "-default-channel-timeout", it.getProp("channelTimeout"),default_timeout);
ptReopen.setTiming(tout);
if( mblog->is_info() ) if( mblog->is_info() )
printMap(devices); printMap(devices);
...@@ -210,6 +217,10 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen ) ...@@ -210,6 +217,10 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen )
mbi = mblist.rbegin(); mbi = mblist.rbegin();
mbi->init(mblog); mbi->init(mblog);
// переопределяем timeout на данный канал
ptReopen.setTiming( mbi->channel_timeout );
mb = mbi->mbtcp; mb = mbi->mbtcp;
return mbi->mbtcp; return mbi->mbtcp;
} }
...@@ -243,6 +254,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen ) ...@@ -243,6 +254,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen )
mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl; mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl;
mb = mbi->mbtcp; mb = mbi->mbtcp;
mbi->setUse(true); mbi->setUse(true);
ptReopen.setTiming( mbi->channel_timeout );
return mbi->mbtcp; return mbi->mbtcp;
} }
...@@ -263,6 +275,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen ) ...@@ -263,6 +275,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen )
mbi = it; mbi = it;
mb = mbi->mbtcp; mb = mbi->mbtcp;
mbi->setUse(true); mbi->setUse(true);
ptReopen.setTiming( mbi->channel_timeout );
mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl; mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl;
return it->mbtcp; return it->mbtcp;
} }
...@@ -281,6 +294,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen ) ...@@ -281,6 +294,7 @@ std::shared_ptr<ModbusClient> MBTCPMultiMaster::initMB( bool reopen )
mb = mbi->mbtcp; mb = mbi->mbtcp;
mbi->ignore = false; mbi->ignore = false;
mbi->setUse(true); mbi->setUse(true);
ptReopen.setTiming( mbi->channel_timeout );
mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl; mblog4 << myname << "(initMB): SELECT CHANNEL " << mbi->ip << ":" << mbi->port << endl;
return it->mbtcp; return it->mbtcp;
} }
...@@ -416,7 +430,9 @@ void MBTCPMultiMaster::check_thread() ...@@ -416,7 +430,9 @@ void MBTCPMultiMaster::check_thread()
mblog4 << myname << "(check): " << it->myname << " " << setw(4) << ( r ? "OK" : "FAIL" ) mblog4 << myname << "(check): " << it->myname << " " << setw(4) << ( r ? "OK" : "FAIL" )
<< " [ respondDelay=" << it->respondDelay.check( r ) << " [ respondDelay=" << it->respondDelay.check( r )
<< " offDelay=" << it->respondDelay.getOffDelay() << " timeout=" << it->channel_timeout
<< " use=" << it->use
<< " ignore=" << it->ignore
<< " ]" << " ]"
<< endl; << endl;
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
в которой указываются настроечные параметры по умолчанию. в которой указываются настроечные параметры по умолчанию.
Пример: Пример:
\code \code
<MBMaster1 name="MBMaster1" polltime="200" exchangeModeID=".."> <MBMaster1 name="MBMaster1" polltime="200" channelTimeout="..." exchangeModeID="..">
<DeviceList> <DeviceList>
<item addr="0x01" respondSensor="RTU1_Not_Respond_FS" force="0" timeout="2000" invert="1"/> <item addr="0x01" respondSensor="RTU1_Not_Respond_FS" force="0" timeout="2000" invert="1"/>
<item addr="0x02" respondSensor="RTU2_Respond_FS" timeout="2000" invert="0"/> <item addr="0x02" respondSensor="RTU2_Respond_FS" timeout="2000" invert="0"/>
...@@ -63,6 +63,8 @@ ...@@ -63,6 +63,8 @@
<GateList> <GateList>
</MBMaster1> </MBMaster1>
\endcode \endcode
- \b channelTimeout - умолчательный timeout для переключения каналов. По умолчанию: берётся общий defaultTimeout.
Секция <DeviceList> позволяет задать параметры обмена с конкретным RTU-устройством. Секция <DeviceList> позволяет задать параметры обмена с конкретным RTU-устройством.
- \b addr - адрес устройства для которого, задаются параметры - \b addr - адрес устройства для которого, задаются параметры
...@@ -293,6 +295,7 @@ class MBTCPMultiMaster: ...@@ -293,6 +295,7 @@ class MBTCPMultiMaster:
bool respond_init = { false }; bool respond_init = { false };
bool respond_force = { false }; // флаг означающий принудительно обновлять значение датчика связи на каждом цикле проверки bool respond_force = { false }; // флаг означающий принудительно обновлять значение датчика связи на каждом цикле проверки
DelayTimer respondDelay; DelayTimer respondDelay;
timeout_t channel_timeout = { 0 };
inline bool operator < ( const MBSlaveInfo& mbs ) const inline bool operator < ( const MBSlaveInfo& mbs ) const
{ {
......
...@@ -4,15 +4,16 @@ ...@@ -4,15 +4,16 @@
--confile test.xml \ --confile test.xml \
--mbtcp-name MBMaster1 \ --mbtcp-name MBMaster1 \
--smemory-id SharedMemory \ --smemory-id SharedMemory \
--mbtcp-log-add-levels system,info,crit,warn,level4,level3 \ --mbtcp-log-add-levels level4 \
--mbtcp-set-prop-prefix \ --mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \ --mbtcp-filter-field rs \
--mbtcp-filter-value 5 \ --mbtcp-filter-value 5 \
--mbtcp-gateway-iaddr localhost \ --mbtcp-gateway-iaddr localhost \
--mbtcp-gateway-port 2048 \ --mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000 \ --mbtcp-recv-timeout 900 \
--mbtcp-polltime 200 \
--mbtcp-polltime 200 \
--mbtcp-force-disconnect 1 \ --mbtcp-force-disconnect 1 \
--mbtcp-polltime 3000 \
--mbtcp-force-out 1 \ --mbtcp-force-out 1 \
--ulog-add-levels system \ --ulog-add-levels system \
--mbtcp-run-logserver \ --mbtcp-run-logserver \
......
...@@ -8,9 +8,8 @@ ...@@ -8,9 +8,8 @@
--mbtcp-set-prop-prefix \ --mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \ --mbtcp-filter-field rs \
--mbtcp-filter-value 5 \ --mbtcp-filter-value 5 \
--mbtcp-recv-timeout 7000 \ --mbtcp-recv-timeout 500 \
--mbtcp-timeout 2000 \ --mbtcp-polltime 200 \
--mbtcp-polltime 2000 \
--mbtcp-force-out 1 \ --mbtcp-force-out 1 \
--mbtcp-log-add-levels level4,warn,crit \ --mbtcp-log-add-levels level4,warn,crit \
--mbtcp-persistent-connection 1 \ --mbtcp-persistent-connection 1 \
......
...@@ -187,5 +187,16 @@ TEST_CASE("[DelayTimer]: zero time", "[DelayTimer]" ) ...@@ -187,5 +187,16 @@ TEST_CASE("[DelayTimer]: zero time", "[DelayTimer]" )
msleep(40); msleep(40);
CHECK( dt.check(true) ); CHECK( dt.check(true) );
} }
SECTION("off delay")
{
DelayTimer dt(0,2000);
PassiveTimer pt;
dt.check(true);
while( dt.check(false) )
msleep(100);
REQUIRE( pt.getCurrent() >= 2000 );
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
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