|
UniSet
2.0.0
|
00001 #ifndef _MBExchange_H_ 00002 #define _MBExchange_H_ 00003 // ----------------------------------------------------------------------------- 00004 #include <ostream> 00005 #include <string> 00006 #include <map> 00007 #include <vector> 00008 #include <memory> 00009 #include "IONotifyController.h" 00010 #include "UniSetObject_LT.h" 00011 #include "PassiveTimer.h" 00012 #include "Trigger.h" 00013 #include "Mutex.h" 00014 #include "Calibration.h" 00015 #include "SMInterface.h" 00016 #include "SharedMemory.h" 00017 #include "ThreadCreator.h" 00018 #include "IOBase.h" 00019 #include "VTypes.h" 00020 #include "MTR.h" 00021 #include "RTUStorage.h" 00022 #include "modbus/ModbusClient.h" 00023 // ----------------------------------------------------------------------------- 00027 class MBExchange: 00028 public UniSetObject_LT 00029 { 00030 public: 00031 MBExchange( UniSetTypes::ObjectId objId, UniSetTypes::ObjectId shmID, SharedMemory* ic=0, 00032 const std::string& prefix="mb" ); 00033 virtual ~MBExchange(); 00034 00036 static void help_print( int argc, const char* const* argv ); 00037 00038 static const int NoSafetyState=-1; 00039 00041 enum ExchangeMode 00042 { 00043 emNone=0, 00044 emWriteOnly=1, 00045 emReadOnly=2, 00046 emSkipSaveToSM=3, 00047 emSkipExchange=4 00048 }; 00049 00050 friend std::ostream& operator<<( std::ostream& os, const ExchangeMode& em ); 00051 00052 enum DeviceType 00053 { 00054 dtUnknown, 00055 dtRTU, 00056 dtMTR, 00057 dtRTU188 00058 }; 00059 00060 static DeviceType getDeviceType( const std::string& dtype ); 00061 friend std::ostream& operator<<( std::ostream& os, const DeviceType& dt ); 00062 00063 struct RTUDevice; 00064 struct RegInfo; 00065 00066 struct RSProperty: 00067 public IOBase 00068 { 00069 // only for RTU 00070 short nbit; 00071 VTypes::VType vType; 00072 short rnum; 00073 short nbyte; 00075 RSProperty(): 00076 nbit(-1),vType(VTypes::vtUnknown), 00077 rnum(VTypes::wsize(VTypes::vtUnknown)), 00078 nbyte(0),reg(0) 00079 {} 00080 00081 // т.к. IOBase содержит rwmutex с запрещённым конструктором копирования 00082 // приходится здесь тоже объявлять разрешенными только операции "перемещения" 00083 RSProperty( const RSProperty& r ) = delete; 00084 RSProperty& operator=(const RSProperty& r) = delete; 00085 RSProperty( RSProperty&& r ) = default; 00086 RSProperty& operator=(RSProperty&& r) = default; 00087 00088 RegInfo* reg; 00089 }; 00090 00091 friend std::ostream& operator<<( std::ostream& os, const RSProperty& p ); 00092 00093 typedef std::list<RSProperty> PList; 00094 static std::ostream& print_plist( std::ostream& os, const PList& p ); 00095 00096 typedef unsigned long RegID; 00097 00098 typedef std::map<RegID,RegInfo*> RegMap; 00099 struct RegInfo 00100 { 00101 // т.к. RSProperty содержит rwmutex с запрещённым конструктором копирования 00102 // приходится здесь тоже объявлять разрешенными только операции "перемещения" 00103 RegInfo( const RegInfo& r ) = default; 00104 RegInfo& operator=(const RegInfo& r) = delete; 00105 RegInfo( RegInfo&& r ) = delete; 00106 RegInfo& operator=(RegInfo&& r) = default; 00107 00108 RegInfo(): 00109 mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown), 00110 id(0),dev(0), 00111 rtuJack(RTUStorage::nUnknown),rtuChan(0), 00112 mtrType(MTR::mtUnknown), 00113 q_num(0),q_count(1),mb_initOK(true),sm_initOK(true) 00114 {} 00115 00116 ModbusRTU::ModbusData mbval; 00117 ModbusRTU::ModbusData mbreg; 00118 ModbusRTU::SlaveFunctionCode mbfunc; 00119 PList slst; 00120 RegID id; 00121 00122 RTUDevice* dev; 00123 00124 // only for RTU188 00125 RTUStorage::RTUJack rtuJack; 00126 int rtuChan; 00127 00128 // only for MTR 00129 MTR::MTRType mtrType; 00131 // optimization 00132 unsigned int q_num; 00133 unsigned int q_count; 00135 RegMap::iterator rit; 00136 00137 // начальная инициалиазция для "записываемых" регистров 00138 // Механизм: 00139 // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства. 00140 // при этом флаг mb_init=false пока не пройдёт успешной инициализации 00141 // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true. 00142 bool mb_initOK; 00144 // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров" 00145 // ещё не инициализировано из SM 00146 bool sm_initOK; 00147 }; 00148 00149 friend std::ostream& operator<<( std::ostream& os, RegInfo& r ); 00150 friend std::ostream& operator<<( std::ostream& os, RegInfo* r ); 00151 00152 struct RTUDevice 00153 { 00154 RTUDevice(): 00155 respnond(false), 00156 mbaddr(0), 00157 dtype(dtUnknown), 00158 resp_id(UniSetTypes::DefaultObjectId), 00159 resp_state(false), 00160 resp_invert(false), 00161 resp_real(false), 00162 resp_init(false), 00163 ask_every_reg(false), 00164 mode_id(UniSetTypes::DefaultObjectId), 00165 mode(emNone), 00166 speed(ComPort::ComSpeed38400), 00167 rtu(0) 00168 { 00169 resp_trTimeout.change(false); 00170 } 00171 00172 bool respnond; 00173 ModbusRTU::ModbusAddr mbaddr; 00174 RegMap regmap; 00175 00176 DeviceType dtype; 00178 UniSetTypes::ObjectId resp_id; 00179 IOController::IOStateList::iterator resp_it; 00180 PassiveTimer resp_ptTimeout; 00181 Trigger resp_trTimeout; 00182 bool resp_state; 00183 bool resp_invert; 00184 bool resp_real; 00185 bool resp_init; 00186 bool ask_every_reg; 00187 UniSetTypes::ObjectId mode_id; 00188 IOController::IOStateList::iterator mode_it; 00189 long mode; // режим работы с устройством (см. ExchangeMode) 00190 00191 // return TRUE if state changed 00192 bool checkRespond(); 00193 00194 // специфические поля для RS 00195 ComPort::Speed speed; 00196 RTUStorage* rtu; 00197 }; 00198 00199 friend std::ostream& operator<<( std::ostream& os, RTUDevice& d ); 00200 00201 typedef std::map<ModbusRTU::ModbusAddr,RTUDevice*> RTUDeviceMap; 00202 00203 friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d ); 00204 void printMap(RTUDeviceMap& d); 00205 00206 // ---------------------------------- 00207 static RegID genRegID( const ModbusRTU::ModbusData r, const int fn ); 00208 00209 enum Timer 00210 { 00211 tmExchange 00212 }; 00213 00214 void execute(); 00215 00216 protected: 00217 virtual void step(); 00218 virtual void sysCommand( const UniSetTypes::SystemMessage *msg ) override; 00219 virtual void sensorInfo( const UniSetTypes::SensorMessage*sm ) override; 00220 virtual void timerInfo( const UniSetTypes::TimerMessage *tm ) override; 00221 virtual void askSensors( UniversalIO::UIOCommand cmd ); 00222 virtual void initOutput(); 00223 virtual void sigterm( int signo ) override; 00224 virtual bool activateObject() override; 00225 virtual void initIterators(); 00226 00227 struct InitRegInfo 00228 { 00229 InitRegInfo(): 00230 dev(0),mbreg(0), 00231 mbfunc(ModbusRTU::fnUnknown), 00232 initOK(false),ri(0) 00233 {} 00234 RSProperty p; 00235 RTUDevice* dev; 00236 ModbusRTU::ModbusData mbreg; 00237 ModbusRTU::SlaveFunctionCode mbfunc; 00238 bool initOK; 00239 RegInfo* ri; 00240 }; 00241 typedef std::list<InitRegInfo> InitList; 00242 00243 void firstInitRegisters(); 00244 bool preInitRead( InitList::iterator& p ); 00245 bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p ); 00246 bool allInitOK; 00247 00248 RTUDeviceMap rmap; 00249 InitList initRegList; 00250 UniSetTypes::uniset_rwmutex pollMutex; 00251 00252 virtual std::shared_ptr<ModbusClient> initMB( bool reopen=false )= 0; 00253 00254 virtual void poll(); 00255 bool pollRTU( RTUDevice* dev, RegMap::iterator& it ); 00256 00257 void updateSM(); 00258 void updateRTU(RegMap::iterator& it); 00259 void updateMTR(RegMap::iterator& it); 00260 void updateRTU188(RegMap::iterator& it); 00261 void updateRSProperty( RSProperty* p, bool write_only=false ); 00262 virtual void updateRespondSensors(); 00263 00264 bool checkUpdateSM( bool wrFunc, long devMode ); 00265 bool checkPoll( bool wrFunc ); 00266 00267 bool checkProcActive(); 00268 void setProcActive( bool st ); 00269 void waitSMReady(); 00270 00271 void readConfiguration(); 00272 bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec ); 00273 bool initItem( UniXML::iterator& it ); 00274 void initDeviceList(); 00275 void initOffsetList(); 00276 00277 RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML::iterator& it ); 00278 RegInfo* addReg( RegMap& rmap, RegID id, ModbusRTU::ModbusData r, UniXML::iterator& it, RTUDevice* dev ); 00279 RSProperty* addProp( PList& plist, RSProperty&& p ); 00280 00281 bool initMTRitem( UniXML::iterator& it, RegInfo* p ); 00282 bool initRTU188item( UniXML::iterator& it, RegInfo* p ); 00283 bool initRSProperty( RSProperty& p, UniXML::iterator& it ); 00284 bool initRegInfo( RegInfo* r, UniXML::iterator& it, RTUDevice* dev ); 00285 bool initRTUDevice( RTUDevice* d, UniXML::iterator& it ); 00286 virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML::iterator& it ); 00287 00288 void rtuQueryOptimization( RTUDeviceMap& m ); 00289 00290 xmlNode* cnode; 00291 std::string s_field; 00292 std::string s_fvalue; 00293 00294 SMInterface* shm; 00295 00296 bool initPause; 00297 UniSetTypes::uniset_rwmutex mutex_start; 00298 00299 bool force; 00300 bool force_out; 00301 bool mbregFromID; 00302 int polltime; 00303 timeout_t sleepPause_usec; 00304 00305 PassiveTimer ptHeartBeat; 00306 UniSetTypes::ObjectId sidHeartBeat; 00307 int maxHeartBeat; 00308 IOController::IOStateList::iterator itHeartBeat; 00309 UniSetTypes::ObjectId test_id; 00310 00311 UniSetTypes::ObjectId sidExchangeMode; 00312 IOController::IOStateList::iterator itExchangeMode; 00313 long exchangeMode; 00315 std::atomic_bool activated; 00316 int activateTimeout; 00317 bool noQueryOptimization; 00318 bool no_extimer; 00319 00320 std::string prefix; 00321 00322 timeout_t stat_time; 00323 int poll_count; 00324 PassiveTimer ptStatistic; 00326 std::string prop_prefix; 00328 std::shared_ptr<ModbusClient> mb; 00329 00330 // определение timeout для соединения 00331 PassiveTimer ptTimeout; 00332 bool pollActivated; 00333 int recv_timeout; 00334 00335 int aftersend_pause; 00336 00337 PassiveTimer ptReopen; 00338 Trigger trReopen; 00339 00340 // т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список 00341 // и отдельно его проверяем потом 00342 typedef std::list<IOBase> ThresholdList; 00343 ThresholdList thrlist; 00344 00345 private: 00346 MBExchange(); 00347 00348 }; 00349 // ----------------------------------------------------------------------------- 00350 #endif // _MBExchange_H_ 00351 // -----------------------------------------------------------------------------
1.7.6.1