libFAUDES

Sections

Index

iop_sdevice.h

Go to the documentation of this file.
00001 /** @file iop_sdevice.h Virtual device for signal based io  */
00002 
00003 /*
00004   FAU Discrete Event Systems Library (libfaudes)
00005 
00006   Copyright (C) 2008, Thomas Moor
00007   Exclusive copyright is granted to Klaus Schmidt
00008 
00009 */
00010 
00011 
00012 
00013 #ifndef FAUDES_SDEVICE_H
00014 #define FAUDES_SDEVICE_H
00015 
00016 #include "corefaudes.h"
00017 #include "iop_vdevice.h"
00018 
00019 
00020 
00021 namespace faudes {
00022 
00023 
00024 /**
00025  * Configuration of a signal based actuator mapping.
00026  *
00027  * An actuator mapping consists of a list of actions that to be performed when the
00028  * event is executed. Each action may set or clear the physical output line
00029  * specified by an abstract bitaddress.
00030  *
00031  */
00032 
00033 class AttributeSignalActuator : public AttributeVoid {
00034 
00035 FAUDES_TYPE_DECLARATION(AttributeSignalActuator,AttributeVoid)
00036 
00037 public:
00038 
00039   /** Default constructor (no triggers) */
00040   AttributeSignalActuator(void) : AttributeVoid() {};
00041 
00042   /** Copy - constructor */
00043   AttributeSignalActuator(const AttributeSignalActuator& rOtherAttr) : AttributeVoid() 
00044       { DoAssign(rOtherAttr); };
00045 
00046   /** Test for default value (never) */
00047   virtual bool IsDefault(void) const {return false;};
00048 
00049   /** Clear */
00050   virtual void Clear(void) {mActions.clear();};
00051 
00052   /** Typedef for a single actuator action */
00053   typedef struct {
00054     int  mBit;         //// Bitaddress
00055     bool mValue;       //// Value to set (true<>1, false <>0)
00056   } Action;
00057 
00058   /** List of actions to perform */
00059   std::vector<Action> mActions;
00060 
00061  protected:
00062 
00063   /**
00064    * Copy method
00065    *
00066    * @param rSrcAttr
00067    *   Source to copy from
00068    * @return
00069    *   Ref to this attribute
00070    */
00071   virtual AttributeSignalActuator& DoAssign(const AttributeSignalActuator& rSrcAttr);
00072 
00073   /**
00074    * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
00075    *
00076    * If the current token indicates an actuator mapping, the method reads that
00077    * section. Else it does nothing. Exceptions may only be thrown
00078    * on invalid data within the section. The label argument is ignored, we the hardcoded
00079    * actuator for actuator device attributes. The context argument is ignored.
00080    *
00081    * @param rTr
00082    *   TokenReader to read from
00083    * @param rLabel
00084    *   Section to read
00085    * @param pContext
00086    *   Read context to provide contextual information
00087    *
00088    * @exception Exception
00089    *   - IO error (id 1)
00090    */
00091   virtual void DoRead(TokenReader& rTr,const std::string& rLabel="", const Type*  pContext=0);
00092 
00093   /**
00094    * Writes the attribute to TokenWriter, see AttributeVoid for public wrappers.
00095    *
00096    * Writes the actuator mapping data.The label argument is ignored, we use
00097    * the hardcoded section "Actuator". The context argument is ignored.
00098    *
00099    * @param rTw
00100    *   TokenWriter to write to
00101    * @param rLabel
00102    *   Section to write
00103    * @param pContext
00104    *   Read context to provide contextual information
00105    *
00106    * @exception Exception
00107    *   - IO error (id 2)
00108    */
00109   virtual void DoWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
00110 
00111 }; // end class AttributeSignalActuator
00112 
00113 
00114 
00115 
00116 
00117 
00118 /**
00119  * Configuration of a signal based sensor mapping.
00120  *
00121  * A sensor mapping consists of a list of abstract bitaddresses with an
00122  * edge polarity each. When on one of respecive physical input lines an edge
00123  * with matching priority is sensed, the logical event is triggered.
00124  *
00125  */
00126 
00127 class AttributeSignalSensor : public AttributeVoid {
00128 
00129 FAUDES_TYPE_DECLARATION(AttributeSignalSensor,AttributeVoid)
00130 
00131 public:
00132 
00133   /** Default constructor (no triggers) */
00134   AttributeSignalSensor(void) : AttributeVoid() {};
00135 
00136   /** Copy constructor */
00137   AttributeSignalSensor (const AttributeSignalSensor& rOtherAttr) : AttributeVoid() 
00138       { DoAssign(rOtherAttr); };
00139 
00140   /** Test for default value (never) */
00141   virtual bool IsDefault(void) const {return false;};
00142 
00143   /** Clear */
00144   virtual void Clear(void) {mTriggers.clear();};
00145 
00146   /** Typedef for a single sensor trigger */
00147   typedef struct {
00148     int mBit;          //// Bitaddress
00149     bool  mPos;        //// Positive edge triggers event
00150     bool  mNeg;        //// Negative edge triggers event
00151   } Trigger;
00152 
00153   /** List of triggers */
00154   std::vector<Trigger> mTriggers;
00155 
00156  protected:
00157 
00158   /**
00159    * Copy method
00160    *
00161    * @param rSrcAttr
00162    *   Source to copy from
00163    * @return
00164    *   Ref to this attribute
00165    */
00166   virtual AttributeSignalSensor& DoAssign(const AttributeSignalSensor& rSrcAttr);
00167 
00168   /**
00169    * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
00170    *
00171    * If the current token indicates a sensor mapping, the method reads that
00172    * section. Else it does nothing. Exceptions may only be thrown
00173    * on invalid data within the section. The label argument is ignored, we use the
00174    * hardcoded section "Sensor" for sensor attributes. The context argument is ignored.
00175    *
00176    * @param rTr
00177    *   TokenReader to read from
00178    * @param rLabel
00179    *   Section to read
00180    * @param pContext
00181    *   Read context to provide contextual information
00182    *
00183    * @exception Exception
00184    *   - IO error (id 1)
00185    */
00186   virtual void DoRead(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
00187 
00188 
00189   /**
00190    * Writes the attribute to TokenWriter, see AttributeVoid for public wrappers.
00191    *
00192    * Writes the sensor mapping data.The label argument is ignored, we use the
00193    * hardcoded section "Sensor". The context argument is ignored.
00194    *
00195    * @param rTw
00196    *   TokenWriter to write to
00197    * @param rLabel
00198    *   Section to write
00199    * @param pContext
00200    *   Read context to provide contextual information
00201    *
00202    * @exception Exception
00203    *   - IO error (id 2)
00204    */
00205 
00206   virtual void DoWrite(TokenWriter& rTw,const std::string& rLabel="", const Type* pContext=0) const;
00207 
00208 }; // end class AttributeSignalSensor
00209 
00210 
00211 
00212 
00213 /**
00214  * Configuration of a signal based sensor or actuator
00215  *
00216  * This class is derived from the AttributeDeviceEvent to specialise
00217  * for signal based sensor and actuator mapping.
00218  *
00219  */
00220 
00221 class AttributeSignalEvent : public AttributeDeviceEvent {
00222 
00223 FAUDES_TYPE_DECLARATION(AttributeSignalEvent,AttributeDeviceEvent)
00224 
00225  public:
00226 
00227   /** Default constructor (no mapping at all) */
00228   AttributeSignalEvent(void);
00229 
00230   /** Copy constructor */
00231   AttributeSignalEvent(const AttributeSignalEvent& rOtherAttr); 
00232 
00233   /** Test for default value (never) */
00234   virtual bool IsDefault(void) const {return false;};
00235 
00236   /** Clear */
00237   virtual void Clear(void)  { AttributeDeviceEvent::Clear(); };
00238 
00239   /**  Get actuator mapping */
00240   const AttributeSignalActuator*  Actuatorp(void) const {
00241     return static_cast<AttributeSignalActuator*>(mpActuatorAttribute); };
00242 
00243   /**  Get sensor mapping */
00244   const AttributeSignalSensor*  Sensorp(void) const {
00245     return static_cast<AttributeSignalSensor*>(mpSensorAttribute); };
00246 
00247  protected:
00248 
00249   /** DoAssign */
00250   virtual AttributeSignalEvent& DoAssign(const AttributeSignalEvent& rSrc)  
00251   { AttributeDeviceEvent::DoAssign(rSrc); return *this;};
00252 
00253   /** Prototype, sensor */
00254   static AttributeSignalSensor sSensorPrototype;
00255 
00256   /** Prototype, actuator */
00257   static AttributeSignalActuator sActuatorPrototype;
00258 
00259 }; // class AttributeSignalEvent
00260 
00261 
00262 
00263 /**
00264  * An sDevice implements signal based semantics for faudes events.
00265  *
00266  * The class is configured by AttributeSignalEvents, which in turn consist of
00267  * either a AttributeSignalSensor or a AttributeSignalActuator. Thus,
00268  * we set and clear output signals for actuator events, while edges on input
00269  * signals trigger sensor events.
00270  *
00271  * Sensing edges is done by separate thread that is started by Start().
00272  *
00273  * This class is still virtual in that it does not provide the code for actually
00274  * reading or writing signals. See cDevice and pDevice for derived device classes
00275  * that implement digital io via comedi or the parallel printer port, respectively.
00276  *
00277  * @ingroup IODevicePlugin
00278  */
00279 
00280 class sDevice : public vDevice {
00281 
00282   // provide all access to background task
00283   friend void* SDeviceSynchro(void*);
00284 
00285  public:
00286 
00287 
00288   /**
00289    * Default constructor
00290    */
00291   sDevice(void);
00292 
00293   /**
00294    * copy-constructor
00295    */
00296   sDevice(const sDevice& rOtherDevice);
00297 
00298   /**
00299    * Explicit destructor.
00300    */
00301   virtual ~sDevice(void);
00302 
00303 
00304 
00305   /**
00306    * Clear all configuration.
00307    * This implies Stop().
00308    */
00309   virtual void Clear(void);
00310 
00311   /**
00312    * 
00313    * Build up internal data-structure(e.g. signal-event - mapping)
00314    *
00315    */
00316   virtual void Compile(void);
00317 
00318   /**
00319    * Report max bit address.
00320    *
00321    * @return
00322    *   Set of all configured sensors
00323    */
00324   int MaxBitAddress(void) const { return mMaxBitAddress;};
00325 
00326 
00327   /**
00328    * Activate the device. This function enables actuator execution and sensor reading.
00329    * It starts the background thread for edge detection and sensor event buffer.
00330    *
00331    * @exception Exception
00332    *   - Not yet configured (id 551)
00333    */
00334   virtual void Start(void);
00335 
00336   /**
00337    * Deactivate the device. This function disables actuator execution and sensor reading.
00338    * It stops the backhround thread and resets all actuator signals to 0.
00339    */
00340   virtual void Stop(void);
00341 
00342   /** Clear dynamic data and restart device */
00343   virtual void Reset(void);
00344 
00345 
00346   /**
00347    * Run actuator command.
00348    *
00349    * @exception Exception
00350    *   - unknown actuator event (id 65)
00351    */
00352   virtual void WriteActuator(Idx actuator);
00353 
00354 
00355 
00356   /**
00357    * Set output signal.
00358    *
00359    *
00360    * This function provides user level access to output signals. It executes the virtual pre and post hook methods 
00361    * and the likewise virtual actual harware access to set the signal level via DoWriteSignal(int,bool). 
00362    *
00363    * @param bitaddr
00364    *   Abstract bit address
00365    * @param value
00366    *   True for active/high/1/set;
00367    *   false for passive/low/0/clr;
00368    *
00369    */
00370    void WriteSignal(int bitaddr, bool value);
00371 
00372   /**
00373    * Get input signal.
00374    *
00375    * This function provides user level access to input signals. It executes the virtual pre and post hook methods 
00376    * and the likewise virtual actual harware access to sample an input signal via DoReadSignal(int). 
00377    *
00378    * @param bitaddr
00379    *   Abstract bit address
00380    * @return
00381    *  True for logic level high;
00382    */
00383    bool ReadSignal(int bitaddr);
00384 
00385 
00386   /**
00387    * Report cycle time
00388    *
00389    * @return
00390    *   Actual cycle time in ms
00391    */
00392 
00393   virtual int CycleTime() const;
00394 
00395   /**
00396    * Set cycle time
00397    *
00398    * @param cycleTime
00399    *   Desired cycle time in ms
00400    */
00401 
00402   virtual void CycleTime(int cycleTime);
00403 
00404  protected:
00405 
00406   /** Overall configuration (with actual type) */
00407   TaNameSet<AttributeSignalEvent>* pConfiguration ;
00408 
00409   /** Reverse sensor map: map signal edges to logical event sets */
00410   std::map<int, EventSet> mSensorPosEdgeIndexMap;
00411 
00412   /** Reverse sensor map: map signal edges to logical event sets */
00413   std::map<int, EventSet> mSensorNegEdgeIndexMap;
00414 
00415   /** Address range */
00416   int mMaxBitAddress;
00417 
00418   /**  Writes non-event-configuration to TokenWriter
00419    *
00420    * This function is part of the non-event-configuration data output-system. Device data
00421    * will be written w.r.t the class-hierarchy. Therefore first thing to do is to the base
00422    * class. See vDevice::DoWritePreface for further information.
00423    *
00424    * After base-class function returned the mMaxBitAdress and mCycleTime will be written to tokenwriter.
00425    *
00426    * Note: in order to keep the outputfile-layout as easy as possible no label will be used to separate
00427    *       this data-section. Never the less a default-label ("SignalDevice") is specified.
00428    *
00429    * @param rTw
00430    *   TokenWriter to write
00431    * @param rLabel
00432    *   Section to write
00433    * @param pContext
00434    *   Context to provide contextual information
00435    *
00436    * */
00437   void DoWritePreface(TokenWriter& rTw, const std::string& rLabel,  const Type* pContext=0) const;
00438 
00439   /**  Reads non-event-configuration data from TokenReader
00440    *
00441    * This function is part of the non-event-configuration data input-system. Device data
00442    * will be read w.r.t the class-hierarchy. Therefore first thing to do is to call the base
00443    * class. See vDevice::DoReadPreface for further information.
00444    *
00445    * After base-class returned the mMaxBitAddress and mCycleTime will be read.
00446    * The max. bit-address depends on the IO-card used while the cycle-time should be chosen depending on
00447    * the physical plant to control.
00448    *
00449    * Note: in order to keep the inputfile-layout as easy as possible no label will be used to separate
00450    *     this data-section. Never the less a default-label ("SignalDevice") is specified.
00451    *
00452    * @param rTr
00453    *   TokenReader to read from
00454    * @param rLabel
00455    *   Section to read
00456    * @param pContext
00457    *   Read context to provide contextual information
00458    *
00459    * */
00460   virtual void DoReadPreface(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
00461 
00462   /**
00463    * IO Hook, sensors
00464    *
00465    * The background thread calls this hook before reading sensor signals.
00466    * You may reimplement this method to e.g. prepare a process image.
00467    *
00468    * @return 
00469    *  True on success, false on error
00470    *
00471    */
00472   virtual bool DoReadSignalsPre(void) {return true;};
00473 
00474   /**
00475    * IO Hook, sensors
00476    *
00477    * The background thread calls this hook after reading sensor signals.
00478    * You may reimplement this method to e.g. release a process image.
00479    *
00480    *
00481    */
00482   virtual void DoReadSignalsPost(void) {};
00483 
00484   /**
00485    * Sample input signal.
00486    *
00487    * Reimplement this function to implements actual harware access to sample an input signal. This function gets
00488    * called from the periodic background thread to sense edges. It is guaranteed that the pre and post
00489    * hook is executed before/afterwards.
00490    *
00491    * @param bitaddr
00492    *   Abstract bit address
00493    * @return
00494    *  True for logic level high;
00495    */
00496   virtual bool DoReadSignal(int bitaddr)=0;
00497 
00498   /**
00499    * IO Hook, actuators
00500    *
00501    * The background thread calls this hook before reading sensor signals.
00502    * You may reimplement this method to e.g. prepare a process image.
00503    *
00504    * @return 
00505    *  True on success, false on error
00506    *
00507    */
00508   virtual bool DoWriteSignalsPre(void) {return true;};
00509 
00510   /**
00511    * IO Hook, actuator
00512    *
00513    * The background thread calls this hook after reading sensor signals.
00514    * You may reimplement this method to e.g. release a process image.
00515    *
00516    *
00517    */
00518   virtual void DoWriteSignalsPost(void) {};
00519 
00520   /**
00521    * Reimplement this function in a derived class for actual harware access
00522    * to set or clear an output signal. Hooks are executoed appropriately.
00523    *
00524    * @param bitaddr
00525    *   Abstract bit address
00526    * @param value
00527    *   True for active/high/1/set;
00528    *   false for passive/low/0/clr;
00529    *
00530    */
00531   virtual void DoWriteSignal(int bitaddr, bool value)=0;
00532 
00533 
00534 
00535  private:
00536 
00537   /** Background: mutex for below shared variables*/
00538   pthread_mutex_t mMutex;
00539 
00540   /** Background: thread handle (global) */
00541   pthread_t mThreadSynchro;
00542 
00543   /** Cycle time of background thread in usecs (shared) */
00544   int mCycleTime;
00545 
00546   /** Background: cycle counter (shared) */
00547   int mCycleCount;
00548 
00549   /** Background: cycle counte (global only) */
00550   int mRecentCycleCount;
00551 
00552   /** Background: type def for edge detection  */
00553   typedef struct {
00554     bool current;  //// current value (most recent reading)
00555     bool past;     //// past value (reading before)
00556     bool posrel;   //// positive edge is relevant for some sensor event
00557     bool negrel;   //// negative edge is relevant for some sensor event
00558     bool pos;      //// positive edge detected
00559     bool neg;      //// negative edge detected
00560     bool lost;     //// relevant edge has been lost
00561   } Edges;
00562 
00563   /** Background: accumulated edges (shared)   */
00564   Edges* mpSensorEdges;
00565 
00566   /** Background: recently accumulated edges (global only)   */
00567   Edges* mpRecentSensorEdges;
00568 
00569   /** Background: some sensor event did occur (shared) */
00570   bool mSensorReady;
00571 
00572   /** Background: terminate-flag for endless-loop   */
00573   bool mCancelRequest;
00574 
00575   /** clear all sensor states */
00576   void ClrSensorSignals(void);
00577 
00578   /** clear all actuator values */
00579   void ClrActuatorSignals(void);
00580 
00581 }; 
00582 
00583 // declare background thread
00584 void* SDeviceSynchro(void*);
00585 
00586 }
00587 
00588 
00589 #endif
00590 

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6