Commit ac610fd2 authored by Pavel Vainerman's avatar Pavel Vainerman

(ModbusMaster): рефаторинг (перешёл по возможности на shared_ptr),

переписал механизм реализации pollfactor (частота опроса).
parent 8ab0dba0
......@@ -37,8 +37,6 @@ Version 2.0
- unetudp: добавить возмоность привязать номера текущего посылаемого и принимаемого пакетов к датчику
- ModbusMaster: встроить возможность задать 'pulsar' (регистр сердцебиения)
- ModbusMaster: сделать RegMap unordered_map-ом по pollfactor
(список регистров опроса формироваать по приоритету опроса и каждому такому списку уже применять oprimization-query)
- IOBase: выдавать warning если заданые одновременно jardelay,ondelay и offdelay
......
......@@ -13,7 +13,7 @@
Name: libuniset2
Version: 2.1
Release: alt21
Release: alt22
Summary: UniSet - library for building distributed industrial control systems
......@@ -456,6 +456,9 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%changelog
* Sun Sep 06 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt22
- refactoring (use shared_ptr), change pollfactor realisation..
* Sat Sep 05 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt21
- (modbus slave): add more logs..
......
......@@ -4,7 +4,7 @@
#include <ostream>
#include <string>
#include <map>
#include <vector>
#include <unordered_map>
#include <memory>
#include "IONotifyController.h"
#include "UniSetObject_LT.h"
......@@ -84,7 +84,7 @@ class MBExchange:
RSProperty():
nbit(-1), vType(VTypes::vtUnknown),
rnum(VTypes::wsize(VTypes::vtUnknown)),
nbyte(0), reg(0)
nbyte(0)
{}
// т.к. IOBase содержит rwmutex с запрещённым конструктором копирования
......@@ -94,7 +94,7 @@ class MBExchange:
RSProperty( RSProperty&& r ) = default;
RSProperty& operator=(RSProperty&& r) = default;
RegInfo* reg;
std::shared_ptr<RegInfo> reg;
};
friend std::ostream& operator<<( std::ostream& os, const RSProperty& p );
......@@ -102,7 +102,7 @@ class MBExchange:
typedef std::list<RSProperty> PList;
static std::ostream& print_plist( std::ostream& os, const PList& p );
typedef std::map<ModbusRTU::RegID, RegInfo*> RegMap;
typedef std::map<ModbusRTU::RegID, std::shared_ptr<RegInfo>> RegMap;
struct RegInfo
{
// т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования
......@@ -126,7 +126,7 @@ class MBExchange:
PList slst;
ModbusRTU::RegID id;
RTUDevice* dev;
std::shared_ptr<RTUDevice> dev;
// only for RTU188
RTUStorage::RTUJack rtuJack;
......@@ -151,11 +151,6 @@ class MBExchange:
// Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
// ещё не инициализировано из SM
bool sm_initOK; /*!< инициализировалось ли значение из SM */
/*! приоритет опроса, 0,1 - высший,
* 1...n - задаёт "часоту" опроса. Т.е. каждые 1...n циклов
*/
int pollfactor = { 0 };
};
friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
......@@ -175,12 +170,12 @@ class MBExchange:
mode_id(UniSetTypes::DefaultObjectId),
mode(emNone),
speed(ComPort::ComSpeed38400),
rtu(0)
rtu188(0)
{
}
ModbusRTU::ModbusAddr mbaddr; /*!< адрес устройства */
RegMap regmap;
std::unordered_map<unsigned int, std::shared_ptr<RegMap>> pollmap;
DeviceType dtype; /*!< тип устройства */
......@@ -208,14 +203,14 @@ class MBExchange:
// специфические поля для RS
ComPort::Speed speed;
RTUStorage* rtu;
std::shared_ptr<RTUStorage> rtu188;
std::string getShortInfo() const;
};
friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
typedef std::map<ModbusRTU::ModbusAddr, RTUDevice*> RTUDeviceMap;
typedef std::map<ModbusRTU::ModbusAddr, std::shared_ptr<RTUDevice>> RTUDeviceMap;
friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
void printMap(RTUDeviceMap& d);
......@@ -256,14 +251,14 @@ class MBExchange:
InitRegInfo():
dev(0), mbreg(0),
mbfunc(ModbusRTU::fnUnknown),
initOK(false), ri(0)
initOK(false)
{}
RSProperty p;
RTUDevice* dev;
std::shared_ptr<RTUDevice> dev;
ModbusRTU::ModbusData mbreg;
ModbusRTU::SlaveFunctionCode mbfunc;
bool initOK;
RegInfo* ri;
std::shared_ptr<RegInfo> ri;
};
typedef std::list<InitRegInfo> InitList;
......@@ -272,14 +267,14 @@ class MBExchange:
bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p );
bool allInitOK;
RTUDeviceMap rmap;
RTUDeviceMap devices;
InitList initRegList; /*!< список регистров для инициализации */
UniSetTypes::uniset_rwmutex pollMutex;
virtual std::shared_ptr<ModbusClient> initMB( bool reopen = false ) = 0;
virtual bool poll();
bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
bool pollRTU( std::shared_ptr<RTUDevice>& dev, RegMap::iterator& it );
void updateSM();
void updateRTU(RegMap::iterator& it);
......@@ -301,15 +296,15 @@ class MBExchange:
void initDeviceList();
void initOffsetList();
RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
RegInfo* addReg( RegMap& rmap, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, RTUDevice* dev );
std::shared_ptr<RTUDevice> addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
std::shared_ptr<RegInfo> addReg(std::shared_ptr<RegMap>& devices, ModbusRTU::RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, std::shared_ptr<RTUDevice> dev );
RSProperty* addProp( PList& plist, RSProperty&& p );
bool initMTRitem( UniXML::iterator& it, RegInfo* p );
bool initRTU188item( UniXML::iterator& it, RegInfo* p );
bool initMTRitem(UniXML::iterator& it, std::shared_ptr<RegInfo>& p );
bool initRTU188item(UniXML::iterator& it, std::shared_ptr<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 initRegInfo(std::shared_ptr<RegInfo>& r, UniXML::iterator& it, std::shared_ptr<RTUDevice>& dev );
bool initRTUDevice( std::shared_ptr<RTUDevice>& d, UniXML::iterator& it );
virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it );
std::string initPropPrefix( const std::string& def_prop_prefix = "" );
......
......@@ -48,7 +48,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if( shm->isLocalwork() )
{
readConfiguration();
rtuQueryOptimization(rmap);
rtuQueryOptimization(devices);
initDeviceList();
}
else
......@@ -58,7 +58,7 @@ MBTCPMaster::MBTCPMaster( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
pollThread->setFinalAction(this, &MBTCPMaster::final_thread);
if( mblog->is_info() )
printMap(rmap);
printMap(devices);
}
// -----------------------------------------------------------------------------
MBTCPMaster::~MBTCPMaster()
......
......@@ -128,7 +128,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
if( shm->isLocalwork() )
{
readConfiguration();
rtuQueryOptimization(rmap);
rtuQueryOptimization(devices);
initDeviceList();
}
else
......@@ -145,7 +145,7 @@ MBTCPMultiMaster::MBTCPMultiMaster( UniSetTypes::ObjectId objId, UniSetTypes::Ob
ptReopen.setTiming(default_timeout);
if( mblog->is_info() )
printMap(rmap);
printMap(devices);
}
// -----------------------------------------------------------------------------
MBTCPMultiMaster::~MBTCPMultiMaster()
......
......@@ -70,7 +70,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
if( shm->isLocalwork() )
{
readConfiguration();
rtuQueryOptimization(rmap);
rtuQueryOptimization(devices);
initDeviceList();
}
else
......@@ -79,7 +79,7 @@ RTUExchange::RTUExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shm
initMB(false);
if( dlog()->is_info() )
printMap(rmap);
printMap(devices);
}
// -----------------------------------------------------------------------------
void RTUExchange::help_print( int argc, const char* const* argv )
......@@ -204,9 +204,9 @@ bool RTUExchange::poll()
bool allNotRespond = true;
ComPort::Speed s = mbrtu->getSpeed();
for( auto it1 : rmap )
for( auto it1 : devices )
{
RTUDevice* d(it1.second);
auto d = it1.second;
if( d->mode_id != DefaultObjectId && d->mode == emSkipExchange )
continue;
......@@ -221,7 +221,7 @@ bool RTUExchange::poll()
if( d->dtype == MBExchange::dtRTU188 )
{
if( !d->rtu )
if( !d->rtu188 )
continue;
dlog3 << myname << "(pollRTU188): poll RTU188 "
......@@ -233,7 +233,7 @@ bool RTUExchange::poll()
if( rs_pre_clean )
mb->cleanupChannel();
d->rtu->poll(mbrtu);
d->rtu188->poll(mbrtu);
d->numreply++;
allNotRespond = false;
}
......@@ -249,38 +249,46 @@ bool RTUExchange::poll()
else
{
dlog3 << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " regs=" << d->regmap.size() << endl;
<< " regs=" << d->pollmap.size() << endl;
for( auto it = d->regmap.begin(); it != d->regmap.end(); ++it )
for( auto&& m: d->pollmap )
{
try
if( m.first!=0 && (ncycle % m.first) != 0 )
continue;
auto rmap = m.second;
for( auto&& it = rmap->begin(); it != rmap->end(); ++it )
{
if( d->dtype == RTUExchange::dtRTU || d->dtype == RTUExchange::dtMTR )
try
{
if( rs_pre_clean )
mb->cleanupChannel();
if( pollRTU(d, it) )
if( d->dtype == RTUExchange::dtRTU || d->dtype == RTUExchange::dtMTR )
{
d->numreply++;
allNotRespond = false;
if( rs_pre_clean )
mb->cleanupChannel();
if( pollRTU(d, it) )
{
d->numreply++;
allNotRespond = false;
}
}
}
}
catch( ModbusRTU::mbException& ex )
{
dlog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " reg=" << ModbusRTU::dat2str(it->second->mbreg)
<< " for sensors: ";
print_plist(dlog()->level3(), it->second->slst);
dlog()->level3() << " err: " << ex << endl;
}
catch( ModbusRTU::mbException& ex )
{
dlog3 << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " reg=" << ModbusRTU::dat2str(it->second->mbreg)
<< " for sensors: ";
print_plist(dlog()->level3(), it->second->slst);
dlog()->level3() << " err: " << ex << endl;
}
if( it == d->regmap.end() )
break;
if( it == rmap->end() )
break;
if( !checkProcActive() )
return false;
if( !checkProcActive() )
return false;
}
}
}
}
......
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