UniSet  1.4.0
ModbusMaster/MBExchange.h
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             // only for RTU
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 //              rtuJack(RTUStorage::nUnknown),rtuChan(0),
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             // only for RTU188
00109             RTUStorage::RTUJack rtuJack;
00110             int rtuChan;
00111 
00112             // only for MTR
00113             MTR::MTRType mtrType;   
00115             // optimization
00116             int q_num;      
00117             int q_count;    
00119             RegMap::iterator rit;
00120 
00121             // начальная инициалиазция для "записываемых" регистров
00122             // Механизм:
00123             // Если tcp_preinit="1", то сперва будет сделано чтение значения из устройства.
00124             // при этом флаг mb_init=false пока не пройдёт успешной инициализации
00125             // Если tcp_preinit="0", то флаг mb_init сразу выставляется в true.
00126             bool mb_initOK; 
00128             // Флаг sm_init означает, что писать в устройство нельзя, т.к. значение в "карте регистров"
00129             // ещё не инициализировано из SM
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             // return TRUE if state changed
00171             bool checkRespond();
00172 
00173             // специфические поля для RS
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         // определение timeout для соединения
00313         PassiveTimer ptTimeout;
00314         bool pollActivated;
00315         int recv_timeout;
00316 
00317      private:
00318         MBExchange();
00319 
00320 };
00321 // -----------------------------------------------------------------------------
00322 #endif // _MBExchange_H_
00323 // -----------------------------------------------------------------------------