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
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
00110 RTUStorage::RTUJack rtuJack;
00111 int rtuChan;
00112
00113
00114 MTR::MTRType mtrType;
00116
00117 int q_num;
00118 int q_count;
00120 RegMap::iterator rit;
00121
00122
00123
00124
00125
00126
00127 bool mb_initOK;
00129
00130
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;
00175
00176
00177 bool checkRespond();
00178
00179
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
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