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
00135 struct RTUDevice
00136 {
00137 RTUDevice():
00138 respnond(false),
00139 mbaddr(0),
00140 dtype(dtUnknown),
00141 resp_id(UniSetTypes::DefaultObjectId),
00142 resp_state(false),
00143 resp_invert(false),
00144 resp_real(false),
00145 resp_init(false),
00146 ask_every_reg(false),
00147 speed(ComPort::ComSpeed38400),
00148 rtu(0)
00149 {
00150 resp_trTimeout.change(false);
00151 }
00152
00153 bool respnond;
00154 ModbusRTU::ModbusAddr mbaddr;
00155 RegMap regmap;
00156
00157 DeviceType dtype;
00159 UniSetTypes::ObjectId resp_id;
00160 IOController::DIOStateList::iterator resp_dit;
00161 PassiveTimer resp_ptTimeout;
00162 Trigger resp_trTimeout;
00163 bool resp_state;
00164 bool resp_invert;
00165 bool resp_real;
00166 bool resp_init;
00167 bool ask_every_reg;
00168
00169
00170 bool checkRespond();
00171
00172
00173 ComPort::Speed speed;
00174 RTUStorage* rtu;
00175 };
00176
00177 friend std::ostream& operator<<( std::ostream& os, RTUDevice& d );
00178
00179 typedef std::map<ModbusRTU::ModbusAddr,RTUDevice*> RTUDeviceMap;
00180
00181 friend std::ostream& operator<<( std::ostream& os, RTUDeviceMap& d );
00182 void printMap(RTUDeviceMap& d);
00183
00184
00185 static RegID genRegID( const ModbusRTU::ModbusData r, const int fn );
00186
00187 enum Timer
00188 {
00189 tmExchange
00190 };
00191
00192 void execute();
00193
00194 protected:
00195 virtual void step();
00196 virtual void processingMessage( UniSetTypes::VoidMessage *msg );
00197 virtual void sysCommand( UniSetTypes::SystemMessage *msg );
00198 virtual void sensorInfo( UniSetTypes::SensorMessage*sm );
00199 virtual void timerInfo( UniSetTypes::TimerMessage *tm );
00200 virtual void askSensors( UniversalIO::UIOCommand cmd );
00201 virtual void initOutput();
00202 virtual void sigterm( int signo );
00203 virtual bool activateObject();
00204 virtual void initIterators();
00205
00206 struct InitRegInfo
00207 {
00208 InitRegInfo():
00209 dev(0),mbreg(0),
00210 mbfunc(ModbusRTU::fnUnknown),
00211 initOK(false),ri(0)
00212 {}
00213 RSProperty p;
00214 RTUDevice* dev;
00215 ModbusRTU::ModbusData mbreg;
00216 ModbusRTU::SlaveFunctionCode mbfunc;
00217 bool initOK;
00218 RegInfo* ri;
00219 };
00220 typedef std::list<InitRegInfo> InitList;
00221
00222 void firstInitRegisters();
00223 bool preInitRead( InitList::iterator& p );
00224 bool initSMValue( ModbusRTU::ModbusData* data, int count, RSProperty* p );
00225 bool allInitOK;
00226
00227 RTUDeviceMap rmap;
00228 InitList initRegList;
00229 UniSetTypes::uniset_mutex pollMutex;
00230
00231 virtual ModbusClient* initMB( bool reopen=false )= 0;
00232
00233 virtual void poll();
00234 bool pollRTU( RTUDevice* dev, RegMap::iterator& it );
00235
00236 void updateSM();
00237 void updateRTU(RegMap::iterator& it);
00238 void updateMTR(RegMap::iterator& it);
00239 void updateRTU188(RegMap::iterator& it);
00240 void updateRSProperty( RSProperty* p, bool write_only=false );
00241 virtual void updateRespondSensors();
00242
00243 bool checkUpdateSM( bool wrFunc );
00244 bool checkPoll( bool wrFunc );
00245
00246 bool checkProcActive();
00247 void setProcActive( bool st );
00248 void waitSMReady();
00249
00250 void readConfiguration();
00251 bool readItem( UniXML& xml, UniXML_iterator& it, xmlNode* sec );
00252 bool initItem( UniXML_iterator& it );
00253 void initDeviceList();
00254 void initOffsetList();
00255
00256 RTUDevice* addDev( RTUDeviceMap& dmap, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
00257 RegInfo* addReg( RegMap& rmap, RegID id, ModbusRTU::ModbusData r, UniXML_iterator& it,
00258 RTUDevice* dev, RegInfo* rcopy=0 );
00259 RSProperty* addProp( PList& plist, RSProperty& p );
00260
00261 bool initMTRitem( UniXML_iterator& it, RegInfo* p );
00262 bool initRTU188item( UniXML_iterator& it, RegInfo* p );
00263 bool initRSProperty( RSProperty& p, UniXML_iterator& it );
00264 bool initRegInfo( RegInfo* r, UniXML_iterator& it, RTUDevice* dev );
00265 bool initRTUDevice( RTUDevice* d, UniXML_iterator& it );
00266 virtual bool initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniXML_iterator& it );
00267
00268 void rtuQueryOptimization( RTUDeviceMap& m );
00269
00270 xmlNode* cnode;
00271 std::string s_field;
00272 std::string s_fvalue;
00273
00274 SMInterface* shm;
00275
00276 bool initPause;
00277 UniSetTypes::uniset_mutex mutex_start;
00278
00279 bool force;
00280 bool force_out;
00281 bool mbregFromID;
00282 int polltime;
00283 timeout_t sleepPause_usec;
00284
00285 PassiveTimer ptHeartBeat;
00286 UniSetTypes::ObjectId sidHeartBeat;
00287 int maxHeartBeat;
00288 IOController::AIOStateList::iterator aitHeartBeat;
00289 UniSetTypes::ObjectId test_id;
00290
00291 UniSetTypes::ObjectId sidExchangeMode;
00292 IOController::AIOStateList::iterator aitExchangeMode;
00293 long exchangeMode;
00295 UniSetTypes::uniset_mutex actMutex;
00296 bool activated;
00297 int activateTimeout;
00298 bool noQueryOptimization;
00299 bool no_extimer;
00300
00301 std::string prefix;
00302
00303 timeout_t stat_time;
00304 int poll_count;
00305 PassiveTimer ptStatistic;
00307 std::string prop_prefix;
00309 ModbusClient* mb;
00310
00311
00312 PassiveTimer ptTimeout;
00313 bool pollActivated;
00314 int recv_timeout;
00315
00316 private:
00317 MBExchange();
00318
00319 };
00320
00321 #endif // _MBExchange_H_
00322