/* * ProfilerPVs.hh * * Class to interface the PVs defined in the SNL code with the * C++ code used to implement the state sequence. The PVs are * expected to be defined in the SNL code in terms of short, * unsigned and double arrays, and them the structure with pointers * to this arrays is passed to this class. A member of pvStruct is * assigned to this structure, and then is used access the PVs defined * in SNL. This allows not do any CA operations and use facilities * of SNL to deal with CA. Since the same array is going to be accessed * from multiple instances of state sequences with different SSID, * mutexes are implemented to avoid conflicts between different threads * that these state sequences are running. * * Created on: Aug 19, 2015 * Author: Hovanes Egiyan */ #ifndef __PROFILERPVS_HH__ #define __PROFILERPVS_HH__ #include "seqCom.h" #include #include #include #include #include #include #include #include #include #include #include "MtxLock.hh" #include "MutexedClass.hh" #include "ProfilerMap.h" class ProfilerPVs : public MutexedClass { public: // An auxiliary class to interface with the structure with pointers to the PV arrays. // It inherits from pvStructure so that the data layout is the same as the one used in // the SNL code using pvStructure C-structure. class pvStruct : public pvStructure { public: pvStruct() {return;} pvStruct( unsigned offs, unsigned n, unsigned sf, unsigned uf, unsigned df,unsigned wf, short* s, unsigned* u, double* d, long* w ) { offset=offs; nElm=n; shortFlag=sf; unsignedFlag=uf, doubleFlag=df, waveFlag=wf; shortPtr=s; unsignedPtr=u, doublePtr=d; wavePtr=w; } pvStruct( const pvStruct& pv ) { offset=pv.offset; nElm=pv.nElm; shortFlag=pv.shortFlag; unsignedFlag=pv.unsignedFlag; doubleFlag=pv.doubleFlag; waveFlag=pv.waveFlag; shortPtr=pv.shortPtr; unsignedPtr=pv.unsignedPtr; doublePtr=pv.doublePtr; wavePtr=pv.wavePtr;} pvStruct& operator=( const pvStruct& pv ) { offset=pv.offset; nElm=pv.nElm; shortFlag=pv.shortFlag; unsignedFlag=pv.unsignedFlag; doubleFlag=pv.doubleFlag; waveFlag=pv.waveFlag; shortPtr=pv.shortPtr; unsignedPtr=pv.unsignedPtr; doublePtr=pv.doublePtr; wavePtr=pv.wavePtr; return *this; } inline unsigned getOffset() const {return offset;} inline unsigned getNElm() const {return nElm;} inline unsigned getShortFlag() const {return shortFlag;} inline unsigned getUnsignedFlag() const {return unsignedFlag;} inline unsigned getDoubleFlag() const {return doubleFlag;} inline unsigned getWaveFlag() const {return waveFlag;} inline short* getShortPtr() const{return shortPtr;} inline unsigned* getUnsignedPtr() const{return unsignedPtr;} inline double* getDoublePtr() const{return doublePtr;} inline long* getWavePtr() const {return wavePtr;} inline unsigned setOffset(unsigned offs ) { return (offset=offs);} inline unsigned setNElm( unsigned n ) { return (nElm=n);} inline unsigned setShortFlag(unsigned f) {return (shortFlag=f);} inline unsigned setDoubleFlag(unsigned f) {return (doubleFlag=f);} inline unsigned setUnsignedFlag(unsigned f) {return (unsignedFlag=f);} inline unsigned setWaveFlag(unsigned f) {return (waveFlag=f);} inline short* setShortPtr( short* ptr ) {return (shortPtr=ptr);} inline unsigned* setDoublePtr( unsigned* ptr ) {return (unsignedPtr=ptr);} inline double* setDoublePtr( double* ptr ) {return (doublePtr=ptr);} inline long* setWavePtr( long* ptr ) {return (wavePtr=ptr);} }; protected: SS_ID ppSSid; // SNL state sequence Id pvStruct ppArrays; // Arrays with info about SNL PVs unsigned ppCurrentIndex; // Current indexes for PVs std::map ppCurrentTypeIndex; // Current index for arrays of type given by the string key std::map ppTypeIndex; // Index in the array for a given string key std::map ppIndex; // Index for a PV with a given string key std::map ppName; // PV name for a PV with a given string key std::map ppType; // PV var type for a PV with a given string key std::map ppInputFlag; // Flag showing if this is an input PV std::map ppEventID; // Map of event flags for each key. const static unsigned ppNFIFO; // FIFO length static unsigned ppMaxConnectChecks; // Max tries assign/connect checks static unsigned ppMaxReadbackChecks; // Max tries for readback during readback checks static unsigned ppSleepTime; // Sleep time during readback checks static double ppReadbackTolerance; // Tolerance for readback during readback checks public: // Default constructor ProfilerPVs() : MutexedClass(), ppSSid(), ppArrays(), ppCurrentIndex(0), ppCurrentTypeIndex(), ppTypeIndex(), ppIndex(), ppName(), ppType(), ppInputFlag() {ppCurrentTypeIndex["short"]=ppCurrentTypeIndex["unsigned"]=ppCurrentTypeIndex["double"]=ppCurrentTypeIndex["wave"]=0;} // Main constructor ProfilerPVs( SS_ID ssID, pvStruct& pvs ) : MutexedClass(), ppSSid(ssID), ppArrays(pvs), ppCurrentIndex(0), ppCurrentTypeIndex(), ppTypeIndex(), ppIndex(), ppName(), ppType(), ppInputFlag() {initMutex();ppCurrentTypeIndex["short"]=ppCurrentTypeIndex["unsigned"]=ppCurrentTypeIndex["double"]=ppCurrentTypeIndex["wave"]=0;} // Copy constructor ProfilerPVs( const ProfilerPVs& pv ) : MutexedClass(pv), ppSSid(pv.ppSSid),ppArrays(pv.ppArrays), ppCurrentIndex(pv.ppCurrentIndex), ppCurrentTypeIndex(pv.ppCurrentTypeIndex), ppTypeIndex(pv.ppTypeIndex), ppIndex(pv.ppIndex), ppName(pv.ppName), ppType(pv.ppType), ppInputFlag(pv.ppInputFlag) {return;} // Assignment operator ProfilerPVs& operator=( const ProfilerPVs& pv ) { MutexedClass::operator =(pv); MtxLock objLock(mcMutex); ppSSid = pv.ppSSid; ppArrays = pv.ppArrays; ppCurrentIndex=pv.ppCurrentIndex; ppCurrentTypeIndex=pv.ppCurrentTypeIndex; ppTypeIndex=pv.ppTypeIndex; ppIndex=pv.ppIndex; ppName=pv.ppName; ppType=pv.ppType; ppInputFlag=pv.ppInputFlag; return *this; } virtual ~ProfilerPVs() {closeMutex();} virtual inline SS_ID getSSID() const { return ppSSid;} virtual inline pvStruct& getArrays() { MtxLock objLock(mcMutex); return ppArrays; } virtual inline unsigned getCurrentIndex() const {return ppCurrentIndex; } // Get the number of trials for readback checks inline static unsigned getMaxReadbackChecks() {return ppMaxReadbackChecks; } // Get the sleep time between readback checks inline static unsigned getSleepTime() {return ppSleepTime; } // Get the readback check tolerance inline static double getReadbackTolerance() {return ppReadbackTolerance;} // Get FIFO depth for this set of PVs inline static unsigned getNFIFO() { return ppNFIFO; } // Return state sequence ID virtual inline SS_ID setSSID(SS_ID id) {MtxLock objLock(mcMutex); return (ppSSid=id);} // Check if the input PVs have changed template bool inputsChanged(); // Set the number of trials for readback checks inline static unsigned setMaxReadbackChecks(unsigned n) {return (ppMaxReadbackChecks=n); } // Set the sleep time between readback checks inline static unsigned setSleepTime(unsigned n) {return (ppSleepTime=n); } // Set the readback check tolerance inline static double setReadbackTolerance(double tolr) {return (ppReadbackTolerance=tolr);} // Return the PV array pointer for type T (T can be short, unsigned and double) template T* getPtr4Type(T fakePar); // Get the values of the PVs with a give label "label" defined for different parameter types. // The type is picked based on fakePar type. template T getPV( const std::string label, enum compType syncType, T fakePar ); // Method to get array values of type T into the vector vec starting at itBegin to itEnd void getPV( const std::string label, enum compType syncType, std::vector& vec ); // Set the values of the PVs template T setValue( std::string pvKey, const T value, enum compType syncType = SYNC ); bool pvCheckEvtFlag( const std::string pvLabel ); void pvClearEvtFlag( const std::string pvLabel ); void pvSetEvtFlag( const std::string pvLabel ); bool pvCheckAndClearEvtFlag( const std::string pvLabel ); // Method that waits until the setpoint for short and readback are the same within tolerance template bool gotReadback( const T setValue, const std::string readChannel, double tolerance = ppReadbackTolerance ); // Add a PV of type pvType with label (key) pvKey that will be assigned to PV called pvName virtual void addPV( const std::string pvType, const std::string pvKey, const std::string pvName ); // Connect all the PVs defined so far virtual void assignPVs(); }; #endif /* __PROFILERPVS_HH__ */