Commit bbdd555e authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusMaster): перенёс реализацию ModbusMaster TCP и RTU в один каталог ModbusMaster

parent df497744
......@@ -179,13 +179,11 @@ AC_CONFIG_FILES([Makefile
extensions/DBServer-MySQL/libUniSetMySQL.pc
extensions/IOControl/Makefile
extensions/IOControl/libUniSetIOControl.pc
extensions/RTUExchange/Makefile
extensions/RTUExchange/libUniSetRTU.pc
extensions/ModbusMaster/Makefile
extensions/ModbusMaster/libUniSetRTU.pc
extensions/ModbusMaster/libUniSetMBTCPMaster.pc
extensions/ModbusSlave/Makefile
extensions/ModbusSlave/libUniSetMBSlave.pc
extensions/MBTCPMaster/Makefile
extensions/MBTCPMaster/libUniSetMBTCPMaster.pc
extensions/LogicProcessor/Makefile
extensions/LogicProcessor/libUniSetLogicProcessor.pc
extensions/SMViewer/Makefile
......
// -----------------------------------------------------------------------------
#include <cmath>
#include <limits>
#include <sstream>
#include <Exceptions.h>
#include <extensions/Extensions.h>
#include "MBTCPMaster.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId,
SharedMemory* ic, const std::string prefix ):
MBExchange(objId,shmId,ic,prefix),
force_disconnect(true),
mbtcp(0),
pollThread(0)
{
// cout << "$ $" << endl;
prop_prefix = "tcp_";
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(MBTCPMaster): objId=-1?!! Use --" + prefix + "-name" );
UniXML_iterator it(cnode);
// ---------- init MBTCP ----------
string pname("--" + prefix + "-gateway-iaddr");
iaddr = conf->getArgParam(pname,it.getProp("gateway_iaddr"));
if( iaddr.empty() )
throw UniSetTypes::SystemError(myname+"(MBMaster): Unknown inet addr...(Use: " + pname +")" );
string tmp("--" + prefix + "-gateway-port");
port = conf->getArgInt(tmp,it.getProp("gateway_port"));
if( port <= 0 )
throw UniSetTypes::SystemError(myname+"(MBMaster): Unknown inet port...(Use: " + tmp +")" );
force_disconnect = conf->getArgInt("--" + prefix + "-persistent-connection",it.getProp("persistent_connection")) ? false : true;
dlog[Debug::INFO] << myname << "(init): persisten-connection=" << (!force_disconnect) << endl;
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
ptTimeout.setTiming(tout);
if( shm->isLocalwork() )
{
readConfiguration();
rtuQueryOptimization(rmap);
initDeviceList();
}
else
ic->addReadItem( sigc::mem_fun(this,&MBTCPMaster::readItem) );
pollThread = new ThreadCreator<MBTCPMaster>(this, &MBTCPMaster::poll_thread);
}
// -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster()
{
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
for( MBTCPMaster::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
delete it->second;
delete it1->second;
}
delete pollThread;
delete mbtcp;
}
// -----------------------------------------------------------------------------
ModbusClient* MBTCPMaster::initMB( bool reopen )
{
if( mbtcp )
{
if( !reopen )
return mbtcp;
delete mbtcp;
mb = 0;
mbtcp = 0;
}
try
{
ost::Thread::setException(ost::Thread::throwException);
mbtcp = new ModbusTCPMaster();
ost::InetAddress ia(iaddr.c_str());
mbtcp->connect(ia,port);
mbtcp->setForceDisconnect(force_disconnect);
if( recv_timeout > 0 )
mbtcp->setTimeout(recv_timeout);
mbtcp->setSleepPause(sleepPause_usec);
dlog[Debug::INFO] << myname << "(init): ipaddr=" << iaddr << " port=" << port << endl;
if( dlog.debugging(Debug::LEVEL9) )
mbtcp->setLog(dlog);
}
catch( ModbusRTU::mbException& ex )
{
dlog[Debug::WARN] << "(init): " << ex << endl;
}
catch(...)
{
if( mbtcp )
delete mbtcp;
mb = 0;
mbtcp = 0;
}
mb = mbtcp;
return mbtcp;
}
// -----------------------------------------------------------------------------
void MBTCPMaster::sysCommand( UniSetTypes::SystemMessage *sm )
{
MBExchange::sysCommand(sm);
if( sm->command == SystemMessage::StartUp )
pollThread->start();
}
// -----------------------------------------------------------------------------
void MBTCPMaster::step()
{
updateRespondSensors();
MBExchange::step();
}
// -----------------------------------------------------------------------------
void MBTCPMaster::updateRespondSensors()
{
bool tcpIsTimeout = false;
{
uniset_mutex_lock l(tcpMutex);
tcpIsTimeout = pollActivated && ptTimeout.checkTime();
}
if( dlog.debugging(Debug::LEVEL4) )
dlog[Debug::LEVEL4] << myname << ": tcpTimeout=" << tcpIsTimeout << endl;
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
if( tcpIsTimeout )
d->resp_real = false;
if( dlog.debugging(Debug::LEVEL4) )
{
dlog[Debug::LEVEL4] << myname << ": check respond addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " respond_id=" << d->resp_id
<< " real=" << d->resp_real
<< " state=" << d->resp_state
<< endl;
}
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;
}
}
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::poll_thread()
{
{
uniset_mutex_lock l(pollMutex,300);
ptTimeout.reset();
}
while( checkProcActive() )
{
try
{
if( sidExchangeMode != DefaultObjectId && force_out )
exchangeMode = shm->localGetValue(aitExchangeMode,sidExchangeMode);
}
catch(...){}
try
{
poll();
}
catch(...){}
if( !checkProcActive() )
break;
msleep(polltime);
}
}
// -----------------------------------------------------------------------------
bool MBTCPMaster::RTUDevice::checkRespond()
{
bool prev = resp_state;
if( resp_ptTimeout.getInterval() <= 0 )
{
resp_state = resp_real;
return (prev != resp_state);
}
if( resp_trTimeout.hi(resp_state && !resp_real) )
resp_ptTimeout.reset();
if( resp_real )
resp_state = true;
else if( resp_state && !resp_real && resp_ptTimeout.checkTime() )
resp_state = false;
// если ещё не инициализировали значение в SM
// то возвращаем true, чтобы оно принудительно сохранилось
if( !resp_init )
{
resp_state = resp_real;
resp_init = true;
prev = resp_state;
return true;
}
return ( prev != resp_state );
}
// -----------------------------------------------------------------------------
void MBTCPMaster::sigterm( int signo )
{
dlog[Debug::WARN] << myname << ": ********* SIGTERM(" << signo <<") ********" << endl;
setProcActive(false);
/*! \todo Доделать выставление безопасного состояния на выходы.
И нужно ли это. Ведь может не хватить времени на "обмен"
*/
// выставление безопасного состояния на выходы....
/*
RSMap::iterator it=rsmap.begin();
for( ; it!=rsmap.end(); ++it )
{
// if( it->stype!=UniversalIO::DigitalOutput && it->stype!=UniversalIO::AnalogOutput )
// continue;
if( it->safety == NoSafetyState )
continue;
try
{
}
catch( UniSetTypes::Exception& ex )
{
dlog[Debug::WARN] << myname << "(sigterm): " << ex << std::endl;
}
catch(...){}
}
*/
UniSetObject_LT::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void MBTCPMaster::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='mbtcp'" << endl;
MBExchange::help_print(argc,argv);
// ---------- init MBTCP ----------
// cout << "--prefix-sm-ready-timeout - время на ожидание старта SM" << endl;
cout << " Настройки протокола TCP: " << endl;
cout << "--prefix-gateway hostname,IP - IP опрашиваемого узла" << endl;
cout << "--prefix-gateway-port num - port на опрашиваемом узле" << endl;
cout << "--prefix-recv-timeout msec - Таймаут на приём одного сообщения" << endl;
cout << "--prefix-timeout msec - Таймаут для определения отсутсвия соединения" << endl;
cout << "--prefix-persistent-connection 0,1 - Не закрывать соединение на каждом цикле опроса" << endl;
}
// -----------------------------------------------------------------------------
MBTCPMaster* MBTCPMaster::init_mbmaster( int argc, const char* const* argv,
UniSetTypes::ObjectId icID, SharedMemory* ic,
const std::string prefix )
{
string name = conf->getArgParam("--" + prefix + "-name","MBTCPMaster1");
if( name.empty() )
{
dlog[Debug::CRIT] << "(MBTCPMaster): Не задан name'" << endl;
return 0;
}
ObjectId ID = conf->getObjectID(name);
if( ID == UniSetTypes::DefaultObjectId )
{
dlog[Debug::CRIT] << "(MBTCPMaster): идентификатор '" << name
<< "' не найден в конф. файле!"
<< " в секции " << conf->getObjectsSection() << endl;
return 0;
}
dlog[Debug::INFO] << "(MBTCPMaster): name = " << name << "(" << ID << ")" << endl;
return new MBTCPMaster(ID,icID,ic,prefix);
}
// -----------------------------------------------------------------------------
void MBTCPMaster::execute()
{
no_extimer = true;
try
{
askTimer(tmExchange,0);
}
catch(...){}
initMB(false);
while(1)
{
try
{
step();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << myname << "(execute): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(execute): catch ..." << endl;
}
msleep(polltime);
}
}
// -----------------------------------------------------------------------------
bin_PROGRAMS = @PACKAGE@-mbtcpmaster
# не забывайте править версию в pc-файле
UMBTCP_VER=1:2:1
lib_LTLIBRARIES = libUniSetMBTCPMaster.la
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 -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 -I$(top_builddir)/extensions/ModbusMaster $(SIGC_CFLAGS)
# install
devel_include_HEADERS = *.h
devel_includedir = $(pkgincludedir)/extensions
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libUniSetMBTCPMaster.pc
all-local:
ln -sf ../MBTCPMaster/$(devel_include_HEADERS) ../include
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetMBTCPMaster
Description: Support library for UniSetModbusTCPMaster
Requires: libUniSetExtensions libUniSetSharedMemory
Version: 1.2.1
Libs: -L${libdir} -lUniSetMBTCPMaster
Cflags: -I${includedir}/uniset
#include <sys/wait.h>
#include <sstream>
#include "MBTCPMaster.h"
#include "Configuration.h"
#include "Debug.h"
#include "ObjectsActivator.h"
#include "Extensions.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, const char** argv )
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: autodetect" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--mbtcp-logfile filename - logfilename. Default: mbtcpmaster.log" << endl;
cout << endl;
MBTCPMaster::help_print(argc, argv);
return 0;
}
try
{
string confile=UniSetTypes::getArgParam("--confile",argc, argv, "configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--mbtcp-logfile"));
if( logfilename.empty() )
logfilename = "mbtcpmaster.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
MBTCPMaster* mb = MBTCPMaster::init_mbmaster(argc,argv,shmID);
if( !mb )
{
dlog[Debug::CRIT] << "(mbmaster): init MBTCPMaster failed." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(mb));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- MBTCP Exchange START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- MBTCP Exchange START -------------------------\n\n";
act.run(false);
while( waitpid(-1, 0, 0) > 0 );
return 0;
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(mbtcpmaster): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(mbtcpmaster): catch ..." << std::endl;
}
while( waitpid(-1, 0, 0) > 0 );
return 1;
}
#!/bin/sh
./uniset-start.sh -f ./uniset-mbtcpmaster \
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
--dlog-add-levels info,crit,warn,level4,level3 \
--mbtcp-filter-field mbtcp \
--mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000 \
--mbtcp-force-disconnect 1
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
......@@ -55,10 +55,10 @@ pollActivated(false)
if( stat_time > 0 )
ptStatistic.setTiming(stat_time*1000);
// recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
//
// int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
// ptTimeout.setTiming(tout);
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
ptTimeout.setTiming(tout);
noQueryOptimization = conf->getArgInt("--" + prefix + "-no-query-optimization",it.getProp("no_query_optimization"));
......@@ -148,6 +148,21 @@ void MBExchange::help_print( int argc, const char* const* argv )
// -----------------------------------------------------------------------------
MBExchange::~MBExchange()
{
for( RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
if( it1->second->rtu )
{
delete it1->second->rtu;
it1->second->rtu = 0;
}
RTUDevice* d(it1->second);
for( RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
delete it->second;
delete it1->second;
}
delete shm;
}
// -----------------------------------------------------------------------------
......@@ -2613,3 +2628,34 @@ void MBExchange::poll()
// printMap(rmap);
}
// -----------------------------------------------------------------------------
bool MBExchange::RTUDevice::checkRespond()
{
bool prev = resp_state;
if( resp_ptTimeout.getInterval() <= 0 )
{
resp_state = resp_real;
return (prev != resp_state);
}
if( resp_trTimeout.hi(resp_state && !resp_real) )
resp_ptTimeout.reset();
if( resp_real )
resp_state = true;
else if( resp_state && !resp_real && resp_ptTimeout.checkTime() )
resp_state = false;
// если ещё не инициализировали значение в SM
// то возвращаем true, чтобы оно принудительно сохранилось
if( !resp_init )
{
resp_state = resp_real;
resp_init = true;
prev = resp_state;
return true;
}
return ( prev != resp_state );
}
// -----------------------------------------------------------------------------
......@@ -17,28 +17,11 @@ force_disconnect(true),
mbtcp(0),
pollThread(0)
{
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(MBTCPMaster): objId=-1?!! Use --" + prefix + "-name" );
// префикс для "свойств" - по умолчанию
// cout << "$ $" << endl;
prop_prefix = "tcp_";
// если задано поле для "фильтрации"
// то в качестве префикса используем его
if( !s_field.empty() )
prop_prefix = s_field + "_";
// если "принудительно" задан префикс
// используем его.
{
string p("--" + prefix + "-set-prop-prefix");
string v = conf->getArgParam(p,"");
if( !v.empty() && v[0] != '-' )
prop_prefix = v;
// если параметр всё-таки указан, считаем, что это попытка задать "пустой" префикс
else if( findArgParam(p,conf->getArgc(),conf->getArgv()) != -1 )
prop_prefix = "";
}
dlog[Debug::INFO] << myname << "(init): prop_prefix=" << prop_prefix << endl;
if( objId == DefaultObjectId )
throw UniSetTypes::SystemError("(MBTCPMaster): objId=-1?!! Use --" + prefix + "-name" );
UniXML_iterator it(cnode);
......@@ -57,6 +40,11 @@ pollThread(0)
force_disconnect = conf->getArgInt("--" + prefix + "-persistent-connection",it.getProp("persistent_connection")) ? false : true;
dlog[Debug::INFO] << myname << "(init): persisten-connection=" << (!force_disconnect) << endl;
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 500);
int tout = conf->getArgPInt("--" + prefix + "-timeout",it.getProp("timeout"), 5000);
ptTimeout.setTiming(tout);
if( shm->isLocalwork() )
{
readConfiguration();
......@@ -67,9 +55,6 @@ pollThread(0)
ic->addReadItem( sigc::mem_fun(this,&MBTCPMaster::readItem) );
pollThread = new ThreadCreator<MBTCPMaster>(this, &MBTCPMaster::poll_thread);
if( dlog.debugging(Debug::INFO) )
printMap(rmap);
}
// -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster()
......@@ -104,8 +89,6 @@ ModbusClient* MBTCPMaster::initMB( bool reopen )
mbtcp->setSleepPause(sleepPause_usec);
mbtcp->setAfterSendPause(aftersend_pause);
dlog[Debug::INFO] << myname << "(init): ipaddr=" << iaddr << " port=" << port << endl;
if( dlog.debugging(Debug::LEVEL9) )
......@@ -134,6 +117,54 @@ void MBTCPMaster::sysCommand( UniSetTypes::SystemMessage *sm )
pollThread->start();
}
// -----------------------------------------------------------------------------
void MBTCPMaster::step()
{
updateRespondSensors();
MBExchange::step();
}
// -----------------------------------------------------------------------------
void MBTCPMaster::updateRespondSensors()
{
bool tcpIsTimeout = false;
{
uniset_mutex_lock l(tcpMutex);
tcpIsTimeout = pollActivated && ptTimeout.checkTime();
}
if( dlog.debugging(Debug::LEVEL4) )
dlog[Debug::LEVEL4] << myname << ": tcpTimeout=" << tcpIsTimeout << endl;
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
if( tcpIsTimeout )
d->resp_real = false;
if( dlog.debugging(Debug::LEVEL4) )
{
dlog[Debug::LEVEL4] << myname << ": check respond addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " respond_id=" << d->resp_id
<< " real=" << d->resp_real
<< " state=" << d->resp_state
<< endl;
}
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;
}
}
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::poll_thread()
{
{
......@@ -145,7 +176,7 @@ void MBTCPMaster::poll_thread()
{
try
{
if( sidExchangeMode != DefaultObjectId && force )
if( sidExchangeMode != DefaultObjectId && force_out )
exchangeMode = shm->localGetValue(aitExchangeMode,sidExchangeMode);
}
catch(...){}
......@@ -162,14 +193,50 @@ void MBTCPMaster::poll_thread()
}
}
// -----------------------------------------------------------------------------
void MBTCPMaster::sigterm( int signo )
{
dlog[Debug::WARN] << myname << ": ********* SIGTERM(" << signo <<") ********" << endl;
setProcActive(false);
/*! \todo Доделать выставление безопасного состояния на выходы.
И нужно ли это. Ведь может не хватить времени на "обмен"
*/
// выставление безопасного состояния на выходы....
/*
RSMap::iterator it=rsmap.begin();
for( ; it!=rsmap.end(); ++it )
{
// if( it->stype!=UniversalIO::DigitalOutput && it->stype!=UniversalIO::AnalogOutput )
// continue;
if( it->safety == NoSafetyState )
continue;
try
{
}
catch( UniSetTypes::Exception& ex )
{
dlog[Debug::WARN] << myname << "(sigterm): " << ex << std::endl;
}
catch(...){}
}
*/
UniSetObject_LT::sigterm(signo);
}
// ------------------------------------------------------------------------------------------
void MBTCPMaster::help_print( int argc, const char* const* argv )
{
cout << "Default: prefix='mbtcp'" << endl;
MBExchange::help_print(argc,argv);
cout << endl;
// ---------- init MBTCP ----------
// cout << "--prefix-sm-ready-timeout - время на ожидание старта SM" << endl;
cout << " Настройки протокола TCP: " << endl;
cout << "--prefix-gateway-iaddr hostname,IP - IP опрашиваемого узла" << endl;
cout << "--prefix-gateway hostname,IP - IP опрашиваемого узла" << endl;
cout << "--prefix-gateway-port num - port на опрашиваемом узле" << endl;
cout << "--prefix-recv-timeout msec - Таймаут на приём одного сообщения" << endl;
cout << "--prefix-timeout msec - Таймаут для определения отсутсвия соединения" << endl;
cout << "--prefix-persistent-connection 0,1 - Не закрывать соединение на каждом цикле опроса" << endl;
}
// -----------------------------------------------------------------------------
......@@ -197,3 +264,34 @@ MBTCPMaster* MBTCPMaster::init_mbmaster( int argc, const char* const* argv,
return new MBTCPMaster(ID,icID,ic,prefix);
}
// -----------------------------------------------------------------------------
void MBTCPMaster::execute()
{
no_extimer = true;
try
{
askTimer(tmExchange,0);
}
catch(...){}
initMB(false);
while(1)
{
try
{
step();
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << myname << "(execute): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << myname << "(execute): catch ..." << endl;
}
msleep(polltime);
}
}
// -----------------------------------------------------------------------------
......@@ -5,12 +5,22 @@
#include <string>
#include <map>
#include <vector>
#include "MBExchange.h"
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "modbus/ModbusRTUMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "IOBase.h"
#include "VTypes.h"
// -----------------------------------------------------------------------------
class RTUExchange:
public MBExchange
public UniSetObject_LT
{
public:
RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID,
......@@ -25,25 +35,232 @@ class RTUExchange:
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtRTU188, /*!< RTU188 (Fastwell) */
dtMTR /*!< MTR (DEIF) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
// -------------------------------------------------------------------------------
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:
ModbusRTUMaster* mbrtu;
RTUDeviceMap rmap;
ModbusRTUMaster* mb;
UniSetTypes::uniset_mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
bool use485F;
bool transmitCtl;
virtual void step();
virtual void poll();
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
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 );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
virtual ModbusClient* initMB( bool reopen=false );
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
void initMB( bool reopen=false );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
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 );
void readConfiguration();
private:
RTUExchange();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_usec;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
bool activated;
int activateTimeout;
bool rs_pre_clean;
bool noQueryOptimization;
bool allNotRespond;
Trigger trAllNotRespond;
PassiveTimer ptAllNotRespond;
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _RS_EXCHANGE_H_
......
......@@ -6,6 +6,6 @@ includedir=@includedir@
Name: libUniSetMBTCPMaster
Description: Support library for UniSetModbusTCPMaster
Requires: libUniSetExtensions libUniSetSharedMemory
Version: 1.3.1
Version: 1.2.1
Libs: -L${libdir} -lUniSetMBTCPMaster
Cflags: -I${includedir}/uniset
......@@ -6,6 +6,6 @@ includedir=@includedir@
Name: libUniSetRTU
Description: Support library for UniSetRTUExchange
Requires: libUniSetExtensions
Version: 2.1.0
Version: 2.0.0
Libs: -L${libdir} -lUniSetRTU
Cflags: -I${includedir}/uniset
......@@ -88,7 +88,7 @@ int main( int argc, char **argv )
ModbusRTU::ModbusAddr end = 255;
int tout = 20;
DebugStream dlog;
//string tofile("");
string tofile("");
int use485 = 0;
ComPort::StopBits sbits = ComPort::OneBit;
ComPort::Parity parity = ComPort::NoParity;
......@@ -363,7 +363,6 @@ int main( int argc, char **argv )
return 1;
}
return 0;
}
catch( ModbusRTU::mbException& ex )
{
......@@ -382,7 +381,7 @@ int main( int argc, char **argv )
cerr << "(mtr-setup): catch(...)" << endl;
}
return 1;
return 0;
}
// --------------------------------------------------------------------------
char* checkArg( int i, int argc, char* argv[] )
......
......@@ -4,14 +4,11 @@ uniset-start.sh -f ./uniset-rtuexchange --confile test.xml \
--smemory-id SharedMemory \
--rs-dev /dev/cbsideA0 \
--rs-name RTUExchange \
--rs-speed 115200 \
--rs-speed 38400 \
--rs-filter-field rs \
--rs-filter-value 4 \
--rs-filter-value 1 \
--dlog-add-levels info,crit,warn,level4,level3 \
--rs-force 0 \
--rs-force-out 0 \
--rs-polltime 500 \
--rs-set-prop-prefix \
#,level3
# --rs-force 1 \
......@@ -4,19 +4,11 @@
--confile test.xml \
--mbtcp-name MBMaster1 \
--smemory-id SharedMemory \
--dlog-add-levels info,crit,warn,level4,level3,level9 \
--mbtcp-set-prop-prefix \
--mbtcp-filter-field rs \
--mbtcp-filter-value 5 \
--mbtcp-gateway-iaddr 192.168.1.42 \
--dlog-add-levels info,crit,warn,level4,level3 \
--mbtcp-filter-field mbtcp \
--mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000 \
--mbtcp-force-disconnect 1 \
--mbtcp-polltime 3000 \
--mbtcp-force-out 1 \
$*
#--mbtcp-exchange-mode-id MB1_Mode_AS \
--mbtcp-force-disconnect 1
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
#--mbtcp-set-prop-prefix rs_ \
......@@ -9,12 +9,12 @@ using namespace VTypes;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: vtconv TYPE[F2|F2r|F4|I2|U2|I2r|U2r] hex1 hex2 [hex3 hex4]\n");
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
/*
VTypes::F2 f2;
f2.raw.val = 2.345;
......@@ -58,7 +58,8 @@ int main( int argc, const char **argv )
cout << "-------------" << endl << endl;
// return 0;
*/
unsigned short v[4];
memset(v,0,sizeof(v));
......@@ -89,13 +90,6 @@ int main( int argc, const char **argv )
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F2r") )
{
VTypes::F2r f(v,sizeof(v));
cout << "(F2r): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F4") )
{
VTypes::F4 f(v,sizeof(v));
......@@ -112,13 +106,6 @@ int main( int argc, const char **argv )
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"I2r") )
{
VTypes::I2r i(v,sizeof(v));
cout << "(I2r): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"U2") )
{
VTypes::U2 i(v,sizeof(v));
......@@ -126,13 +113,6 @@ int main( int argc, const char **argv )
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else if( !strcmp(type,"U2r") )
{
VTypes::U2r i(v,sizeof(v));
cout << "(U2r): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else
{
cout << " Unknown type: " << type << endl;
......
#ifndef _RTUEXCHANGE_H_
#define _RTUEXCHANGE_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "modbus/ModbusRTUMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "MTR.h"
#include "RTUStorage.h"
#include "IOBase.h"
#include "VTypes.h"
// -----------------------------------------------------------------------------
class RTUExchange:
public UniSetObject_LT
{
public:
RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID,
SharedMemory* ic=0, const std::string prefix="rs" );
virtual ~RTUExchange();
/*! глобальная функция для инициализации объекта */
static RTUExchange* init_rtuexchange( int argc, const char* const* argv,
UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="rs" );
/*! глобальная функция для вывода help-а */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< неизвестный */
dtRTU, /*!< RTU (default) */
dtRTU188, /*!< RTU188 (Fastwell) */
dtMTR /*!< MTR (DEIF) */
};
static DeviceType getDeviceType( const std::string dtype );
friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt );
// -------------------------------------------------------------------------------
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;
UniSetTypes::uniset_mutex mbMutex;
std::string devname;
ComPort::Speed defSpeed;
int recv_timeout;
bool use485F;
bool transmitCtl;
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
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 );
void sysCommand( UniSetTypes::SystemMessage *msg );
void sensorInfo( UniSetTypes::SensorMessage*sm );
void timerInfo( UniSetTypes::TimerMessage *tm );
void askSensors( UniversalIO::UIOCommand cmd );
void initOutput();
void waitSMReady();
virtual bool activateObject();
// действия при завершении работы
virtual void sigterm( int signo );
void initMB( bool reopen=false );
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
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 );
void readConfiguration();
private:
RTUExchange();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< флаг означающий, что надо сохранять в SM, даже если значение не менялось */
bool force_out; /*!< флаг означающий, принудительного чтения выходов */
bool mbregFromID;
int polltime; /*!< переодичность обновления данных, [мсек] */
timeout_t sleepPause_usec;
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
bool activated;
int activateTimeout;
bool rs_pre_clean;
bool noQueryOptimization;
bool allNotRespond;
Trigger trAllNotRespond;
PassiveTimer ptAllNotRespond;
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _RS_EXCHANGE_H_
// -----------------------------------------------------------------------------
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libUniSetRTU
Description: Support library for UniSetRTUExchange
Requires: libUniSetExtensions
Version: 2.0.0
Libs: -L${libdir} -lUniSetRTU
Cflags: -I${includedir}/uniset
#include <sys/wait.h>
#include <sstream>
#include "ObjectsActivator.h"
#include "Extensions.h"
#include "RTUExchange.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main( int argc, char** argv )
{
try
{
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{
cout << "--smemory-id objectName - SharedMemory objectID. Default: read from <SharedMemory>" << endl;
cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--rs-logfile filename - logfilename. Default: rtuexchange.log" << endl;
cout << endl;
RTUExchange::help_print(argc, argv);
return 0;
}
string confile=UniSetTypes::getArgParam("--confile", argc, argv, "configure.xml");
conf = new Configuration( argc, argv, confile );
string logfilename(conf->getArgParam("--rs-logfile"));
if( logfilename.empty() )
logfilename = "rtuexchange.log";
conf->initDebug(dlog,"dlog");
std::ostringstream logname;
string dir(conf->getLogDir());
logname << dir << logfilename;
unideb.logFile( logname.str() );
dlog.logFile( logname.str() );
ObjectId shmID = DefaultObjectId;
string sID = conf->getArgParam("--smemory-id");
if( !sID.empty() )
shmID = conf->getControllerID(sID);
else
shmID = getSharedMemoryID();
if( shmID == DefaultObjectId )
{
cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
return 1;
}
RTUExchange* rs = RTUExchange::init_rtuexchange(argc,argv,shmID,0,"rs");
if( !rs )
{
dlog[Debug::CRIT] << "(rtuexchange): init не прошёл..." << endl;
return 1;
}
ObjectsActivator act;
act.addObject(static_cast<class UniSetObject*>(rs));
SystemMessage sm(SystemMessage::StartUp);
act.broadcast( sm.transport_msg() );
unideb(Debug::ANY) << "\n\n\n";
unideb[Debug::ANY] << "(main): -------------- RTU Exchange START -------------------------\n\n";
dlog(Debug::ANY) << "\n\n\n";
dlog[Debug::ANY] << "(main): -------------- RTU Exchange START -------------------------\n\n";
act.run(false);
while( waitpid(-1, 0, 0) > 0 );
return 0;
}
catch( Exception& ex )
{
dlog[Debug::CRIT] << "(rtuexchange): " << ex << std::endl;
}
catch(...)
{
dlog[Debug::CRIT] << "(rtuexchange): catch ..." << std::endl;
}
while( waitpid(-1, 0, 0) > 0 );
return 1;
}
// --------------------------------------------------------------------------
#include <string>
#include <getopt.h>
#include "modbus/ModbusRTUMaster.h"
#include "RTUStorage.h"
// --------------------------------------------------------------------------
using namespace UniSetTypes;
using namespace std;
// --------------------------------------------------------------------------
static struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "slave", required_argument, 0, 'q' },
{ "device", required_argument, 0, 'd' },
{ "verbose", no_argument, 0, 'v' },
{ "speed", required_argument, 0, 's' },
{ "use485F", no_argument, 0, 'y' },
{ NULL, 0, 0, 0 }
};
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: rtustate -q addr\n");
printf("-h|--help - this message\n");
printf("[-q|--slave] addr - Slave address. Default: 0x01.\n");
printf("[-d|--device] dev - use device dev. Default: /dev/ttyS0\n");
printf("[-s|--speed] speed - 9600,14400,19200,38400,57600,115200. Default: 38400.\n");
printf("[-t|--timeout] msec - Timeout. Default: 2000.\n");
printf("[-v|--verbose] - Print all messages to stdout\n");
printf("[-y|--use485F] - use RS485 Fastwel.\n");
}
// --------------------------------------------------------------------------
int main( int argc, char **argv )
{
int optindex = 0;
int opt = 0;
int verb = 0;
string dev("/dev/ttyS0");
string speed("38400");
ModbusRTU::ModbusAddr slaveaddr = 0x01;
int tout = 2000;
DebugStream dlog;
int use485 = 0;
try
{
while( (opt = getopt_long(argc, argv, "hva:d:s:t:q:",longopts,&optindex)) != -1 )
{
switch (opt)
{
case 'h':
print_help();
return 0;
case 'd':
dev = string(optarg);
break;
case 's':
speed = string(optarg);
break;
case 't':
tout = uni_atoi(optarg);
break;
case 'q':
slaveaddr = ModbusRTU::str2mbAddr(optarg);
break;
case 'v':
verb = 1;
break;
case 'y':
use485 = 1;
break;
case '?':
default:
printf("? argumnet\n");
return 0;
}
}
if( verb )
{
cout << "(init): dev=" << dev
<< " speed=" << speed
<< " timeout=" << tout << " msec "
<< endl;
}
ModbusRTUMaster mb(dev,use485);
if( verb )
dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
mb.setTimeout(tout);
mb.setSpeed(speed);
mb.setLog(dlog);
RTUStorage rtu(slaveaddr);
rtu.poll(&mb);
cout << rtu << endl;
for( int i=0; i<24; i++ )
cout << "UNIO1 AI" << i << ": " << rtu.getFloat( RTUStorage::nJ1, i, UniversalIO::AnalogInput ) << endl;
for( int i=0; i<24; i++ )
cout << "UNIO1 DI" << i << ": " << rtu.getState( RTUStorage::nJ1, i, UniversalIO::DigitalInput ) << endl;
return 0;
}
catch( ModbusRTU::mbException& ex )
{
cerr << "(rtustate): " << ex << endl;
}
catch(SystemError& err)
{
cerr << "(rtustate): " << err << endl;
}
catch(Exception& ex)
{
cerr << "(rtustate): " << ex << endl;
}
catch(...)
{
cerr << "(rtustate): catch(...)" << endl;
}
return 1;
}
// --------------------------------------------------------------------------
#!/bin/sh
uniset-start.sh -f ./uniset-rtuexchange --confile test.xml \
--smemory-id SharedMemory \
--rs-dev /dev/cbsideA0 \
--rs-name RTUExchange \
--rs-speed 38400 \
--rs-filter-field rs \
--rs-filter-value 1 \
--dlog-add-levels info,crit,warn,level4,level3 \
--rs-force 0 \
--rs-force-out 0 \
#,level3
# --rs-force 1 \
// --------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include "UniSetTypes.h"
#include "VTypes.h"
// --------------------------------------------------------------------------
using namespace std;
using namespace VTypes;
// --------------------------------------------------------------------------
static void print_help()
{
printf("Usage: vtconv TYPE[F2|F4|I2|U2] hex1 hex2 [hex3 hex4]\n");
}
// --------------------------------------------------------------------------
int main( int argc, const char **argv )
{
VTypes::F2 f2;
f2.raw.val = 2.345;
cout << "Example(F2): float=" << f2.raw.val
<< " regs:"
<< " v[0]=" << f2.raw.v[0]
<< " v[1]=" << f2.raw.v[1]
<< endl;
VTypes::F4 f4;
f4.raw.val = 2.345123123;
cout << "Example(F4): float=" << f4.raw.val
<< " regs:"
<< " v[0]=" << f4.raw.v[0]
<< " v[1]=" << f4.raw.v[1]
<< " v[2]=" << f4.raw.v[2]
<< " v[3]=" << f4.raw.v[3]
<< endl;
cout << "-------------" << endl << endl;
VTypes::I2 i2;
i2.raw.val = -6553004;
cout << "Example(I2): int=" << i2.raw.val
<< " regs:"
<< " v[0]=" << i2.raw.v[0]
<< " v[1]=" << i2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
VTypes::U2 u2;
u2.raw.val = 655300400;
cout << "Example(U2): unsigned int=" << u2.raw.val
<< " regs:"
<< " v[0]=" << u2.raw.v[0]
<< " v[1]=" << u2.raw.v[1]
<< endl;
cout << "-------------" << endl << endl;
// return 0;
unsigned short v[4];
memset(v,0,sizeof(v));
const char* type="";
if( argc<3 )
{
print_help();
return 1;
}
type = argv[1];
v[0] = UniSetTypes::uni_atoi(argv[2]);
if( argc>3 )
v[1] = UniSetTypes::uni_atoi(argv[3]);
if( argc>4 )
v[2] = UniSetTypes::uni_atoi(argv[4]);
if( argc>5 )
v[3] = UniSetTypes::uni_atoi(argv[5]);
if( !strcmp(type,"F2") )
{
VTypes::F2 f(v,sizeof(v));
cout << "(F2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"F4") )
{
VTypes::F4 f(v,sizeof(v));
cout << "(F4): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " v[2]=" << v[2]
<< " v[3]=" << v[3]
<< " --> (float) " << (float)f << endl;
}
else if( !strcmp(type,"I2") )
{
VTypes::I2 i(v,sizeof(v));
cout << "(I2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (int) " << (int)i << endl;
}
else if( !strcmp(type,"U2") )
{
VTypes::U2 i(v,sizeof(v));
cout << "(U2): v[0]=" << v[0]
<< " v[1]=" << v[1]
<< " --> (unsigned int) " << (unsigned int)i << endl;
}
else
{
cout << " Unknown type: " << type << endl;
}
return 0;
}
// --------------------------------------------------------------------------
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