Commit 902e3a76 authored by Pavel Vainerman's avatar Pavel Vainerman

(Modbus): продолжаю выносить код в базовый класс

parent 78333cac
......@@ -181,6 +181,7 @@ AC_CONFIG_FILES([Makefile
extensions/IOControl/libUniSetIOControl.pc
extensions/RTUExchange/Makefile
extensions/RTUExchange/libUniSetRTU.pc
extensions/ModbusMaster/Makefile
extensions/ModbusSlave/Makefile
extensions/ModbusSlave/libUniSetMBSlave.pc
extensions/MBTCPMaster/Makefile
......
......@@ -8,16 +8,18 @@ libUniSetMBTCPMaster_la_LDFLAGS = -version-info $(UMBTCP_VER)
libUniSetMBTCPMaster_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(top_builddir)/extensions/ModbusMaster/libMBMaster.la \
$(SIGC_LIBS)
libUniSetMBTCPMaster_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory -I$(top_builddir)/extensions/ModbusMaster $(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_SOURCES = MBTCPMaster.cc
@PACKAGE@_mbtcpmaster_SOURCES = main.cc
@PACKAGE@_mbtcpmaster_LDADD = libUniSetMBTCPMaster.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(top_builddir)/extensions/ModbusMaster/libMBMaster.la \
$(SIGC_LIBS)
@PACKAGE@_mbtcpmaster_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
@PACKAGE@_mbtcpmaster_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory -I$(top_builddir)/extensions/ModbusMaster $(SIGC_CFLAGS)
# install
devel_include_HEADERS = *.h
......
#!/bin/sh
./uniset-start.sh -g ./uniset-mbtcpmaster \
./uniset-start.sh -f ./uniset-mbtcpmaster \
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
......
......@@ -3,7 +3,7 @@
############################################################################
if HAVE_EXTENTIONS
SUBDIRS = lib include SharedMemory IOControl RTUExchange LogicProcessor \
SUBDIRS = lib include ModbusMaster SharedMemory IOControl RTUExchange LogicProcessor \
ModbusSlave MBTCPMaster SMViewer UniNetwork UNet2 DBServer-MySQL tests
#SMDBServer
#SharedMemoryPlus
......
......@@ -1547,6 +1547,69 @@ void MBExchange::updateMTR( RegMap::iterator& rit )
}
}
// -----------------------------------------------------------------------------
void MBExchange::updateRTU188( RegMap::iterator& it )
{
RegInfo* r(it->second);
if( !r->dev->rtu )
return;
using namespace ModbusRTU;
// bool save = false;
if( isWriteFunction(r->mbfunc) )
{
// save = true;
cerr << myname << "(updateRTU188): write reg(" << dat2str(r->mbreg) << ") to RTU188 NOT YET!!!" << endl;
return;
}
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
{
try
{
if( it->stype == UniversalIO::DigitalInput )
{
bool set = r->dev->rtu->getState(r->rtuJack,r->rtuChan,it->stype);
IOBase::processingAsDI( &(*it), set, shm, force );
continue;
}
if( it->stype == UniversalIO::AnalogInput )
{
long val = r->dev->rtu->getInt(r->rtuJack,r->rtuChan,it->stype);
IOBase::processingAsAI( &(*it),val, shm, force );
continue;
}
}
catch(IOController_i::NameNotFound &ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): (BadRange)..." << endl;
}
catch( Exception& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): catch ..." << endl;
}
}
}
// -----------------------------------------------------------------------------
MBExchange::RTUDevice* MBExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML_iterator& xmlit )
{
RTUDeviceMap::iterator it = mp.find(a);
......
......@@ -17,9 +17,9 @@
#include "IOBase.h"
#include "VTypes.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "modbus/ModbusClient.h"
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*!
\par Базовый класс для реализация обмена по протоколу Modbus [RTU|TCP].
*/
......@@ -106,8 +106,8 @@ class MBExchange:
RTUDevice* dev;
// only for RTU188
// RTUStorage::RTUJack rtuJack;
// int rtuChan;
RTUStorage::RTUJack rtuJack;
int rtuChan;
// only for MTR
MTR::MTRType mtrType; /*!< тип регистра (согласно спецификации на MTR) */
......@@ -143,7 +143,9 @@ class MBExchange:
resp_invert(false),
resp_real(false),
resp_init(false),
ask_every_reg(false)
ask_every_reg(false),
speed(ComPort::ComSpeed38400),
rtu(0)
{
resp_trTimeout.change(false);
}
......@@ -167,6 +169,9 @@ class MBExchange:
// return TRUE if state changed
bool checkRespond();
// специфические поля для RS
ComPort::Speed speed;
RTUStorage* rtu;
};
friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
......@@ -221,14 +226,15 @@ class MBExchange:
InitList initRegList; /*!< список регистров для инициализации */
UniSetTypes::uniset_mutex pollMutex;
virtual ModbusClient* initMB( bool reopen=false )=0;
virtual ModbusClient* initMB( bool reopen=false )= 0;
void poll();
virtual void poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
void updateSM();
void updateRTU(RegMap::iterator& it);
void updateMTR(RegMap::iterator& it);
void updateRTU188(RegMap::iterator& it);
void updateRSProperty( RSProperty* p, bool write_only=false );
bool checkUpdateSM( bool wrFunc );
......@@ -250,10 +256,11 @@ class MBExchange:
RSProperty* addProp( PList& plist, RSProperty& p );
bool initMTRitem( UniXML_iterator& it, RegInfo* p );
bool initRTU188item( UniXML_iterator& it, RegInfo* p );
bool initRSProperty( RSProperty& p, UniXML_iterator& it );
bool initRegInfo( RegInfo* r, UniXML_iterator& it, RTUDevice* dev );
bool initRTUDevice( RTUDevice* d, UniXML_iterator& it );
bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
void rtuQueryOptimization( RTUDeviceMap& m );
......
noinst_LTLIBRARIES = libMBMaster.la
libMBMaster_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
libMBMaster_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
libMBMaster_la_SOURCES = MBExchange.cc RTUStorage.cc
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
all-local:
ln -sf ../ModbusMaster/$(devel_include_HEADERS) ../include
......@@ -8,16 +8,18 @@ libUniSetRTU_la_LDFLAGS = -version-info $(URTU_VER)
libUniSetRTU_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(top_builddir)/extensions/ModbusMaster/libMBMaster.la \
$(SIGC_LIBS)
libUniSetRTU_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
libUniSetRTU_la_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory -I$(top_builddir)/extensions/ModbusMaster $(SIGC_CFLAGS)
libUniSetRTU_la_SOURCES = RTUExchange.cc
@PACKAGE@_rtuexchange_SOURCES = rtuexchange.cc
@PACKAGE@_rtuexchange_LDADD = libUniSetRTU.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(top_builddir)/extensions/ModbusMaster/libMBMaster.la \
$(SIGC_LIBS)
@PACKAGE@_rtuexchange_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory $(SIGC_CFLAGS)
@PACKAGE@_rtuexchange_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/SharedMemory -I$(top_builddir)/extensions/ModbusMaster $(SIGC_CFLAGS)
@PACKAGE@_mtr_conv_SOURCES = mtrconv.cc
@PACKAGE@_mtr_conv_LDADD = $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
......@@ -31,8 +33,10 @@ libUniSetRTU_la_SOURCES = RTUStorage.cc RTUExchange.cc
@PACKAGE@_vtconv_LDADD = $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
@PACKAGE@_vtconv_CXXFLAGS = -I$(top_builddir)/extensions/include
@PACKAGE@_rtu188_state_LDADD = libUniSetRTU.la $(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la
@PACKAGE@_rtu188_state__CXXFLAGS = -I$(top_builddir)/extensions/include
@PACKAGE@_rtu188_state_LDADD = libUniSetRTU.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/ModbusMaster/libMBMaster.la
@PACKAGE@_rtu188_state_CXXFLAGS = -I$(top_builddir)/extensions/include -I$(top_builddir)/extensions/ModbusMaster
@PACKAGE@_rtu188_state_SOURCES = rtustate.cc
# install
......
......@@ -11,13 +11,15 @@ using namespace UniSetExtensions;
RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, SharedMemory* ic,
const std::string prefix_ ):
MBExchange(objId,shmId,ic,prefix_),
mb(0),
mbrtu(0),
defSpeed(ComPort::ComSpeed0),
use485F(false),
transmitCtl(false),
rs_pre_clean(false),
allNotRespond(false)
{
prop_prefix = "";
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(RTUExchange): objId=-1?!! Use --" + prefix + "-name" );
......@@ -65,7 +67,7 @@ allNotRespond(false)
// -----------------------------------------------------------------------------
RTUExchange::~RTUExchange()
{
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
for( MBExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
if( it1->second->rtu )
{
......@@ -80,58 +82,57 @@ RTUExchange::~RTUExchange()
delete it1->second;
}
delete mb;
delete mbrtu;
}
// -----------------------------------------------------------------------------
void RTUExchange::initMB( bool reopen )
ModbusClient* RTUExchange::initMB( bool reopen )
{
if( !file_exist(devname) )
{
if( mb )
if( mbrtu )
{
delete mb;
delete mbrtu;
mb = 0;
mbrtu = 0;
}
return;
return mbrtu;
}
if( mb )
if( mbrtu )
{
if( !reopen )
return;
return mbrtu;
delete mb;
delete mbrtu;
mbrtu = 0;
mb = 0;
}
try
{
mb = new ModbusRTUMaster(devname,use485F,transmitCtl);
mbrtu = new ModbusRTUMaster(devname,use485F,transmitCtl);
if( defSpeed != ComPort::ComSpeed0 )
mb->setSpeed(defSpeed);
mbrtu->setSpeed(defSpeed);
// mb->setLog(dlog);
if( recv_timeout > 0 )
mb->setTimeout(recv_timeout);
mbrtu->setTimeout(recv_timeout);
mb->setSleepPause(sleepPause_usec);
mbrtu->setSleepPause(sleepPause_usec);
dlog[Debug::INFO] << myname << "(init): dev=" << devname << " speed=" << ComPort::getSpeed(defSpeed) << endl;
}
catch(...)
{
if( mb )
delete mb;
mb = 0;
if( mbrtu )
delete mbrtu;
mbrtu = 0;
}
}
// -----------------------------------------------------------------------------
void RTUExchange::timerInfo( TimerMessage *tm )
{
if( tm->id == tmExchange )
step();
mb = mbrtu;
return mbrtu;
}
// -----------------------------------------------------------------------------
void RTUExchange::step()
......@@ -161,23 +162,23 @@ void RTUExchange::poll()
initMB(false);
if( !mb )
{
for( RTUExchange::RTUDeviceMap::iterator it=rmap.begin(); it!=rmap.end(); ++it )
for( MBExchange::RTUDeviceMap::iterator it=rmap.begin(); it!=rmap.end(); ++it )
it->second->resp_real = false;
}
updateSM();
return;
}
ComPort::Speed s = mb->getSpeed();
ComPort::Speed s = mbrtu->getSpeed();
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
for( MBExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
if( d->speed != s )
{
s = d->speed;
mb->setSpeed(d->speed);
mbrtu->setSpeed(d->speed);
}
if( dlog.debugging(Debug::INFO) )
......@@ -200,7 +201,7 @@ void RTUExchange::poll()
if( rs_pre_clean )
mb->cleanupChannel();
d->rtu->poll(mb);
d->rtu->poll(mbrtu);
d->resp_real = true;
}
catch( ModbusRTU::mbException& ex )
......@@ -256,7 +257,7 @@ void RTUExchange::poll()
updateSM();
// check thresholds
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
for( MBExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
......@@ -270,209 +271,6 @@ void RTUExchange::poll()
// printMap(rmap);
}
// -----------------------------------------------------------------------------
bool RTUExchange::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{
RegInfo* p(it->second);
if( dlog.debugging(Debug::LEVEL3) )
{
dlog[Debug::LEVEL3] << myname << "(pollRTU): poll "
<< " mbaddr=" << ModbusRTU::addr2str(dev->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " mboffset=" << p->offset
<< " mbfunc=" << p->mbfunc
<< " q_count=" << p->q_count
<< " mb_init=" << p->mb_init
<< endl;
}
if( !checkPoll(ModbusRTU::isWriteFunction(p->mbfunc)) )
return true;
if( p->q_count == 0 )
{
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << myname << "(pollRTU): q_count=0 for mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " IGNORE register..." << endl;
return false;
}
switch( p->mbfunc )
{
case ModbusRTU::fnReadInputRegisters:
{
ModbusRTU::ReadInputRetMessage ret = mb->read04(dev->mbaddr,p->mbreg+p->offset,p->q_count);
for( int i=0; i<p->q_count; i++,it++ )
it->second->mbval = ret.data[i];
it--;
}
break;
case ModbusRTU::fnReadOutputRegisters:
{
ModbusRTU::ReadOutputRetMessage ret = mb->read03(dev->mbaddr, p->mbreg+p->offset,p->q_count);
for( int i=0; i<p->q_count; i++,it++ )
it->second->mbval = ret.data[i];
it--;
}
break;
case ModbusRTU::fnReadInputStatus:
{
ModbusRTU::ReadInputStatusRetMessage ret = mb->read02(dev->mbaddr,p->mbreg+p->offset,p->q_count);
int m=0;
for( int i=0; i<ret.bcnt; i++ )
{
ModbusRTU::DataBits b(ret.data[i]);
for( int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
it->second->mbval = b[k];
}
it--;
}
break;
case ModbusRTU::fnReadCoilStatus:
{
ModbusRTU::ReadCoilRetMessage ret = mb->read01(dev->mbaddr,p->mbreg+p->offset,p->q_count);
int m = 0;
for( int i=0; i<ret.bcnt; i++ )
{
ModbusRTU::DataBits b(ret.data[i]);
for( int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
it->second->mbval = b[k] ? 1 : 0;
}
it--;
}
break;
case ModbusRTU::fnWriteOutputSingleRegister:
{
if( p->q_count != 1 )
{
dlog[Debug::CRIT] << myname << "(pollRTU): mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " IGNORE WRITE SINGLE REGISTER (0x06) q_count=" << p->q_count << " ..." << endl;
return false;
}
if( !p->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg) << endl;
ModbusRTU::ReadInputRetMessage ret1 = mb->read04(dev->mbaddr,p->mb_init_mbreg,1);
p->mbval = ret1.data[0];
p->sm_init = true;
return true;
}
// cerr << "**** mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU::WriteSingleOutputRetMessage ret = mb->write06(dev->mbaddr,p->mbreg+p->offset,p->mbval);
}
break;
case ModbusRTU::fnWriteOutputRegisters:
{
ModbusRTU::WriteOutputMessage msg(dev->mbaddr,p->mbreg+p->offset);
for( int i=0; i<p->q_count; i++,it++ )
{
if( !it->second->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg) << endl;
ModbusRTU::ReadOutputRetMessage ret1 = mb->read03(dev->mbaddr,it->second->mb_init_mbreg,1);
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg)
// << " mbval=" << ret1.data[0] << endl;
it->second->mbval = ret1.data[0];
it->second->sm_init = true;
}
msg.addData(it->second->mbval);
}
it--;
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
}
break;
case ModbusRTU::fnForceSingleCoil:
{
if( p->q_count != 1 )
{
dlog[Debug::CRIT] << myname << "(pollRTU): mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " IGNORE FORCE SINGLE COIL (0x05) q_count=" << p->q_count << " ..." << endl;
return false;
}
if( !p->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg)
// << " init mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg) << endl;
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,p->mb_init_mbreg,1);
ModbusRTU::DataBits b(ret1.data[0]);
// cerr << "******* mb_init_mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg)
// << " read val=" << (int)b[0] << endl;
p->mbval = b[0];
p->sm_init = true;
return true;
}
// cerr << "****(coil) mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU::ForceSingleCoilRetMessage ret = mb->write05(dev->mbaddr,p->mbreg+p->offset,p->mbval);
}
break;
case ModbusRTU::fnForceMultipleCoils:
{
if( !p->mb_init )
{
// every register ask... (for mb_init_mbreg no some)
for( int i=0; i<p->q_count; i++,it++ )
{
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,it->second->mb_init_mbreg,1);
ModbusRTU::DataBits b(ret1.data[0]);
it->second->mbval = b[0] ? 1 : 0;
it->second->sm_init = true;
}
/*
// alone query for all register (if mb_init_mbreg ++ )
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,p->mb_init_mbreg,p->q_count);
int m=0;
for( int i=0; i<ret1.bcnt; i++ )
{
ModbusRTU::DataBits b(ret1.data[i]);
for( int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
{
it->second->mbval = b[k] ? 1 : 0;
it->second->sm_init = true;
}
}
*/
p->sm_init = true;
it--;
return true;
}
ModbusRTU::ForceCoilsMessage msg(dev->mbaddr,p->mbreg+p->offset);
for( int i=0; i<p->q_count; i++,it++ )
msg.addBit( (it->second->mbval ? true : false) );
it--;
// cerr << "*********** (write multiple): " << msg << endl;
ModbusRTU::ForceCoilsRetMessage ret = mb->write0F(msg);
}
break;
default:
{
if( dlog.debugging(Debug::WARN) )
dlog[Debug::WARN] << myname << "(pollRTU): mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " IGNORE mfunc=" << (int)p->mbfunc << " ..." << endl;
return false;
}
break;
}
return true;
}
// -----------------------------------------------------------------------------
bool RTUExchange::RTUDevice::checkRespond()
{
bool prev = resp_state;
......@@ -500,1570 +298,65 @@ bool RTUExchange::RTUDevice::checkRespond()
return ( prev != resp_state );
}
// -----------------------------------------------------------------------------
void RTUExchange::updateSM()
void RTUExchange::help_print( int argc, const char* const* argv )
{
allNotRespond = true;
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
if( dlog.debugging(Debug::LEVEL4) )
{
dlog[Debug::LEVEL4] << "check respond addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " respond_id=" << d->resp_id
<< " real=" << d->resp_real
<< " state=" << d->resp_state
<< endl;
}
if( d->resp_real )
allNotRespond = false;
// update respond sensors...
if( d->checkRespond() && d->resp_id != DefaultObjectId )
{
try
{
bool set = d->resp_invert ? !d->resp_state : d->resp_state;
shm->localSaveState(d->resp_dit,d->resp_id,set,getId());
}
catch(Exception& ex)
{
dlog[Debug::CRIT] << myname
<< "(step): (respond) " << ex << std::endl;
}
}
// cerr << "*********** allNotRespond=" << allNotRespond << endl;
// update values...
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
try
{
if( d->dtype == dtRTU )
updateRTU(it);
else if( d->dtype == dtMTR )
updateMTR(it);
else if( d->dtype == dtRTU188 )
updateRTU188(it);
}
catch(IOController_i::NameNotFound &ex)
{
dlog[Debug::LEVEL3] << myname << "(updateSM):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateSM):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
dlog[Debug::LEVEL3] << myname << "(updateSM): (BadRange)..." << endl;
}
catch( Exception& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateSM): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::LEVEL3] << myname << "(updateSM): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::LEVEL3] << myname << "(updateSM): catch ..." << endl;
}
if( it==d->regmap.end() )
break;
}
}
cout << "Default: prefix='rs'" << endl;
MBExchange::help_print(argc,argv);
// cout << " Настройки протокола RS: " << endl;
cout << "--prefix-dev devname - файл устройства" << endl;
cout << "--prefix-speed - Скорость обмена (9600,19920,38400,57600,115200)." << endl;
cout << "--prefix-my-addr - адрес текущего узла" << endl;
cout << "--prefix-recv-timeout - Таймаут на ожидание ответа." << endl;
}
// -----------------------------------------------------------------------------
void RTUExchange::processingMessage(UniSetTypes::VoidMessage *msg)
RTUExchange* RTUExchange::init_rtuexchange( int argc, const char* const* argv, UniSetTypes::ObjectId icID,
SharedMemory* ic, const std::string prefix )
{
try
{
switch(msg->type)
{
case UniSetTypes::Message::SysCommand:
{
UniSetTypes::SystemMessage sm( msg );
sysCommand( &sm );
}
break;
case Message::Timer:
{
TimerMessage tm(msg);
timerInfo(&tm);
}
break;
case Message::SensorInfo:
{
SensorMessage sm( msg );
sensorInfo(&sm);
}
break;
default:
break;
}
}
catch( SystemError& ex )
{
dlog[Debug::CRIT] << myname << "(SystemError): " << ex << std::endl;
// throw SystemError(ex);
}
catch( Exception& ex )
string name = conf->getArgParam("--" + prefix + "-name","RTUExchange1");
if( name.empty() )
{
dlog[Debug::CRIT] << myname << "(processingMessage): " << ex << std::endl;
cerr << "(rtuexchange): Unknown 'name'. Use --" << prefix << "-name" << endl;
return 0;
}
catch(...)
ObjectId ID = conf->getObjectID(name);
if( ID == UniSetTypes::DefaultObjectId )
{
dlog[Debug::CRIT] << myname << "(processingMessage): catch ...\n";
cerr << "(rtuexchange): Not found ID for '" << name
<< "'!"
<< " in section <" << conf->getObjectsSection() << ">" << endl;
return 0;
}
}
// -----------------------------------------------------------------------------
void RTUExchange::sysCommand( UniSetTypes::SystemMessage *sm )
{
switch( sm->command )
{
case SystemMessage::StartUp:
{
if( rmap.empty() )
{
dlog[Debug::CRIT] << myname << "(sysCommand): ************* rmap EMPTY! terminated... *************" << endl;
raise(SIGTERM);
return;
}
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << myname << "(sysCommand): rmap size= " << rmap.size() << endl;
if( !shm->isLocalwork() )
initDeviceList();
waitSMReady();
// подождать пока пройдёт инициализация датчиков
// см. activateObject()
msleep(initPause);
PassiveTimer ptAct(activateTimeout);
while( !activated && !ptAct.checkTime() )
{
cout << myname << "(sysCommand): wait activate..." << endl;
msleep(300);
if( activated )
break;
}
if( !activated )
dlog[Debug::CRIT] << myname << "(sysCommand): ************* don`t activate?! ************" << endl;
{
UniSetTypes::uniset_mutex_lock l(mutex_start, 10000);
askSensors(UniversalIO::UIONotify);
initOutput();
}
// начальная инициализация
if( !force )
{
uniset_mutex_lock l(pollMutex,2000);
force = true;
poll();
force = false;
}
askTimer(tmExchange,polltime);
break;
}
case SystemMessage::FoldUp:
case SystemMessage::Finish:
askSensors(UniversalIO::UIODontNotify);
break;
case SystemMessage::WatchDog:
{
// ОПТИМИЗАЦИЯ (защита от двойного перезаказа при старте)
// Если идёт локальная работа
// (т.е. RTUExchange запущен в одном процессе с SharedMemory2)
// то обрабатывать WatchDog не надо, т.к. мы и так ждём готовности SM
// при заказе датчиков, а если SM вылетит, то вместе с этим процессом(RTUExchange)
if( shm->isLocalwork() )
break;
askSensors(UniversalIO::UIONotify);
initOutput();
if( !force )
{
uniset_mutex_lock l(pollMutex,2000);
force = true;
poll();
force = false;
}
}
break;
case SystemMessage::LogRotate:
{
// переоткрываем логи
unideb << myname << "(sysCommand): logRotate" << std::endl;
string fname = unideb.getLogFile();
if( !fname.empty() )
{
unideb.logFile(fname);
unideb << myname << "(sysCommand): ***************** UNIDEB LOG ROTATE *****************" << std::endl;
}
dlog << myname << "(sysCommand): logRotate" << std::endl;
fname = dlog.getLogFile();
if( !fname.empty() )
{
dlog.logFile(fname);
dlog << myname << "(sysCommand): ***************** dlog LOG ROTATE *****************" << std::endl;
}
}
break;
default:
break;
}
}
// ------------------------------------------------------------------------------------------
void RTUExchange::initOutput()
{
dlog[Debug::INFO] << "(rtuexchange): name = " << name << "(" << ID << ")" << endl;
return new RTUExchange(ID,icID,ic,prefix);
}
// ------------------------------------------------------------------------------------------
void RTUExchange::askSensors( UniversalIO::UIOCommand cmd )
// -----------------------------------------------------------------------------
bool RTUExchange::initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it )
{
if( !shm->waitSMworking(test_id,activateTimeout,50) )
{
ostringstream err;
err << myname
<< "(askSensors): Не дождались готовности(work) SharedMemory к работе в течение "
<< activateTimeout << " мсек";
if( !MBExchange::initDeviceInfo(m,a,it) )
return false;
dlog[Debug::CRIT] << err.str() << endl;
kill(SIGTERM,getpid()); // прерываем (перезапускаем) процесс...
throw SystemError(err.str());
}
if( force_out )
return;
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
RTUDeviceMap::iterator d = m.find(a);
if( d == m.end() )
{
RTUDevice* d(it1->second);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
if( !isWriteFunction(it->second->mbfunc) )
continue;
for( PList::iterator i=it->second->slst.begin(); i!=it->second->slst.end(); ++i )
{
try
{
shm->askSensor(i->si.id,cmd);
}
catch( UniSetTypes::Exception& ex )
{
dlog[Debug::WARN] << myname << "(askSensors): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::WARN] << myname << "(askSensors): catch..." << std::endl;
}
}
}
dlog[Debug::WARN] << myname << "(initDeviceInfo): not found device for addr=" << ModbusRTU::addr2str(a) << endl;
return false;
}
}
// ------------------------------------------------------------------------------------------
void RTUExchange::sensorInfo( UniSetTypes::SensorMessage* sm )
{
if( force_out )
return;
MBExchange::sensorInfo(sm);
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
string s = it.getProp("speed");
if( !s.empty() )
{
RTUDevice* d(it1->second);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
d->second->speed = ComPort::getSpeed(s);
if( d->second->speed == ComPort::ComSpeed0 )
{
if( !isWriteFunction(it->second->mbfunc) )
continue;
for( PList::iterator i=it->second->slst.begin(); i!=it->second->slst.end(); ++i )
{
if( sm->id == i->si.id && sm->node == i->si.node )
{
if( dlog.debugging(Debug::INFO) )
{
dlog[Debug::INFO] << myname<< "(sensorInfo): si.id=" << sm->id
<< " reg=" << ModbusRTU::dat2str(i->reg->mbreg)
<< " val=" << sm->value
<< " mb_init=" << i->reg->mb_init << endl;
}
if( !i->reg->mb_init )
continue;
i->value = sm->value;
updateRSProperty( &(*i),true);
return;
}
}
d->second->speed = defSpeed;
dlog[Debug::CRIT] << myname << "(initDeviceInfo): Unknown speed=" << s <<
" for addr=" << ModbusRTU::addr2str(a) << endl;
return false;
}
}
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::activateObject()
{
// блокирование обработки Starsp
// пока не пройдёт инициализация датчиков
// см. sysCommand()
{
activated = false;
UniSetTypes::uniset_mutex_lock l(mutex_start, 5000);
UniSetObject_LT::activateObject();
if( !shm->isLocalwork() )
rtuQueryOptimization(rmap);
initIterators();
activated = true;
}
return true;
}
// ------------------------------------------------------------------------------------------
void RTUExchange::sigterm( int signo )
{
cerr << myname << ": ********* SIGTERM(" << signo <<") ********" << endl;
MBExchange::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
RTUExchange::RTUDevice* RTUExchange::addDev( RTUDeviceMap& mp, ModbusRTU::ModbusAddr a, UniXML_iterator& xmlit )
{
RTUDeviceMap::iterator it = mp.find(a);
if( it != mp.end() )
{
DeviceType dtype = getDeviceType(xmlit.getProp("mbtype"));
if( it->second->dtype != dtype )
{
dlog[Debug::CRIT] << myname << "(addDev): OTHER mbtype=" << dtype << " for " << xmlit.getProp("name")
<< ". Already used devtype=" << it->second->dtype
<< " for mbaddr=" << ModbusRTU::addr2str(it->second->mbaddr)
<< endl;
return 0;
}
dlog[Debug::INFO] << myname << "(addDev): device for addr=" << ModbusRTU::addr2str(a)
<< " already added. Ignore device params for " << xmlit.getProp("name") << " ..." << endl;
return it->second;
}
RTUExchange::RTUDevice* d = new RTUExchange::RTUDevice();
d->mbaddr = a;
if( !initRTUDevice(d,xmlit) )
{
delete d;
return 0;
}
mp.insert(RTUDeviceMap::value_type(a,d));
return d;
}
// ------------------------------------------------------------------------------------------
RTUExchange::RegInfo* RTUExchange::addReg( RegMap& mp, ModbusRTU::ModbusData r,
UniXML_iterator& xmlit, RTUExchange::RTUDevice* dev,
RTUExchange::RegInfo* rcopy )
{
RegMap::iterator it = mp.find(r);
if( it != mp.end() )
{
if( !it->second->dev )
{
dlog[Debug::CRIT] << myname << "(addReg): for reg=" << ModbusRTU::dat2str(r)
<< " dev=0!!!! " << endl;
return 0;
}
if( it->second->dev->dtype != dev->dtype )
{
dlog[Debug::CRIT] << myname << "(addReg): OTHER mbtype=" << dev->dtype << " for reg=" << ModbusRTU::dat2str(r)
<< ". Already used devtype=" << it->second->dev->dtype << " for " << it->second->dev << endl;
return 0;
}
if( dlog.debugging(Debug::INFO) )
{
dlog[Debug::INFO] << myname << "(addReg): reg=" << ModbusRTU::dat2str(r)
<< " already added. Ignore register params for " << xmlit.getProp("name") << " ..." << endl;
}
it->second->rit = it;
return it->second;
}
RTUExchange::RegInfo* ri;
if( rcopy )
{
ri = new RTUExchange::RegInfo(*rcopy);
ri->slst.clear();
ri->mbreg = r;
}
else
{
ri = new RTUExchange::RegInfo();
if( !initRegInfo(ri,xmlit,dev) )
{
delete ri;
return 0;
}
ri->mbreg = r;
}
mp.insert(RegMap::value_type(r,ri));
ri->rit = mp.find(r);
return ri;
}
// ------------------------------------------------------------------------------------------
RTUExchange::RSProperty* RTUExchange::addProp( PList& plist, RSProperty& p )
{
for( PList::iterator it=plist.begin(); it!=plist.end(); ++it )
{
if( it->si.id == p.si.id && it->si.node == p.si.node )
return &(*it);
}
plist.push_back(p);
PList::iterator it = plist.end();
it--;
return &(*it);
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initRSProperty( RSProperty& p, UniXML_iterator& it )
{
if( !IOBase::initItem(&p,it,shm,&dlog,myname) )
return false;
string sbit(it.getProp("nbit"));
if( !sbit.empty() )
{
p.nbit = UniSetTypes::uni_atoi(sbit);
if( p.nbit < 0 || p.nbit >= ModbusRTU::BitsPerData )
{
dlog[Debug::CRIT] << myname << "(initRSProperty): BAD nbit=" << p.nbit
<< ". (0 >= nbit < " << ModbusRTU::BitsPerData <<")." << endl;
return false;
}
}
if( p.nbit > 0 &&
( p.stype == UniversalIO::AnalogInput ||
p.stype == UniversalIO::AnalogOutput ) )
{
dlog[Debug::WARN] << "(initRSProperty): (ignore) uncorrect param`s nbit>1 (" << p.nbit << ")"
<< " but iotype=" << p.stype << " for " << it.getProp("name") << endl;
}
string sbyte(it.getProp("nbyte"));
if( !sbyte.empty() )
{
p.nbyte = UniSetTypes::uni_atoi(sbyte);
if( p.nbyte < 0 || p.nbyte > VTypes::Byte::bsize )
{
dlog[Debug::CRIT] << myname << "(initRSProperty): BAD nbyte=" << p.nbyte
<< ". (0 >= nbyte < " << VTypes::Byte::bsize << ")." << endl;
return false;
}
}
string vt(it.getProp("vtype"));
if( vt.empty() )
{
p.rnum = VTypes::wsize(VTypes::vtUnknown);
p.vType = VTypes::vtUnknown;
}
else
{
VTypes::VType v(VTypes::str2type(vt));
if( v == VTypes::vtUnknown )
{
dlog[Debug::CRIT] << myname << "(initRSProperty): Unknown rtuVType=" << vt << " for "
<< it.getProp("name")
<< endl;
return false;
}
p.vType = v;
p.rnum = VTypes::wsize(v);
}
return true;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initRegInfo( RegInfo* r, UniXML_iterator& it, RTUExchange::RTUDevice* dev )
{
r->dev = dev;
r->mbval = it.getIntProp("default");
r->offset= it.getIntProp("mboffset");
r->mb_init = it.getIntProp("mbinit");
if( dev->dtype == RTUExchange::dtMTR )
{
// only for MTR
if( !initMTRitem(it,r) )
return false;
}
else if( dev->dtype == RTUExchange::dtRTU188 )
{ // only for RTU188
if( !initRTU188item(it,r) )
return false;
}
else if( dev->dtype == RTUExchange::dtRTU )
{
}
else
{
dlog[Debug::CRIT] << myname << "(initRegInfo): Unknown mbtype='" << dev->dtype
<< "' for " << it.getProp("name") << endl;
return false;
}
if( mbregFromID )
r->mbreg = conf->getSensorID(it.getProp("name"));
else if( dev->dtype != RTUExchange::dtRTU188 )
{
string reg = it.getProp("mbreg");
if( reg.empty() )
{
dlog[Debug::CRIT] << myname << "(initRegInfo): unknown mbreg for " << it.getProp("name") << endl;
return false;
}
r->mbreg = ModbusRTU::str2mbData(reg);
}
else // if( dev->dtype == RTUExchange::dtRTU188 )
{
UniversalIO::IOTypes stype = UniSetTypes::getIOType(it.getProp("iotype"));
r->mbreg = RTUStorage::getRegister(r->rtuJack,r->rtuChan,stype);
if( r->mbreg == -1 )
{
dlog[Debug::CRIT] << myname << "(initRegInfo): (RTU188) unknown mbreg for " << it.getProp("name") << endl;
return false;
}
}
{
string sr = it.getProp("init_mbreg");
if( sr == "-1" )
{
r->mb_init = true; // OFF mb_init
r->sm_init = true;
}
else if( sr.empty() )
r->mb_init_mbreg = r->mbreg;
else
r->mb_init_mbreg = ModbusRTU::str2mbData(sr);
}
r->mbfunc = ModbusRTU::fnUnknown;
string f = it.getProp("mbfunc");
if( !f.empty() )
{
r->mbfunc = (ModbusRTU::SlaveFunctionCode)UniSetTypes::uni_atoi(f);
if( r->mbfunc == ModbusRTU::fnUnknown )
{
dlog[Debug::CRIT] << myname << "(initRegInfo): Unknown mbfunc ='" << f
<< "' for " << it.getProp("name") << endl;
return false;
}
}
return true;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initRTUDevice( RTUDevice* d, UniXML_iterator& it )
{
d->dtype = getDeviceType(it.getProp("mbtype"));
if( d->dtype == dtUnknown )
{
dlog[Debug::CRIT] << myname << "(initRTUDevice): Unknown mbtype=" << it.getProp("mbtype")
<< ". Use: rtu | mtr | rtu188"
<< " for " << it.getProp("name") << endl;
return false;
}
string addr = it.getProp("mbaddr");
if( addr.empty() )
{
dlog[Debug::CRIT] << myname << "(initRTUDevice): Unknown mbaddr for " << it.getProp("name") << endl;
return false;
}
d->speed = defSpeed;
d->mbaddr = ModbusRTU::str2mbAddr(addr);
return true;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initItem( UniXML_iterator& it )
{
RSProperty p;
if( !initRSProperty(p,it) )
return false;
string addr = it.getProp("mbaddr");
if( addr.empty() )
{
dlog[Debug::CRIT] << myname << "(initItem): Unknown mbaddr='" << addr << " for " << it.getProp("name") << endl;
return false;
}
ModbusRTU::ModbusAddr mbaddr = ModbusRTU::str2mbAddr(addr);
RTUDevice* dev = addDev(rmap,mbaddr,it);
if( !dev )
{
dlog[Debug::CRIT] << myname << "(initItem): " << it.getProp("name") << " CAN`T ADD for polling!" << endl;
return false;
}
ModbusRTU::ModbusData mbreg;
if( mbregFromID )
mbreg = p.si.id; // conf->getSensorID(it.getProp("name"));
else if( dev->dtype != RTUExchange::dtRTU188 )
{
string reg = it.getProp("mbreg");
if( reg.empty() )
{
dlog[Debug::CRIT] << myname << "(initRegInfo): unknown mbreg for " << it.getProp("name") << endl;
return false;
}
mbreg = ModbusRTU::str2mbData(reg);
}
else // if( dev->dtype == RTUExchange::dtRTU188 )
{
RegInfo rr;
initRegInfo(&rr,it,dev);
mbreg = RTUStorage::getRegister(rr.rtuJack,rr.rtuChan,p.stype);
if( mbreg == -1 )
{
dlog[Debug::CRIT] << myname << "(initItem): unknown mbreg for " << it.getProp("name") << endl;
return false;
}
}
RegInfo* ri = addReg(dev->regmap,mbreg,it,dev);
if( dev->dtype == dtMTR )
{
p.rnum = MTR::wsize(ri->mtrType);
if( p.rnum <= 0 )
{
dlog[Debug::CRIT] << myname << "(initItem): unknown word size for " << it.getProp("name") << endl;
return false;
}
}
if( !ri )
return false;
ri->dev = dev;
// п÷п═п·п▓п•п═п п░!
// п╣я│п╩п╦ я└я┐п╫п╨я├п╦я▐ п╫п╟ п╥п╟п©п╦я│я▄, я┌п╬ п╫п╟п╢п╬ п©я─п╬п╡п╣я─п╦я┌я▄
// я┤я┌п╬ п╬п╢п╦п╫ п╦ я┌п╬я┌п╤п╣ я─п╣пЁп╦я│я┌я─ п╫п╣ п©п╣я─п╣п╥п╟п©п╦я┬я┐я┌ п╫п╣я│п╨п╬п╩я▄п╨п╬ п╢п╟я┌я┤п╦п╨п╬п╡
// я█я┌п╬ п╡п╬п╥п╪п╬п╤п╫п╬ я┌п╬п╩я▄п╨п╬, п╣я│п╩п╦ п╬п╫п╦ п©п╦я┬я┐я┌ п╠п╦я┌я▀!!
// п≤п╒п·п⌠:
// п•я│п╩п╦ п╢п╩я▐ я└я┐п╫п╨я├п╦п╧ п╥п╟п©п╦я│п╦ я│п©п╦я│п╬п╨ п╢п╟я┌я┤п╦п╨п╬п╡ п╫п╟ п╬п╢п╦п╫ я─п╣пЁп╦я│я┌я─ > 1
// п╥п╫п╟я┤п╦я┌ п╡ я│п©п╦я│п╨п╣ п╪п╬пЁя┐я┌ п╠я▀я┌я▄ я┌п╬п╩я▄п╨п╬ п╠п╦я┌п╬п╡я▀п╣ п╢п╟я┌я┤п╦п╨п╦
// п╦ п╣я│п╩п╦ п╦п╢я▒я┌ п©п╬п©я▀я┌п╨п╟ п╡п╫п╣я│я┌п╦ п╡ я│п©п╦я│п╬п╨ п╫п╣ п╠п╦я┌п╬п╡я▀п╧ п╢п╟я┌я┤п╦п╨ я┌п╬ п·п╗п≤п▒п п░!
// п≤ п╫п╟п╬п╠п╬я─п╬я┌: п╣я│п╩п╦ п╦п╢я▒я┌ п©п╬п©я▀я┌п╨п╟ п╡п╫п╣я│я┌п╦ п╠п╦я┌п╬п╡я▀п╧ п╢п╟я┌я┤п╦п╨, п╟ п╡ я│п©п╦я│п╨п╣
// я┐п╤п╣ я│п╦п╢п╦я┌ п╢п╟я┌я┤п╦п╨ п╥п╟п╫п╦п╪п╟я▌я┴п╦п╧ я├п╣п╩я▀п╧ я─п╣пЁп╦я│я┌я─, я┌п╬ я┌п╬п╤п╣ п·п╗п≤п▒п п░!
if( ModbusRTU::isWriteFunction(ri->mbfunc) )
{
if( p.nbit<0 && ri->slst.size() > 1 )
{
dlog[Debug::CRIT] << myname << "(initItem): FAILED! Sharing SAVE (not bit saving) to "
<< " mbreg=" << ModbusRTU::dat2str(ri->mbreg)
<< " for " << it.getProp("name") << endl;
abort(); // ABORT PROGRAM!!!!
return false;
}
if( p.nbit >= 0 && ri->slst.size() == 1 )
{
PList::iterator it2 = ri->slst.begin();
if( it2->nbit < 0 )
{
dlog[Debug::CRIT] << myname << "(initItem): FAILED! Sharing SAVE (mbreg="
<< ModbusRTU::dat2str(ri->mbreg) << " already used)!"
<< " IGNORE --> " << it.getProp("name") << endl;
abort(); // ABORT PROGRAM!!!!
return false;
}
}
}
RSProperty* p1 = addProp(ri->slst,p);
if( !p1 )
return false;
p1->reg = ri;
if( p1->rnum > 1 )
{
for( int i=1; i<p1->rnum; i++ )
{
RTUExchange::RegInfo* ri1 = addReg(dev->regmap,mbreg+i,it,dev,ri);
ri1->mb_init_mbreg = ri->mb_init_mbreg+i;
}
}
if( dev->dtype == dtRTU188 )
{
if( !dev->rtu )
dev->rtu = new RTUStorage(mbaddr);
}
return true;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initMTRitem( UniXML_iterator& it, RegInfo* p )
{
p->mtrType = MTR::str2type(it.getProp("mtrtype"));
if( p->mtrType == MTR::mtUnknown )
{
dlog[Debug::CRIT] << myname << "(readMTRItem): Unknown mtrtype '"
<< it.getProp("mtrtype")
<< "' for " << it.getProp("name") << endl;
return false;
}
return true;
}
// ------------------------------------------------------------------------------------------
bool RTUExchange::initRTU188item( UniXML_iterator& it, RegInfo* p )
{
string jack = it.getProp("jack");
string chan = it.getProp("channel");
if( jack.empty() )
{
dlog[Debug::CRIT] << myname << "(readRTU188Item): Unknown jack='' "
<< " for " << it.getProp("name") << endl;
return false;
}
p->rtuJack = RTUStorage::s2j(jack);
if( p->rtuJack == RTUStorage::nUnknown )
{
dlog[Debug::CRIT] << myname << "(readRTU188Item): Unknown jack=" << jack
<< " for " << it.getProp("name") << endl;
return false;
}
if( chan.empty() )
{
dlog[Debug::CRIT] << myname << "(readRTU188Item): Unknown channel='' "
<< " for " << it.getProp("name") << endl;
return false;
}
p->rtuChan = UniSetTypes::uni_atoi(chan);
if( dlog.debugging(Debug::LEVEL2) )
dlog[Debug::LEVEL2] << myname << "(readRTU188Item): " << p << endl;
return true;
}
// -----------------------------------------------------------------------------
void RTUExchange::initIterators()
{
MBExchange::initIterators();
for( RTUExchange::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
shm->initDIterator(d->resp_dit);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
for( PList::iterator it2=it->second->slst.begin();it2!=it->second->slst.end(); ++it2 )
{
shm->initDIterator(it2->dit);
shm->initAIterator(it2->ait);
}
}
}
}
// -----------------------------------------------------------------------------
void RTUExchange::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='rs'" << endl;
MBExchange::help_print(argc,argv);
// cout << " Настройки протокола RS: " << endl;
cout << "--prefix-dev devname - файл устройства" << endl;
cout << "--prefix-speed - Скорость обмена (9600,19920,38400,57600,115200)." << endl;
cout << "--prefix-my-addr - адрес текущего узла" << endl;
cout << "--prefix-recv-timeout - Таймаут на ожидание ответа." << endl;
}
// -----------------------------------------------------------------------------
RTUExchange* RTUExchange::init_rtuexchange( int argc, const char* const* argv, UniSetTypes::ObjectId icID,
SharedMemory* ic, const std::string prefix )
{
string name = conf->getArgParam("--" + prefix + "-name","RTUExchange1");
if( name.empty() )
{
cerr << "(rtuexchange): Unknown 'name'. Use --" << prefix << "-name" << endl;
return 0;
}
ObjectId ID = conf->getObjectID(name);
if( ID == UniSetTypes::DefaultObjectId )
{
cerr << "(rtuexchange): Not found ID for '" << name
<< "'!"
<< " in section <" << conf->getObjectsSection() << ">" << endl;
return 0;
}
dlog[Debug::INFO] << "(rtuexchange): name = " << name << "(" << ID << ")" << endl;
return new RTUExchange(ID,icID,ic,prefix);
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, const RTUExchange::RSProperty& p )
{
os << " (" << ModbusRTU::dat2str(p.reg->mbreg) << ")"
<< " sid=" << p.si.id
<< " stype=" << p.stype
<< " nbit=" << p.nbit
<< " nbyte=" << p.nbyte
<< " rnum=" << p.rnum
<< " safety=" << p.safety
<< " invert=" << p.invert;
if( p.stype == UniversalIO::AnalogInput || p.stype == UniversalIO::AnalogOutput )
{
os << p.cal
<< " cdiagram=" << ( p.cdiagram ? "yes" : "no" );
}
return os;
}
// -----------------------------------------------------------------------------
void RTUExchange::initDeviceList()
{
xmlNode* respNode = conf->findNode(cnode,"DeviceList");
if( respNode )
{
UniXML_iterator it1(respNode);
if( it1.goChildren() )
{
for(;it1.getCurrent(); it1.goNext() )
{
ModbusRTU::ModbusAddr a = ModbusRTU::str2mbAddr(it1.getProp("addr"));
initDeviceInfo(rmap,a,it1);
}
}
else
dlog[Debug::WARN] << myname << "(init): <DeviceList> empty section..." << endl;
}
else
dlog[Debug::WARN] << myname << "(init): <DeviceList> not found..." << endl;
}
// -----------------------------------------------------------------------------
bool RTUExchange::initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it )
{
RTUDeviceMap::iterator d = m.find(a);
if( d == m.end() )
{
dlog[Debug::WARN] << myname << "(initDeviceInfo): not found device for addr=" << ModbusRTU::addr2str(a) << endl;
return false;
}
if( !it.getProp("respondSensor").empty() )
{
d->second->resp_id = conf->getSensorID(it.getProp("respondSensor"));
if( d->second->resp_id == DefaultObjectId )
{
dlog[Debug::CRIT] << myname << "(initDeviceInfo): not found ID for noRespondSensor=" << it.getProp("respondSensor") << endl;
return false;
}
}
dlog[Debug::INFO] << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a) << endl;
int tout = it.getPIntProp("timeout", UniSetTimer::WaitUpTime);
d->second->resp_ptTimeout.setTiming(tout);
d->second->resp_invert = it.getIntProp("invert");
string s = it.getProp("speed");
if( !s.empty() )
{
d->second->speed = ComPort::getSpeed(s);
if( d->second->speed == ComPort::ComSpeed0 )
{
d->second->speed = defSpeed;
dlog[Debug::CRIT] << myname << "(initDeviceInfo): Unknown speed=" << s <<
" for addr=" << ModbusRTU::addr2str(a) << endl;
return false;
}
}
return true;
}
// -----------------------------------------------------------------------------
void RTUExchange::printMap( RTUExchange::RTUDeviceMap& m )
{
cout << "devices: num=" << m.size() << endl;
for( RTUExchange::RTUDeviceMap::iterator it=m.begin(); it!=m.end(); ++it )
{
cout << " " << *(it->second) << endl;
}
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, RTUExchange::RTUDeviceMap& m )
{
os << "devices: " << endl;
for( RTUExchange::RTUDeviceMap::iterator it=m.begin(); it!=m.end(); ++it )
{
os << " " << *(it->second) << endl;
}
return os;
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, RTUExchange::RTUDevice& d )
{
os << "addr=" << ModbusRTU::addr2str(d.mbaddr)
<< " type=" << d.dtype;
os << " rtu=" << (d.rtu ? "yes" : "no" );
os << " respond_id=" << d.resp_id
<< " respond_timeout=" << d.resp_ptTimeout.getInterval()
<< " respond_state=" << d.resp_state
<< " respond_invert=" << d.resp_invert
<< endl;
os << " regs: " << endl;
for( RTUExchange::RegMap::iterator it=d.regmap.begin(); it!=d.regmap.end(); ++it )
os << " " << *(it->second) << endl;
return os;
}
// -----------------------------------------------------------------------------
std::ostream& operator<<( std::ostream& os, RTUExchange::RegInfo& r )
{
os << " mbreg=" << ModbusRTU::dat2str(r.mbreg)
<< " mbfunc=" << r.mbfunc
<< " mtrType=" << MTR::type2str(r.mtrType)
<< " jack=" << RTUStorage::j2s(r.rtuJack)
<< " chan=" << r.rtuChan
<< " q_num=" << r.q_num
<< " q_count=" << r.q_count
<< " value=" << ModbusRTU::dat2str(r.mbval) << "(" << (int)r.mbval << ")"
<< endl;
for( RTUExchange::PList::iterator it=r.slst.begin(); it!=r.slst.end(); ++it )
os << " " << (*it) << endl;
return os;
}
// -----------------------------------------------------------------------------
void RTUExchange::rtuQueryOptimization( RTUDeviceMap& m )
{
if( noQueryOptimization )
return;
dlog[Debug::INFO] << myname << "(rtuQueryOptimization): optimization..." << endl;
for( RTUExchange::RTUDeviceMap::iterator it1=m.begin(); it1!=m.end(); ++it1 )
{
RTUDevice* d(it1->second);
for( RTUExchange::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
RTUExchange::RegMap::iterator beg = it;
ModbusRTU::ModbusData reg = it->second->mbreg + it->second->offset;
beg->second->q_num = 1;
beg->second->q_count = 1;
it++;
for( ;it!=d->regmap.end(); ++it )
{
if( (it->second->mbreg + it->second->offset - reg) > 1 )
break;
if( beg->second->mbfunc != it->second->mbfunc )
break;
beg->second->q_count++;
if( beg->second->q_count >= ModbusRTU::MAXDATALEN )
break;
reg = it->second->mbreg + it->second->offset;
it->second->q_num = beg->second->q_count;
it->second->q_count = 0;
}
// check correct function...
if( beg->second->q_count>1 && beg->second->mbfunc==ModbusRTU::fnWriteOutputSingleRegister )
{
dlog[Debug::WARN] << myname << "(rtuQueryOptimization): "
<< " optimization change func=" << ModbusRTU::fnWriteOutputSingleRegister
<< " <--> func=" << ModbusRTU::fnWriteOutputRegisters
<< " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg);
beg->second->mbfunc = ModbusRTU::fnWriteOutputRegisters;
}
else if( beg->second->q_count>1 && beg->second->mbfunc==ModbusRTU::fnForceSingleCoil )
{
dlog[Debug::WARN] << myname << "(rtuQueryOptimization): "
<< " optimization change func=" << ModbusRTU::fnForceSingleCoil
<< " <--> func=" << ModbusRTU::fnForceMultipleCoils
<< " for mbaddr=" << ModbusRTU::addr2str(d->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(beg->second->mbreg);
beg->second->mbfunc = ModbusRTU::fnForceMultipleCoils;
}
if( it==d->regmap.end() )
break;
it--;
}
}
}
// -----------------------------------------------------------------------------
void RTUExchange::updateRTU( RegMap::iterator& rit )
{
RegInfo* r(rit->second);
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
updateRSProperty( &(*it),false );
if( r->sm_init )
r->mb_init = true;
}
// -----------------------------------------------------------------------------
void RTUExchange::updateRSProperty( RSProperty* p, bool write_only )
{
using namespace ModbusRTU;
RegInfo* r(p->reg->rit->second);
bool save = isWriteFunction( r->mbfunc );
if( !save && write_only )
return;
if( !checkUpdateSM(save) )
return;
try
{
if( p->vType == VTypes::vtUnknown )
{
ModbusRTU::DataBits16 b(r->mbval);
if( p->nbit >= 0 )
{
if( save && r->mb_init )
{
bool set = IOBase::processingAsDO( p, shm, force_out );
b.set(p->nbit,set);
r->mbval = b.mdata();
}
else
{
bool set = b[p->nbit];
IOBase::processingAsDI( p, set, shm, force );
}
return;
}
if( p->rnum <= 1 )
{
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
r->mbval = IOBase::processingAsDO( p, shm, force_out );
}
else
r->mbval = IOBase::processingAsAO( p, shm, force_out );
}
else
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
IOBase::processingAsDI( p, r->mbval, shm, force );
}
else
IOBase::processingAsAI( p, (signed short)r->mbval, shm, force );
}
return;
}
dlog[Debug::CRIT] << myname << "(updateRSProperty): IGNORE item: rnum=" << p->rnum
<< " > 1 ?!! for id=" << p->si.id << endl;
return;
}
else if( p->vType == VTypes::vtSigned )
{
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
r->mbval = (signed short)IOBase::processingAsDO( p, shm, force_out );
}
else
r->mbval = (signed short)IOBase::processingAsAO( p, shm, force_out );
}
else
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
IOBase::processingAsDI( p, r->mbval, shm, force );
}
else
{
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force );
}
}
return;
}
else if( p->vType == VTypes::vtUnsigned )
{
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
r->mbval = (unsigned short)IOBase::processingAsDO( p, shm, force_out );
}
else
r->mbval = (unsigned short)IOBase::processingAsAO( p, shm, force_out );
}
else
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
{
IOBase::processingAsDI( p, r->mbval, shm, force );
}
else
{
IOBase::processingAsAI( p, (unsigned short)r->mbval, shm, force );
}
}
return;
}
else if( p->vType == VTypes::vtByte )
{
if( p->nbyte <= 0 || p->nbyte > VTypes::Byte::bsize )
{
dlog[Debug::CRIT] << myname << "(updateRSProperty): IGNORE item: reg=" << ModbusRTU::dat2str(r->mbreg)
<< " vtype=" << p->vType << " but nbyte=" << p->nbyte << endl;
return;
}
if( save && r->mb_init )
{
long v = IOBase::processingAsAO( p, shm, force_out );
VTypes::Byte b(r->mbval);
b.raw.b[p->nbyte-1] = v;
r->mbval = b.raw.w;
}
else
{
VTypes::Byte b(r->mbval);
IOBase::processingAsAI( p, b.raw.b[p->nbyte-1], shm, force );
}
return;
}
else if( p->vType == VTypes::vtF2 )
{
RegMap::iterator i(p->reg->rit);
if( save && r->mb_init )
{
float f = IOBase::processingFasAO( p, shm, force_out );
VTypes::F2 f2(f);
for( int k=0; k<VTypes::F2::wsize(); k++, i++ )
i->second->mbval = f2.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[VTypes::F2::wsize()];
for( int k=0; k<VTypes::F2::wsize(); k++, i++ )
data[k] = i->second->mbval;
VTypes::F2 f(data,VTypes::F2::wsize());
delete[] data;
IOBase::processingFasAI( p, (float)f, shm, force );
}
}
else if( p->vType == VTypes::vtF4 )
{
RegMap::iterator i(p->reg->rit);
if( save && r->mb_init )
{
float f = IOBase::processingFasAO( p, shm, force_out );
VTypes::F4 f4(f);
for( int k=0; k<VTypes::F4::wsize(); k++, i++ )
i->second->mbval = f4.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[VTypes::F4::wsize()];
for( int k=0; k<VTypes::F4::wsize(); k++, i++ )
data[k] = i->second->mbval;
VTypes::F4 f(data,VTypes::F4::wsize());
delete[] data;
IOBase::processingFasAI( p, (float)f, shm, force );
}
}
}
catch(IOController_i::NameNotFound &ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty): (BadRange)..." << endl;
}
catch( Exception& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::LEVEL3] << myname << "(updateRSProperty): catch ..." << endl;
}
}
// -----------------------------------------------------------------------------
void RTUExchange::updateMTR( RegMap::iterator& rit )
{
RegInfo* r(rit->second);
using namespace ModbusRTU;
bool save = isWriteFunction( r->mbfunc );
{
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
{
try
{
if( r->mtrType == MTR::mtT1 )
{
if( save )
r->mbval = IOBase::processingAsAO( &(*it), shm, force_out );
else
{
MTR::T1 t(r->mbval);
IOBase::processingAsAI( &(*it), t.val, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT2 )
{
if( save )
{
MTR::T2 t(IOBase::processingAsAO( &(*it), shm, force_out ));
r->mbval = t.val;
}
else
{
MTR::T2 t(r->mbval);
IOBase::processingAsAI( &(*it), t.val, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT3 )
{
RegMap::iterator i(rit);
if( save )
{
MTR::T3 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( int k=0; k<MTR::T3::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[MTR::T3::wsize()];
for( int k=0; k<MTR::T3::wsize(); k++, i++ )
data[k] = i->second->mbval;
MTR::T3 t(data,MTR::T3::wsize());
delete[] data;
IOBase::processingAsAI( &(*it), (long)t, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT4 )
{
if( save )
cerr << myname << "(updateMTR): write (T4) reg(" << dat2str(r->mbreg) << ") to MTR NOT YET!!!" << endl;
else
{
MTR::T4 t(r->mbval);
IOBase::processingAsAI( &(*it), uni_atoi(t.sval), shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT5 )
{
RegMap::iterator i(rit);
if( save )
{
MTR::T5 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( int k=0; k<MTR::T5::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[MTR::T5::wsize()];
for( int k=0; k<MTR::T5::wsize(); k++, i++ )
data[k] = i->second->mbval;
MTR::T5 t(data,MTR::T5::wsize());
delete[] data;
IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT6 )
{
RegMap::iterator i(rit);
if( save )
{
MTR::T6 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( int k=0; k<MTR::T6::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[MTR::T6::wsize()];
for( int k=0; k<MTR::T6::wsize(); k++, i++ )
data[k] = i->second->mbval;
MTR::T6 t(data,MTR::T6::wsize());
delete[] data;
IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT7 )
{
RegMap::iterator i(rit);
if( save )
{
MTR::T7 t(IOBase::processingAsAO( &(*it), shm, force_out ));
for( int k=0; k<MTR::T7::wsize(); k++, i++ )
i->second->mbval = t.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[MTR::T7::wsize()];
for( int k=0; k<MTR::T7::wsize(); k++, i++ )
data[k] = i->second->mbval;
MTR::T7 t(data,MTR::T7::wsize());
delete[] data;
IOBase::processingFasAI( &(*it), (float)t.val, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT16 )
{
if( save )
{
MTR::T16 t(IOBase::processingFasAO( &(*it), shm, force_out ));
r->mbval = t.val;
}
else
{
MTR::T16 t(r->mbval);
IOBase::processingFasAI( &(*it), t.fval, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtT17 )
{
if( save )
{
MTR::T17 t(IOBase::processingFasAO( &(*it), shm, force_out ));
r->mbval = t.val;
}
else
{
MTR::T17 t(r->mbval);
IOBase::processingFasAI( &(*it), t.fval, shm, force );
}
continue;
}
if( r->mtrType == MTR::mtF1 )
{
RegMap::iterator i(rit);
if( save )
{
float f = IOBase::processingFasAO( &(*it), shm, force_out );
MTR::F1 f1(f);
for( int k=0; k<MTR::F1::wsize(); k++, i++ )
i->second->mbval = f1.raw.v[k];
}
else
{
ModbusRTU::ModbusData* data = new ModbusRTU::ModbusData[MTR::F1::wsize()];
for( int k=0; k<MTR::F1::wsize(); k++, i++ )
data[k] = i->second->mbval;
MTR::F1 t(data,MTR::F1::wsize());
delete[] data;
IOBase::processingFasAI( &(*it), (float)t, shm, force );
}
continue;
}
}
catch(IOController_i::NameNotFound &ex)
{
dlog[Debug::LEVEL3] << myname << "(updateMTR):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateMTR):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
dlog[Debug::LEVEL3] << myname << "(updateMTR): (BadRange)..." << endl;
}
catch( Exception& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateMTR): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::LEVEL3] << myname << "(updateMTR): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::LEVEL3] << myname << "(updateMTR): catch ..." << endl;
}
}
}
}
// -----------------------------------------------------------------------------
void RTUExchange::updateRTU188( RegMap::iterator& it )
{
RegInfo* r(it->second);
if( !r->dev->rtu )
return;
using namespace ModbusRTU;
// bool save = false;
if( isWriteFunction(r->mbfunc) )
{
// save = true;
cerr << myname << "(updateRTU188): write reg(" << dat2str(r->mbreg) << ") to RTU188 NOT YET!!!" << endl;
return;
}
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
{
try
{
if( it->stype == UniversalIO::DigitalInput )
{
bool set = r->dev->rtu->getState(r->rtuJack,r->rtuChan,it->stype);
IOBase::processingAsDI( &(*it), set, shm, force );
continue;
}
if( it->stype == UniversalIO::AnalogInput )
{
long val = r->dev->rtu->getInt(r->rtuJack,r->rtuChan,it->stype);
IOBase::processingAsAI( &(*it),val, shm, force );
continue;
}
}
catch(IOController_i::NameNotFound &ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188):(NameNotFound) " << ex.err << endl;
}
catch(IOController_i::IOBadParam& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188):(IOBadParam) " << ex.err << endl;
}
catch(IONotifyController_i::BadRange )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): (BadRange)..." << endl;
}
catch( Exception& ex )
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): " << ex << endl;
}
catch(CORBA::SystemException& ex)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): CORBA::SystemException: "
<< ex.NP_minorString() << endl;
}
catch(...)
{
dlog[Debug::LEVEL3] << myname << "(updateRTU188): catch ..." << endl;
}
}
}
// -----------------------------------------------------------------------------
//std::ostream& operator<<( std::ostream& os, MBTCPMaster::PList& lst )
std::ostream& RTUExchange::print_plist( std::ostream& os, RTUExchange::PList& lst )
{
os << "[ ";
for( RTUExchange::PList::const_iterator it=lst.begin(); it!=lst.end(); ++it )
os << "(" << it->si.id << ")" << conf->oind->getBaseName(conf->oind->getMapName(it->si.id)) << " ";
os << "]";
return os;
}
// -----------------------------------------------------------------------------
......@@ -25,131 +25,8 @@ class RTUExchange:
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
enum Timer
{
tmExchange
};
// --------------------------------------------------------
struct RTUDevice;
struct RegInfo;
struct RSProperty:
public IOBase
{
// only for RTU
short nbit; /*!< bit number) */
VTypes::VType vType; /*!< type of value */
short rnum; /*!< count of registers */
short nbyte; /*!< byte number (1-2) */
RSProperty():
nbit(-1),vType(VTypes::vtUnknown),
rnum(VTypes::wsize(VTypes::vtUnknown)),
nbyte(0),reg(0)
{}
RegInfo* reg;
};
friend std::ostream& operator<<( std::ostream& os, const RSProperty& p );
typedef std::list<RSProperty> PList;
static std::ostream& print_plist( std::ostream& os, PList& p );
typedef std::map<ModbusRTU::ModbusData,RegInfo*> RegMap;
struct RegInfo
{
RegInfo():
mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown),
mtrType(MTR::mtUnknown),
rtuJack(RTUStorage::nUnknown),rtuChan(0),
dev(0),offset(0),
q_num(0),q_count(1),mb_init(false),sm_init(false),
mb_init_mbreg(0)
{}
ModbusRTU::ModbusData mbval;
ModbusRTU::ModbusData mbreg; /*!< регистр */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< функция для чтения/записи */
PList slst;
// only for MTR
MTR::MTRType mtrType; /*!< тип регистра (согласно спецификации на MTR) */
// only for RTU188
RTUStorage::RTUJack rtuJack;
int rtuChan;
RTUDevice* dev;
int offset;
// optimization
int q_num; /*! number in query */
int q_count; /*! count registers for query */
RegMap::iterator rit;
bool mb_init; /*!< init before use */
bool sm_init; /*!< SM init value */
ModbusRTU::ModbusData mb_init_mbreg; /*!< mb_init register */
};
friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
struct RTUDevice
{
RTUDevice():
speed(ComPort::ComSpeed38400),
respnond(false),
mbaddr(0),
dtype(dtUnknown),
resp_id(UniSetTypes::DefaultObjectId),
resp_state(false),
resp_invert(false),
resp_real(false),
resp_init(false),
rtu(0)
{
resp_trTimeout.change(false);
}
ComPort::Speed speed;
bool respnond;
ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */
RegMap regmap;
DeviceType dtype; /*!< тип устройства */
UniSetTypes::ObjectId resp_id;
IOController::DIOStateList::iterator resp_dit;
PassiveTimer resp_ptTimeout;
Trigger resp_trTimeout;
bool resp_state;
bool resp_invert;
bool resp_real;
bool resp_init;
RTUStorage* rtu;
// return TRUE if state changed
bool checkRespond();
};
friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
typedef std::map<ModbusRTU::ModbusAddr,RTUDevice*> RTUDeviceMap;
friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
void printMap(RTUDeviceMap& d);
// ----------------------------------
protected:
RTUDeviceMap rmap;
ModbusRTUMaster* mb;
ModbusRTUMaster* mbrtu;
UniSetTypes::uniset_mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
......@@ -159,45 +36,9 @@ class RTUExchange:
virtual void step();
void poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
void updateSM();
void updateRTU(RegMap::iterator& it);
void updateMTR(RegMap::iterator& it);
void updateRTU188(RegMap::iterator& it);
void updateRSProperty( RSProperty* p, bool write_only=false );
virtual void processingMessage( UniSetTypes::VoidMessage *msg );
virtual void sysCommand( UniSetTypes::SystemMessage *msg );
virtual void sensorInfo( UniSetTypes::SensorMessage*sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initMB( bool reopen=false );
virtual void initIterators();
bool initItem( UniXML_iterator& it );
void initDeviceList();
void initOffsetList();
RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
RegInfo* addReg( RegMap& rmap, ModbusRTU::ModbusData r, UniXML_iterator& it,
RTUDevice* dev, RegInfo* rcopy=0 );
RSProperty* addProp( PList& plist, RSProperty& p );
bool initMTRitem( UniXML_iterator& it, RegInfo* p );
bool initRTU188item( UniXML_iterator& it, RegInfo* p );
bool initRSProperty( RSProperty& p, UniXML_iterator& it );
bool initRegInfo( RegInfo* r, UniXML_iterator& it, RTUDevice* dev );
bool initRTUDevice( RTUDevice* d, UniXML_iterator& it );
bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
void rtuQueryOptimization( RTUDeviceMap& m );
virtual ModbusClient* initMB( bool reopen=false );
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
private:
RTUExchange();
......
../ModbusMaster/MBExchange.h
\ No newline at end of file
......@@ -6,6 +6,6 @@ libUniSetExtensions_la_LDFLAGS = -version-info $(UEXT_VER)
libUniSetExtensions_la_CPPFLAGS = $(SIGC_CFLAGS) -I$(top_builddir)/extensions/include
libUniSetExtensions_la_LIBADD = $(SIGC_LIBS) $(top_builddir)/lib/libUniSet.la
libUniSetExtensions_la_SOURCES = Extensions.cc SMInterface.cc Calibration.cc SingleProcess.cc \
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc MBExchange.cc
IOBase.cc DigitalFilter.cc PID.cc MTR.cc VTypes.cc
#UObject_SK.cc
\ No newline at end of file
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