|
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 "DelayTimer.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 RegInfo* reg; 00082 }; 00083 00084 friend std::ostream& operator<<( std::ostream& os, const RSProperty& p ); 00085 00086 typedef std::list<RSProperty> PList; 00087 static std::ostream& print_plist( std::ostream& os, PList& p ); 00088 00089 typedef unsigned long RegID; 00090 00091 typedef std::map<RegID,RegInfo*> RegMap; 00092 struct RegInfo 00093 { 00094 RegInfo(): 00095 mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown), 00096 id(0),dev(0), 00097 rtuJack(RTUStorage::nUnknown),rtuChan(0), 00098 mtrType(MTR::mtUnknown), 00099 q_num(0),q_count(1),mb_initOK(false),sm_initOK(false) 00100 {} 00101 00102 ModbusRTU::ModbusData mbval; 00103 ModbusRTU::ModbusData mbreg; 00104 ModbusRTU::SlaveFunctionCode mbfunc; 00105 PList slst; 00106 RegID id; 00107 00108 RTUDevice* dev; 00109 00110 // only for RTU188 00111 RTUStorage::RTUJack rtuJack; 00112 int rtuChan; 00113 00114 // only for MTR 00115 MTR::MTRType mtrType; 00117 // optimization 00118 int q_num; 00119 int q_count; 00121 RegMap::iterator rit; 00122 00123 // начальная инициалиазция для "записываемых" регистров 00124 // Механизм: 00125 // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства. 00126 // при этом флаг mb_init=false пока не пройдёт успешной инициализации 00127 // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true. 00128 bool mb_initOK; 00130 // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров" 00131 // ещё не инициализировано из SM 00132 bool sm_initOK; 00133 }; 00134 00135 friend std::ostream& operator<<( std::ostream& os, RegInfo& r ); 00136 friend std::ostream& operator<<( std::ostream& os, RegInfo* r ); 00137 00138 struct RTUDevice 00139 { 00140 RTUDevice(): 00141 respnond(false), 00142 mbaddr(0), 00143 dtype(dtUnknown), 00144 resp_id(UniSetTypes::DefaultObjectId), 00145 resp_state(false), 00146 resp_invert(false), 00147 numreply(0), 00148 prev_numreply(0), 00149 ask_every_reg(false), 00150 mode_id(UniSetTypes::DefaultObjectId), 00151 mode(emNone), 00152 speed(ComPort::ComSpeed38400), 00153 rtu(0) 00154 { 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 DelayTimer resp_Delay; 00166 PassiveTimer resp_ptInit; 00167 bool resp_state; 00168 bool resp_invert; 00169 ost::AtomicCounter numreply; 00170 ost::AtomicCounter prev_numreply; 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 virtual void initValues(); 00213 00214 struct InitRegInfo 00215 { 00216 InitRegInfo(): 00217 dev(0),mbreg(0), 00218 mbfunc(ModbusRTU::fnUnknown), 00219 initOK(false),ri(0) 00220 {} 00221 RSProperty p; 00222 RTUDevice* dev; 00223 ModbusRTU::ModbusData mbreg; 00224 ModbusRTU::SlaveFunctionCode mbfunc; 00225 bool initOK; 00226 RegInfo* ri; 00227 }; 00228 typedef std::list<InitRegInfo> InitList; 00229 00230 void firstInitRegisters(); 00231 bool preInitRead( InitList::iterator& p ); 00232 bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p ); 00233 bool allInitOK; 00234 00235 RTUDeviceMap rmap; 00236 InitList initRegList; 00237 UniSetTypes::uniset_mutex pollMutex; 00238 00239 virtual ModbusClient* initMB( bool reopen=false )= 0; 00240 00241 virtual void poll(); 00242 bool pollRTU( RTUDevice* dev, RegMap::iterator& it ); 00243 00244 void updateSM(); 00245 void updateRTU(RegMap::iterator& it); 00246 void updateMTR(RegMap::iterator& it); 00247 void updateRTU188(RegMap::iterator& it); 00248 void updateRSProperty( RSProperty* p, bool write_only=false ); 00249 virtual void updateRespondSensors(); 00250 00251 bool checkUpdateSM( bool wrFunc, long devMode ); 00252 bool checkPoll( bool wrFunc ); 00253 00254 bool checkProcActive(); 00255 void setProcActive( bool st ); 00256 void waitSMReady(); 00257 00258 void readConfiguration(); 00259 bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec ); 00260 bool initItem( UniXML_iterator& it ); 00261 void initDeviceList(); 00262 void initOffsetList(); 00263 00264 RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML_iterator& it ); 00265 RegInfo* addReg( RegMap& rmap, RegID id, ModbusRTU::ModbusData r, UniXML_iterator& it, 00266 RTUDevice* dev, RegInfo* rcopy=0 ); 00267 RSProperty* addProp( PList& plist, RSProperty& p ); 00268 00269 bool initMTRitem( UniXML_iterator& it, RegInfo* p ); 00270 bool initRTU188item( UniXML_iterator& it, RegInfo* p ); 00271 bool initRSProperty( RSProperty& p, UniXML_iterator& it ); 00272 bool initRegInfo( RegInfo* r, UniXML_iterator& it, RTUDevice* dev ); 00273 bool initRTUDevice( RTUDevice* d, UniXML_iterator& it ); 00274 virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it ); 00275 00276 void rtuQueryOptimization( RTUDeviceMap& m ); 00277 00278 xmlNode* cnode; 00279 std::string s_field; 00280 std::string s_fvalue; 00281 00282 SMInterface* shm; 00283 00284 bool initPause; 00285 UniSetTypes::uniset_mutex mutex_start; 00286 00287 bool force; 00288 bool force_out; 00289 bool mbregFromID; 00290 int polltime; 00291 timeout_t sleepPause_usec; 00292 00293 PassiveTimer ptHeartBeat; 00294 UniSetTypes::ObjectId sidHeartBeat; 00295 int maxHeartBeat; 00296 IOController::AIOStateList::iterator aitHeartBeat; 00297 UniSetTypes::ObjectId test_id; 00298 00299 UniSetTypes::ObjectId sidExchangeMode; 00300 IOController::AIOStateList::iterator aitExchangeMode; 00301 long exchangeMode; 00303 UniSetTypes::uniset_mutex actMutex; 00304 bool activated; 00305 int activateTimeout; 00306 bool noQueryOptimization; 00307 bool no_extimer; 00308 00309 std::string prefix; 00310 00311 timeout_t stat_time; 00312 int poll_count; 00313 PassiveTimer ptStatistic; 00315 std::string prop_prefix; 00317 ModbusClient* mb; 00318 00319 // определение timeout для соединения 00320 PassiveTimer ptTimeout; 00321 bool pollActivated; 00322 int recv_timeout; 00323 00324 int aftersend_pause; 00325 00326 PassiveTimer ptReopen; 00327 Trigger trReopen; 00328 00329 // т.к. пороговые датчики не связаны напрямую с обменом, создаём для них отдельный список 00330 // и отдельно его проверяем потом 00331 typedef std::list<IOBase> ThresholdList; 00332 ThresholdList thrlist; 00333 00334 bool defaultMBinitOK; // флаг определяющий нужно ли ждать "первого обмена" или при запуске сохранять в SM значение default 00335 00336 private: 00337 MBExchange(); 00338 00339 }; 00340 // ----------------------------------------------------------------------------- 00341 #endif // _MBExchange_H_ 00342 // -----------------------------------------------------------------------------
1.7.6.1