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