About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
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 output mapping.
00026  *
00027  * An output 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 AttributeSignalOutput : public AttributeVoid {
00034 
00035 FAUDES_TYPE_DECLARATION(Void,AttributeSignalOutput,AttributeVoid)
00036 
00037 public:
00038 
00039   /** Default constructor (no triggers) */
00040   AttributeSignalOutput(void) : AttributeVoid() {};
00041 
00042   /** Copy - constructor */
00043   AttributeSignalOutput(const AttributeSignalOutput& 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 output action */
00053   typedef struct {
00054     int  mBit;         //// Bitaddress (numeric)
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 void DoAssign(const AttributeSignalOutput& rSrcAttr);
00072 
00073   /**
00074    * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
00075    *
00076    * If the current token indicates an output 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    * output for output 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 output mapping data. The label argument is ignored, we use
00097    * the hardcoded section "Output". 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 AttributeSignalOutput
00112 
00113 
00114 
00115 
00116 
00117 
00118 /**
00119  * Configuration of a signal based input mapping.
00120  *
00121  * A input 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 AttributeSignalInput : public AttributeVoid {
00128 
00129 FAUDES_TYPE_DECLARATION(Void,AttributeSignalInput,AttributeVoid)
00130 
00131 public:
00132 
00133   /** Default constructor (no triggers) */
00134   AttributeSignalInput(void) : AttributeVoid() {};
00135 
00136   /** Copy constructor */
00137   AttributeSignalInput (const AttributeSignalInput& 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 input 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 void DoAssign(const AttributeSignalInput& rSrcAttr);
00167 
00168   /**
00169    * Reads the attribute from TokenReader, see AttributeVoid for public wrappers.
00170    *
00171    * If the current token indicates a input 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 "Input" for input 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 input mapping data.The label argument is ignored, we use the
00193    * hardcoded section "Input". 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 AttributeSignalInput
00209 
00210 
00211 
00212 
00213 /**
00214  * Configuration of a signal based input or output
00215  *
00216  * This class is derived from the AttributeDeviceEvent to specialise
00217  * for signal based input and output mapping.
00218  *
00219  */
00220 
00221 class AttributeSignalEvent : public AttributeDeviceEvent {
00222 
00223 FAUDES_TYPE_DECLARATION(Void,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 output mapping */
00240   const AttributeSignalOutput*  Outputp(void) const {
00241     return static_cast<AttributeSignalOutput*>(mpOutputAttribute); };
00242 
00243   /**  Get input mapping */
00244   const AttributeSignalInput*  Inputp(void) const {
00245     return static_cast<AttributeSignalInput*>(mpInputAttribute); };
00246 
00247  protected:
00248 
00249   /** DoAssign */
00250   virtual void DoAssign(const AttributeSignalEvent& rSrc)  
00251   { AttributeDeviceEvent::DoAssign(rSrc);};
00252 
00253   /** Prototype, input (construct on first use static) */
00254   static const AttributeSignalInput* InputPrototypep(void);
00255 
00256   /** Prototype, output (construct on first use static) */
00257   static const AttributeSignalOutput* OutputPrototypep(void);
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 AttributeSignalInput or a AttributeSignalOutput. Thus,
00268  * we set and clear output signals for output events, while edges on input
00269  * signals trigger input 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 inputs
00323    */
00324   int MaxBitAddress(void) const { return mMaxBitAddress;};
00325 
00326 
00327   /**
00328    * Activate the device. This function enables output execution and input reading.
00329    * It starts the background thread for edge detection and input 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 output execution and input reading.
00338    * It stops the backhround thread and resets all output 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 output command.
00348    *
00349    * @exception Exception
00350    *   - unknown output event (id 65)
00351    */
00352   virtual void WriteOutput(Idx output);
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 input map: map signal edges to logical event sets */
00410   std::map<int, EventSet> mInputPosEdgeIndexMap;
00411 
00412   /** Reverse input map: map signal edges to logical event sets */
00413   std::map<int, EventSet> mInputNegEdgeIndexMap;
00414 
00415   /** Address range */
00416   int mMaxBitAddress;
00417 
00418   /**  
00419    * Writes non-event-related configuration to TokenWriter
00420    *
00421    * Device data will be written bottom-to-top along the class-hierarchy,
00422    * see also vDevice::DoWritePreface.
00423    *
00424    * Note: in order to keep the outputfile-layout as simple as possible no label will 
00425    * be used to separate this data-section. 
00426    *
00427    * @param rTw
00428    *   TokenWriter to write
00429    * @param rLabel
00430    *   Section to write
00431    * @param pContext
00432    *   Context to provide contextual information
00433    *
00434    * */
00435   void DoWritePreface(TokenWriter& rTw, const std::string& rLabel,  const Type* pContext=0) const;
00436 
00437   /**  Reads non-event-related configuration from TokenReader
00438    *
00439    * Device date is read bottom-to-top along the class-hierarchy; 
00440    * see also vDevice::DoReadPreface.
00441    *
00442    *
00443    * Note: in order to keep the inputfile-layout as simple as possible no label will 
00444    * be used to separate this data-section. 
00445    *
00446    * @param rTr
00447    *   TokenReader to read from
00448    * @param rLabel
00449    *   Section to read
00450    * @param pContext
00451    *   Read context to provide contextual information
00452    *
00453    * */
00454   virtual void DoReadPreface(TokenReader& rTr,const std::string& rLabel="", const Type* pContext=0);
00455 
00456   /**
00457    * IO Hook, inputs
00458    *
00459    * The background thread calls this hook before reading input signals.
00460    * You may reimplement this method to e.g. prepare a process image.
00461    *
00462    * @return 
00463    *  True on success, false on error
00464    *
00465    */
00466   virtual bool DoReadSignalsPre(void) {return true;};
00467 
00468   /**
00469    * IO Hook, inputs
00470    *
00471    * The background thread calls this hook after reading input signals.
00472    * You may reimplement this method to e.g. release a process image.
00473    *
00474    *
00475    */
00476   virtual void DoReadSignalsPost(void) {};
00477 
00478   /**
00479    * Sample input signal.
00480    *
00481    * Reimplement this function to implements actual harware access to sample an input signal. 
00482    * This function gets
00483    * called from the periodic background thread to sense edges. 
00484    * It is guaranteed that the pre-hook was called befor and returned "true".
00485    * The post-hook will be invoked after relevant signals have been sampled.
00486    *
00487    * @param bitaddr
00488    *   Abstract bit address
00489    * @return
00490    *  True for logic level high;
00491    */
00492   virtual bool DoReadSignal(int bitaddr)=0;
00493 
00494   /**
00495    * IO Hook, outputs
00496    *
00497    * This hook is invoked before writing a signal value.
00498    * You may reimplement this method to e.g. assemble a process image.
00499    *
00500    * @return 
00501    *  True on success, false on error
00502    *
00503    */
00504   virtual bool DoWriteSignalsPre(void) {return true;};
00505 
00506   /**
00507    * IO Hook, output
00508    *
00509    * This hook is invoked after writing a signal value.
00510    * You may reimplement this method to e.g. assemble a process image.
00511    *
00512    *
00513    */
00514   virtual void DoWriteSignalsPost(void) {};
00515 
00516   /**
00517    * Reimplement this function in a derived class for actual harware access
00518    * to set or clear an output signal. Hooks are executed appropriately.
00519    * If the device is configured for synchronous write, the background task
00520    * is used to write signals. Otherwise, signal values are written instantly.
00521    *
00522    * @param bitaddr
00523    *   Abstract bit address
00524    * @param value
00525    *   True for active/high/1/set;
00526    *   false for passive/low/0/clr;
00527    *
00528    */
00529   virtual void DoWriteSignal(int bitaddr, bool value)=0;
00530 
00531 
00532   /** Background: mutex for below shared variables*/
00533   pthread_mutex_t mMutex;
00534 
00535 
00536  private:
00537 
00538   /** Background: thread handle (global) */
00539   pthread_t mThreadSynchro;
00540 
00541   /** Cycle time of background thread in nsecs (shared) */
00542   int mCycleTime;
00543 
00544   /** True for synchronous output writes (shared) */
00545   bool mSyncWrite;
00546 
00547   /** Background: cycle counter (shared) */
00548   int mCycleCount;
00549 
00550   /** Background: cycle count  (global only) */
00551   int mRecentCycleCount;
00552 
00553   /** Background: type def for edge detection  */
00554   typedef struct {
00555     bool current;  //// current value (most recent reading)
00556     bool past;     //// past value (reading before)
00557     bool posrel;   //// positive edge is relevant for some input event
00558     bool negrel;   //// negative edge is relevant for some input event
00559     bool pos;      //// positive edge detected
00560     bool neg;      //// negative edge detected
00561     bool lost;     //// relevant edge has been lost
00562   } Edges;
00563 
00564   /** Background: accumulated edges (shared)   */
00565   Edges* mpInputEdges;
00566 
00567   /** Background: recently accumulated edges (global only)   */
00568   Edges* mpRecentInputEdges;
00569 
00570   /** Background: some input event did occur (shared) */
00571   bool mInputReady;
00572 
00573   /** Background: type def output values  */
00574   typedef struct {
00575     bool current;  //// current value (most recent reading)
00576     bool next;     //// past   value (reading before)
00577     bool edge;     //// value  will change
00578     bool lost;     //// toggle has  been lost
00579   } Levels;
00580 
00581   /** Background: accumulated output values (shared) */
00582   Levels* mpOutputLevels;
00583 
00584   /** Background: terminate-flag for endless-loop   */
00585   bool mCancelRequest;
00586 
00587   /** clear all input states */
00588   void ClrInputSignals(void);
00589 
00590   /** clear all output values */
00591   void ClrOutputSignals(void);
00592 
00593 }; 
00594 
00595 // declare background thread
00596 void* SDeviceSynchro(void*);
00597 
00598 }
00599 
00600 
00601 #endif
00602 

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen