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