Commit c12314b3 authored by Pavel Vainerman's avatar Pavel Vainerman

(MBTCPMaster): встроил возможность переключения режима работы процесса

(только чтение, только запись и т.п.)
parent c7dbb803
......@@ -15,12 +15,12 @@
<DumpStateTime name="10"/>
<SleepTickMS name="500"/>
<UniSetDebug levels="crit,warn" name="unideb"/>
<ConfDir/>
<DataDir/>
<BinDir/>
<LogDir/>
<DocDir/>
<LockDir/>
<ConfDir name="./" />
<DataDir name="./" />
<BinDir name="./" />
<LogDir name="./" />
<DocDir name="./" />
<LockDir name="./" />
<Services>
<LocalTimeService AskLifeTimeSEC="10" MaxCountTimers="100" name="TimeService"/>
<LocalInfoServer dbrepeat="1" name="InfoServer">
......@@ -105,7 +105,7 @@
<sensors name="Sensors">
<item db_ignore="1" default="1" iotype="DI" name="Input1_S" priority="Medium" textname="Команда 1"/>
<item iotype="DI" mbaddr="0x01" mbfunc="0x04" mbreg="0x02" mbtype="rtu" name="Input2_S" priority="Medium" rs="2" textname="Команда 2"/>
<item iotype="DI" mbtcp="1" name="Input3_S" priority="Medium" tcp_mbaddr="0x02" tcp_mbfunc="0x06" tcp_mbreg="0x02" tcp_mbtype="rtu" tcp_preinit="1" textname="Команда 3"/>
<item iotype="DI" mbtcp="1" name="Input3_S" priority="Medium" tcp_mbaddr="0x02" tcp_mbfunc="0x03" tcp_mbreg="0x02" tcp_mbtype="rtu" tcp_preinit="1" textname="Команда 3"/>
<item iotype="DI" mbaddr="0x02" mbfunc="0x04" mbreg="0x02" mbtype="rtu" name="Input4_S" priority="Medium" rs="2" textname="Команда 4"/>
<item iotype="DI" name="Input5_S" priority="Medium" textname="Команда 5" udp="2"/>
<item iotype="DI" name="Input6_S" priority="Medium" textname="Команда 6" udp="2">
......@@ -144,6 +144,7 @@
<item name="performance1" precision="6" noprecision="1" textname="Производительность танка 1" iotype="AI" rs="mbmaster" tcp_vtype="I2" tcp_mbtype="rtu"
tcp_mbaddr="1" tcp_mbreg="43" tcp_mbfunc="0x04"/>
<item iotype="DI" name="Message1" priority="Medium" textname="Текст сообщения 1"/>
<item iotype="AI" name="MB1_Mode_AS" priority="Medium" textname="ModbusExchange Mode"/>
</sensors>
<thresholds name="thresholds">
<sensor iotype="AI" name="AI_AS">
......
......@@ -20,6 +20,7 @@ initPause(0),
force(false),
force_out(false),
mbregFromID(false),
sidExchangeMode(DefaultObjectId),
activated(false),
noQueryOptimization(false),
force_disconnect(true),
......@@ -134,15 +135,24 @@ pollThread(0)
dlog[Debug::INFO] << myname << "(init): test_id=" << test_id << endl;
activateTimeout = conf->getArgPInt("--" + prefix + "-activate-timeout", 20000);
// initMB(false);
string emode = conf->getArgParam("--" + prefix + "-exchange-mode-id",it.getProp("exchangeModeID"));
if( !emode.empty() )
{
sidExchangeMode = conf->getSensorID(emode);
if( sidExchangeMode == DefaultObjectId )
{
ostringstream err;
err << myname << ": ID not found ('ExchangeMode') for " << emode;
dlog[Debug::CRIT] << myname << "(init): " << err.str() << endl;
throw SystemError(err.str());
}
}
activateTimeout = conf->getArgPInt("--" + prefix + "-activate-timeout", 20000);
if( dlog.debugging(Debug::INFO) )
printMap(rmap);
// abort();
poll_count = -1;
pollThread = new ThreadCreator<MBTCPMaster>(this, &MBTCPMaster::poll_thread);
}
// -----------------------------------------------------------------------------
......@@ -311,6 +321,12 @@ void MBTCPMaster::poll_thread()
{
try
{
if( sidExchangeMode != DefaultObjectId && force_out )
exchangeMode = shm->localGetValue(aitExchangeMode,sidExchangeMode);
}
catch(...){}
try
{
poll();
}
catch(...){}
......@@ -486,6 +502,21 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
}
}
if( exchangeMode == emWriteOnly && !ModbusRTU::isWriteFunction(p->mbfunc) )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(pollRTU): skip.. mode='emWriteOnly'" << endl;
return true;
}
if( exchangeMode == emReadOnly && ModbusRTU::isWriteFunction(p->mbfunc) )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(pollRTU): skip.. poll mode='emReadOnly'" << endl;
return false;
}
if( p->q_count == 0 )
{
if( dlog.debugging(Debug::INFO) )
......@@ -1149,6 +1180,20 @@ void MBTCPMaster::askSensors( UniversalIO::UIOCommand cmd )
if( force_out )
return;
try
{
if( sidExchangeMode != DefaultObjectId )
shm->askSensor(sidExchangeMode,cmd);
}
catch( UniSetTypes::Exception& ex )
{
dlog[Debug::WARN] << myname << "(askSensors): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::WARN] << myname << "(askSensors): 'sidExchangeMode' catch..." << std::endl;
}
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
......@@ -1181,6 +1226,14 @@ void MBTCPMaster::sensorInfo( UniSetTypes::SensorMessage* sm )
if( force_out )
return;
if( sm->id == sidExchangeMode )
{
exchangeMode = sm->value;
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(sensorInfo): exchange MODE=" << sm->value << std::endl;
return;
}
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
......@@ -1829,6 +1882,7 @@ bool MBTCPMaster::initMTRitem( UniXML_iterator& it, RegInfo* p )
void MBTCPMaster::initIterators()
{
shm->initAIterator(aitHeartBeat);
shm->initAIterator(aitExchangeMode);
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
......@@ -2133,6 +2187,30 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
if( !save && write_only )
return;
if( save && exchangeMode == emReadOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emReadOnly' " << endl;
return;
}
if( !save && exchangeMode == emWriteOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emWriteOnly' " << endl;
return;
}
if( save && exchangeMode == emSkipSaveToSM )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " skip... mode='emSkipSaveToSM' " << endl;
return;
}
// если требуется инициализация и она ещё не произведена,
// то игнорируем
if( save && !r->mb_initOK )
......@@ -2447,6 +2525,30 @@ void MBTCPMaster::updateMTR( RegMap::iterator& rit )
using namespace ModbusRTU;
bool save = isWriteFunction( r->mbfunc );
if( save && exchangeMode == emReadOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(updateMTR):"
<< " skip... mode=emReadOnly " << endl;
return;
}
if( !save && exchangeMode == emWriteOnly )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(updateMTR):"
<< " skip... mode=emWriteOnly " << endl;
return;
}
if( save && exchangeMode == emSkipSaveToSM )
{
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << myname << "(updateMTR):"
<< " skip... mode=emSkipSaveToSM " << endl;
return;
}
{
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
{
......
......@@ -25,6 +25,7 @@
- \ref sec_MBTCP_Comm
- \ref sec_MBTCP_Conf
- \ref sec_MBTCP_ConfList
- \ref sec_MBTCP_ExchangeMode
\section sec_MBTCP_Comm Общее описание ModbusTCP master
Класс реализует процесс обмена (опрос/запись) с RTU-устройствами,
......@@ -163,6 +164,20 @@
\warning Регистр должен быть уникальным. И может повторятся только если указан параметр \a nbit или \a nbyte.
\section sec_MBTCP_ExchangeMode Управление режимом работы MBTCPMaster
В MBTCPMaster заложена возможность управлять режимом работы процесса. Поддерживаются
следующие режимы:
- \b emNone - нормальная работа (по умолчанию)
- \b emWriteOnly - "только посылка данных" (работают только write-функции)
- \b emReadOnly - "только чтение" (работают только read-функции)
- \b emSkipSaveToSM - "не записывать данные в SM", это особый режим, похожий на \b emWriteOnly,
но отличие в том, что при этом режиме ведётся полноценый обмен (и read и write),
только реально данные не записываются в SharedMemory(SM).
Режимы переключаются при помощи датчика, который можно задать либо аргументом командной строки
\b --prefix-exchange-mode-id либо в конф. файле параметром \b echangeModeID="". Константы определяющие режимы объявлены в MBTCPMaster::ExchangeMode.
*/
// -----------------------------------------------------------------------------
/*!
......@@ -194,6 +209,15 @@ class MBTCPMaster:
static const int NoSafetyState=-1;
/*! Режимы работы процесса обмена */
enum ExchangeMode
{
emNone, /*!< нормальная работа (по умолчанию) */
emWriteOnly, /*!< "только посылка данных" (работают только write-функции) */
emReadOnly, /*!< "только чтение" (работают только read-функции) */
emSkipSaveToSM /*!< не писать данные в SM (при этом работают и read и write функции */
};
enum Timer
{
tmExchange
......@@ -428,6 +452,10 @@ class MBTCPMaster:
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::ObjectId sidExchangeMode; /*!< иденидентификатор для датчика режима работы */
IOController::AIOStateList::iterator aitExchangeMode;
long exchangeMode; /*!< режим работы см. ExchangeMode */
UniSetTypes::uniset_mutex actMutex;
bool activated;
int activateTimeout;
......
#!/bin/sh
./uniset-start.sh -g ./uniset-mbtcpmaster \
./uniset-start.sh -f ./uniset-mbtcpmaster \
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
......@@ -10,6 +10,8 @@
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000 \
--mbtcp-force-disconnect 1
--mbtcp-force-disconnect 1 \
--mbtcp-polltime 5000 \
--mbtcp-exchange-mode-id MB1_Mode_AS
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
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