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