Commit 6cfdf2fe authored by Pavel Vainerman's avatar Pavel Vainerman

add new realisation MBTCPMaster

parent b6dd259c
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Name: libuniset Name: libuniset
Version: 0.96 Version: 0.96
Release: eter53 Release: eter56
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
License: GPL License: GPL
Group: Development/C++ Group: Development/C++
...@@ -175,6 +175,15 @@ rm -f %buildroot%_libdir/*.la ...@@ -175,6 +175,15 @@ rm -f %buildroot%_libdir/*.la
%exclude %_pkgconfigdir/libUniSet.pc %exclude %_pkgconfigdir/libUniSet.pc
%changelog %changelog
* Mon Sep 07 2009 Pavel Vainerman <pv@altlinux.ru> 0.96-eter55
- new build
* Mon Sep 07 2009 Pavel Vainerman <pv@altlinux.ru> 0.96-eter54
- rebuild for new ModbusType parameters
* Mon Sep 07 2009 Pavel Vainerman <pv@altlinux.ru> 0.96-eter53
- rebuild for new MBTCPMaster
* Sun Sep 06 2009 Pavel Vainerman <pv@altlinux.ru> 0.96-eter52 * Sun Sep 06 2009 Pavel Vainerman <pv@altlinux.ru> 0.96-eter52
- minor fixes in MBTCPMAster - minor fixes in MBTCPMAster
......
// $Id: MBMaster.h,v 1.7 2009/03/03 10:33:27 pv Exp $
// -----------------------------------------------------------------------------
#ifndef _MBMaster_H_
#define _MBMaster_H_
// -----------------------------------------------------------------------------
#include <string>
#include <vector>
#include "UniSetObject_LT.h"
#include "IONotifyController.h"
#include "modbus/ModbusTCPMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "SharedMemory.h"
#include "IOBase.h"
#include "SMInterface.h"
// -----------------------------------------------------------------------------
class MBMaster:
public UniSetObject_LT
{
public:
MBMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmId, SharedMemory* ic=0,
std::string prefix="mbtcp" );
virtual ~MBMaster();
/*! */
static MBMaster* init_mbmaster( int argc, const char* const* argv, UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
std::string prefix="mbtcp" );
/*! help- */
static void help_print( int argc, const char* const* argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
struct MBProperty:
public IOBase
{
ModbusRTU::ModbusAddr mbaddr; /*!< */
ModbusRTU::ModbusData mbreg; /*!< */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< / */
short nbit; /*!< bit number (for func=[0x01,0x02]) */
MBProperty():
mbaddr(0),mbreg(0),
mbfunc(ModbusRTU::fnUnknown),nbit(0)
{}
friend std::ostream& operator<<( std::ostream& os, MBProperty& p );
};
protected:
typedef std::vector<MBProperty> MBMap;
MBMap mbmap; /*!< / */
unsigned int maxItem; /*!< ( ) */
ModbusTCPMaster* mb;
UniSetTypes::uniset_mutex mbMutex;
std::string iaddr;
int port;
int recv_timeout;
ModbusRTU::ModbusAddr myaddr;
xmlNode* cnode;
std::string s_field;
std::string s_fvalue;
SMInterface* shm;
void step();
void poll();
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();
long readReg( MBMap::iterator& p );
bool writeReg( MBMap::iterator& p, long val );
virtual bool activateObject();
//
virtual void sigterm( int signo );
void init_mb();
void initIterators();
bool initItem( UniXML_iterator& it );
bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
void readConfiguration();
bool check_item( UniXML_iterator& it );
private:
MBMaster();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool mbregFromID;
bool force; /*!< , SM, */
bool force_out; /*!< , */
int polltime; /*!< , [] */
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
Trigger trTimeout;
PassiveTimer ptTimeout;
bool activated;
int activateTimeout;
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _MBMaster_H_
// -----------------------------------------------------------------------------
#ifndef _MBTCPMaster_H_
#define _MBTCPMaster_H_
// -----------------------------------------------------------------------------
#include <ostream>
#include <string>
#include <map>
#include <vector>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
#include "modbus/ModbusTCPMaster.h"
#include "PassiveTimer.h"
#include "Trigger.h"
#include "Mutex.h"
#include "Calibration.h"
#include "SMInterface.h"
#include "SharedMemory.h"
#include "IOBase.h"
#include "VTypes.h"
// -----------------------------------------------------------------------------
/*!
Реализация Modbus TCP Master-а для работы со многими ModbusRTU устройствами,
но только через ОДИН ModbusTCP-шлюз.
*/
class MBTCPMaster:
public UniSetObject_LT
{
public:
MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="mbtcp" );
virtual ~MBTCPMaster();
/*! */
static MBTCPMaster* init_mbmaster( int argc, const char** argv,
UniSetTypes::ObjectId shmID, SharedMemory* ic=0,
const std::string prefix="mbtcp" );
/*! help- */
static void help_print( int argc, const char** argv );
static const int NoSafetyState=-1;
enum Timer
{
tmExchange
};
enum DeviceType
{
dtUnknown, /*!< */
dtRTU /*!< RTU (default) */
};
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;
typedef std::map<ModbusRTU::ModbusData,RegInfo*> RegMap;
struct RegInfo
{
RegInfo():
mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown),
dev(0),offset(0),
q_num(0),q_count(1)
{}
ModbusRTU::ModbusData mbval;
ModbusRTU::ModbusData mbreg; /*!< */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< / */
PList slst;
RTUDevice* dev;
int offset;
// optimization
int q_num; /*! number in query */
int q_count; /*! count registers for query */
RegMap::iterator rit;
};
friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
struct RTUDevice
{
RTUDevice():
respnond(false),
mbaddr(0),
dtype(dtUnknown),
resp_id(UniSetTypes::DefaultObjectId),
resp_state(false),
resp_invert(false),
resp_real(true),
resp_init(false)
{
resp_trTimeout.change(false);
}
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;
// 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;
ModbusTCPMaster* mb;
UniSetTypes::uniset_mutex mbMutex;
std::string iaddr;
// ost::InetAddress* ia;
int port;
int recv_timeout;
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 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 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();
bool check_item( UniXML_iterator& it );
private:
MBTCPMaster();
bool initPause;
UniSetTypes::uniset_mutex mutex_start;
bool force; /*!< , SM, */
bool force_out; /*!< , */
bool mbregFromID;
int polltime; /*!< , [] */
PassiveTimer ptHeartBeat;
UniSetTypes::ObjectId sidHeartBeat;
int maxHeartBeat;
IOController::AIOStateList::iterator aitHeartBeat;
UniSetTypes::ObjectId test_id;
UniSetTypes::uniset_mutex pollMutex;
bool activated;
int activateTimeout;
bool noQueryOptimization;
bool allNotRespond;
Trigger trAllNotRespond;
PassiveTimer ptAllNotRespond;
std::string prefix;
};
// -----------------------------------------------------------------------------
#endif // _MBTCPMaster_H_
// -----------------------------------------------------------------------------
...@@ -6,7 +6,7 @@ libUniSetMBTCPMaster_la_LIBADD = $(top_builddir)/lib/libUniSet.la \ ...@@ -6,7 +6,7 @@ libUniSetMBTCPMaster_la_LIBADD = $(top_builddir)/lib/libUniSet.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \ $(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS) $(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 $(SIGC_CFLAGS)
libUniSetMBTCPMaster_la_SOURCES = MBMaster.cc libUniSetMBTCPMaster_la_SOURCES = MBTCPMaster.cc
@PACKAGE@_mbtcpmaster_SOURCES = main.cc @PACKAGE@_mbtcpmaster_SOURCES = main.cc
@PACKAGE@_mbtcpmaster_LDADD = libUniSetMBTCPMaster.la $(top_builddir)/lib/libUniSet.la \ @PACKAGE@_mbtcpmaster_LDADD = libUniSetMBTCPMaster.la $(top_builddir)/lib/libUniSet.la \
......
// $Id: rsexchange.cc,v 1.2 2008/06/06 11:03:32 pv Exp $ // $Id: rsexchange.cc,v 1.2 2008/06/06 11:03:32 pv Exp $
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <sstream> #include <sstream>
#include "MBMaster.h" #include "MBTCPMaster.h"
#include "Configuration.h" #include "Configuration.h"
#include "Debug.h" #include "Debug.h"
#include "ObjectsActivator.h" #include "ObjectsActivator.h"
...@@ -11,7 +11,7 @@ using namespace std; ...@@ -11,7 +11,7 @@ using namespace std;
using namespace UniSetTypes; using namespace UniSetTypes;
using namespace UniSetExtensions; using namespace UniSetExtensions;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
int main( int argc, char** argv ) int main( int argc, const char** argv )
{ {
if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) ) if( argc>1 && (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) )
{ {
...@@ -19,7 +19,7 @@ int main( int argc, char** argv ) ...@@ -19,7 +19,7 @@ int main( int argc, char** argv )
cout << "--confile filename - configuration file. Default: configure.xml" << endl; cout << "--confile filename - configuration file. Default: configure.xml" << endl;
cout << "--mbtcp-logfile filename - logfilename. Default: mbtcpmaster.log" << endl; cout << "--mbtcp-logfile filename - logfilename. Default: mbtcpmaster.log" << endl;
cout << endl; cout << endl;
MBMaster::help_print(argc, argv); MBTCPMaster::help_print(argc, argv);
return 0; return 0;
} }
...@@ -53,7 +53,7 @@ int main( int argc, char** argv ) ...@@ -53,7 +53,7 @@ int main( int argc, char** argv )
return 1; return 1;
} }
MBMaster* mb = MBMaster::init_mbmaster(argc,argv,shmID); MBTCPMaster* mb = MBTCPMaster::init_mbmaster(argc,argv,shmID);
if( !mb ) if( !mb )
{ {
dlog[Debug::CRIT] << "(mbmaster): init ۣ..." << endl; dlog[Debug::CRIT] << "(mbmaster): init ۣ..." << endl;
......
#!/bin/sh #!/bin/sh
uniset-start.sh -f ./uniset-mbtcpmaster --mbtcp-name MBMaster1 --confile test.xml \ uniset-start.sh -f ./uniset-mbtcpmaster --mbtcp-name MBTCPExchange1 \
--dlog-add-levels info,crit,warn \ --dlog-add-levels info,crit,warn \
--mbtcp-iaddr 127.0.0.1 --mbtcp-port 2048 --mbtcp-filter-field CAN2sender \
--mbtcp-filter-value SYSTSNode \
--mbtcp-reg-from-id 1 \
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 2048
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1 #--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
#--mbtcp-reg-from-id 1
\ No newline at end of file
...@@ -1622,6 +1622,10 @@ void RTUExchange::rtuQueryOptimization( RTUDeviceMap& m ) ...@@ -1622,6 +1622,10 @@ void RTUExchange::rtuQueryOptimization( RTUDeviceMap& m )
dlog[Debug::INFO] << myname << "(rtuQueryOptimization): optimization..." << endl; dlog[Debug::INFO] << myname << "(rtuQueryOptimization): optimization..." << endl;
// MAXLEN/2 - это количество слов данных в ответе
// 10 - на всякие служебные заголовки
int maxcount = ModbusRTU::MAXLENPACKET/2 - 10;
for( RTUExchange::RTUDeviceMap::iterator it1=m.begin(); it1!=m.end(); ++it1 ) for( RTUExchange::RTUDeviceMap::iterator it1=m.begin(); it1!=m.end(); ++it1 )
{ {
RTUDevice* d(it1->second); RTUDevice* d(it1->second);
...@@ -1642,6 +1646,9 @@ void RTUExchange::rtuQueryOptimization( RTUDeviceMap& m ) ...@@ -1642,6 +1646,9 @@ void RTUExchange::rtuQueryOptimization( RTUDeviceMap& m )
break; break;
beg->second->q_count++; beg->second->q_count++;
if( beg->second->q_count > maxcount )
break;
reg = it->second->mbreg + it->second->offset; reg = it->second->mbreg + it->second->offset;
it->second->q_num = beg->second->q_count; it->second->q_num = beg->second->q_count;
it->second->q_count = 0; it->second->q_count = 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