iop_modbus.h

Go to the documentation of this file.
00001 /** @file iop_modbus.h Process image via modbus/tcp */
00002 
00003 /*
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2011, Thomas Moor.
00007 
00008 */
00009 
00010 
00011 
00012 #ifndef FAUDES_IOP_MODBUS_H
00013 #define FAUDES_IOP_MODBUS_H
00014 
00015 
00016 // Include core-libary and iodevice
00017 #include "corefaudes.h"
00018 #include "iop_vdevice.h"
00019 #include "iop_sdevice.h"
00020 #include "iop_simplenet.h"
00021 
00022 
00023 // If configured to have a modbus device 
00024 #ifdef FAUDES_IODEVICE_MODBUS
00025 
00026  
00027 
00028 namespace faudes {
00029 
00030 
00031 
00032 /**
00033  * Processimage synchronisation via Modbus/TCP
00034  *
00035  * This device is derived from the signal based sDevice to
00036  * read and write line levels via ethernet using the Modbus/TCP
00037  * protocol; see also the <a href="http://www.modbus.org">Modbus Organization</a>.  
00038  * When configured as master, the mbDevice
00039  * initiates commucation with a specified list of slaves in order
00040  * to retrieve input line levels and to set output line levels. The latter are
00041  * locally buffered and are propagated to the event-based interface
00042  * inherited via the base class sDevice. 
00043  * When configured as slave, the mbDevice accepts connections from any Modbus
00044  * master, will response to their request sand update the local line-level buffer accordingly.
00045  *
00046  * Further dedatils on the configuration, incl. an example, are provided
00047  * by the <a href="../reference/simulator_devices.html#ModbusDevice">ModbusDevice user-reference</a>
00048  *
00049  * Technical details.
00050  * - The mbDevice slave implements reading and writing bits/coils/registers/holding registers,
00051  *   incl. the multi-read/write variants; regardless which commads you use, they all refer
00052  *   to the one process image implicitly defined by the event configuration.
00053  * - The mbDevice matser usees the commands read multiple bits and write multiple coils
00054  *   for process image synchonisation.
00055  * - All network communication come with quite relaxed timeouts. Please let us know, if
00056  *   you require more strict timeout behaviour.  
00057  * - Network communication is currently implemented synchronous with the edge detection
00058  *   background task; this is restrictive and may be changed in future revisions.
00059  * - Communication uses an additional line-level buffer; a better solution would be
00060  *   to share the line buffer with the sDevice; however, this is not supported by the  current 
00061  *   sDevice interface.
00062  * - Programatic configuration is still incomplete.
00063  * - The mbDevice compiles with MinGW/Windows, however, it was not properly tested
00064  *   in this configuration; please let us know, if you plan to use mbDevice in a
00065  *   Windows context.
00066  *
00067  * Note: This device must be explicitely enabled in Makefile.plugin.
00068  * 
00069  * @ingroup  IODevicePlugin
00070  */
00071 
00072 class mbDevice : public sDevice {
00073 
00074 FAUDES_TYPE_DECLARATION(ModbusDevice,mbDevice,mbDevice)
00075 
00076  public:
00077 
00078   /**
00079    * Default constructor
00080    */
00081   mbDevice(void);
00082 
00083   /**
00084    * Copy constructor (not implemented!)
00085    */
00086   mbDevice(const mbDevice&) : sDevice() {};
00087 
00088   /**
00089    * Explicit destructor.
00090    */
00091   virtual ~mbDevice(void);
00092 
00093 
00094   /**
00095    * Clear all configuration (implies Stop)
00096    */
00097   virtual void Clear(void);
00098 
00099 
00100   /**
00101    * 
00102    * Compile to internal data-structures.
00103    * 
00104    * Exception in misconfiguration/inconsistencies
00105    *
00106    */
00107   virtual void Compile(void);
00108 
00109 
00110   /**
00111    * Append remotely implemented outputs.
00112    * You must
00113    * (re-)compile the mbDevice after adding remote outputs.
00114    *
00115    * @param mbid
00116    *    Remote device id
00117    * @param mbaddr
00118    *    bitaddress within the remote device
00119    * @param count
00120    *    number of output bits to bw written
00121    * @param fdaddr 
00122    *    address within local process image
00123    */
00124    void AppendRemoteOutputs(int mbid, int mbaddr, int cnt, int fdaddr);
00125 
00126 
00127   /**
00128    * Append remotely implemented inputs.
00129    * You must
00130    * (re-)compile the mbDevice after adding remote inputs.
00131    *
00132    * @param mbid
00133    *    Remote device id
00134    * @param mbaddr
00135    *    bitaddress within the remote device
00136    * @param count
00137    *    number of input bits to bw read
00138    * @param fdaddr 
00139    *    address within local process image
00140    */
00141    void AppendRemoteInputs(int mbid, int mbaddr, int cnt, int fdaddr);
00142 
00143   /**
00144    * Set server address of this node.
00145    * Note: you can only set th server address while the
00146    * device is down.
00147    *
00148    * @param rAddr 
00149    *   IP address of the remote Modbus device, e.g. "localhost:1502"
00150    * @exception Exception
00151    *   - No valid address (id 551) (NOT IMPLEMENTED)
00152    */
00153   void SlaveAddress(const std::string& rAddr);
00154 
00155 
00156   /**
00157    * Activate the device. 
00158    * This function opens/initializes a network connection and
00159    * starts the -background thread for communication and edge detection.
00160    *
00161    * @exception Exception
00162    *   - not yet configured (id not configured)
00163    *   - failed to network connection (id not configured)
00164    */
00165   virtual void Start(void);
00166 
00167 
00168   /**
00169    * Deactivate the device. This function shuts down the network,
00170    * stops the background thread and sets all output signals to 0.
00171    */
00172   virtual void Stop(void);
00173 
00174 
00175 protected:
00176    
00177 
00178   /**
00179    * IO Hook, inputs
00180    *
00181    * @return 
00182    *  True on success.
00183    *
00184    */
00185   virtual bool DoReadSignalsPre(void);
00186 
00187   /**
00188    * IO Hook, inputs
00189    */
00190   virtual void DoReadSignalsPost(void);
00191 
00192   /**
00193    * Get input signal.
00194    *
00195    * Extract bit value from image.
00196    *
00197    * @param bitaddr
00198    *   Abstract bit address
00199    * @return
00200    *  True for logic level high;
00201    */
00202   virtual bool DoReadSignal(int bitaddr);
00203   
00204   /**
00205    * IO Hook, outputs
00206    *
00207    * @return 
00208    *  True on success
00209    *
00210    */
00211   virtual bool DoWriteSignalsPre(void);
00212 
00213   /**
00214    * IO Hook, outputs
00215    *
00216    */
00217   virtual void DoWriteSignalsPost(void);
00218 
00219   /**
00220    * Set output signal.
00221    *
00222    * Set value of bit in process image.
00223    *
00224    * @param bitaddr
00225    *   Abstract bit address
00226    * @param value
00227    *   True for logic level high;
00228    *
00229    */
00230   virtual void DoWriteSignal(int bitaddr, bool value);
00231 
00232 
00233   /**
00234    * Loop hook.
00235    *
00236    * This function is called once during each cycle of the
00237    * backgroud thread. It implements the actual communication via Modbus/TCP.
00238    *
00239    */
00240   virtual void DoLoopCallback(void);
00241 
00242   /** 
00243    * Read non-event-related configuration data from tokenreader
00244    *
00245    * @param rTr
00246    *   TokenReader to read from
00247    * @param rLabel
00248    *   Section to read
00249    * @param pContext
00250    *   Read context to provide contextual information
00251    *
00252    */
00253   void DoReadPreface(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
00254 
00255   /**  
00256    * Write non-event-related configuration data to tokenreader
00257    *
00258    * @param rTw
00259    *   TokenWriter to write
00260    * @param rLabel
00261    *   Section to write
00262    * @param pContext
00263    *   Context to provide contextual information
00264    * 
00265    */
00266   void DoWritePreface(TokenWriter& rTw, const std::string& rLabel,  const Type* pContext) const ;
00267 
00268 
00269   /** Role: master/slave */
00270   bool mMasterRole;
00271 
00272   /** IP addresses */
00273   SimplenetAddress mSlaveAddress;
00274 
00275   /** Modbus address ranges */
00276   typedef struct {
00277     bool mInputs;
00278     int mMbId;
00279     int mMbAddress;
00280     int mFdAddress;
00281     int mCount;
00282   } IoRange;
00283   std::vector< IoRange > mSlaveIoRanges;    
00284 
00285   /** Remote process image buffer */
00286   int mImageSize;
00287   char* mpImage;
00288   char* pInputImage;
00289   char* pOutputImage;
00290   char* mpOutputMask;
00291 
00292   /** Background thread: tcp connection to remote slave */
00293   int mSlaveSocket;
00294   int mRequestCount;
00295   char* mMessage;
00296   int   mMessageLen;
00297   int   mRequestId;
00298 
00299   /** Background thread: tcp connection to remote masters */
00300   std::vector<int> mMasterSockets;
00301 
00302   /** I/O helper */
00303   int  MbFlushBuffers(void);
00304   int  MbSendRequest(int id);
00305   int  MbReceiveResponse(void);
00306   int  MbReceiveRequest(int mastersock);
00307   int  MbSendResponse(int mastersock);
00308 
00309 
00310 }; //class spiDevice
00311 
00312 } //namespace 
00313 
00314 
00315 #endif // configured
00316 
00317 #endif // include

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen