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
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
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
00109 RTUStorage::RTUJack rtuJack;
00110 int rtuChan;
00111
00112
00113 MTR::MTRType mtrType;
00115
00116 int q_num;
00117 int q_count;
00119 RegMap::iterator rit;
00120
00121
00122
00123
00124
00125
00126 bool mb_initOK;
00128
00129
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
00171 bool checkRespond();
00172
00173
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
00313 PassiveTimer ptTimeout;
00314 bool pollActivated;
00315 int recv_timeout;
00316
00317 private:
00318 MBExchange();
00319
00320 };
00321
00322 #endif // _MBExchange_H_
00323