Files
caClientLessons/caLesson6/caClientWrapperC/epicsPV.h
T

179 lines
6.5 KiB
C

#ifndef epicsPV_h
#define epicsPV_h
#include <cadef.h>
#include <caerr.h>
#include <alarm.h>
/* How epicsPVs work:
* A PV is a container for a remote named value provided via a so
* called EPICS "channel". It is "linked" to the channel in PVcreate()
* or later with PVlink().
* Because the original value is remote, the PV can only contain
* a copy of the value.
* With the caget() call, one or more PVs are updated from the remote value.
* After that, the updated value can be read as long, double or string.
* With the caput() call, the remote value is updated from the PV.
*/
#ifndef PV_DEFAULT_GET_TIMEOUT_SEC
#define PV_DEFAULT_GET_TIMEOUT_SEC 2.0
#endif
#ifndef PV_DEFAULT_PUT_TIMEOUT_SEC
#define PV_DEFAULT_PUT_TIMEOUT_SEC 10.0
#endif
typedef struct epicsPV_s* epicsPV;
typedef void (*PVconnectionCallback) (epicsPV pv, int connectionUp, void* userarg);
/* Channel Access datatypes (plus caTypeNative as default value)
* depending on the datatype of a PV, exporting the value
* to double, long or const char* may give different results
*/
typedef enum {
caTypeString,
caTypeShort,
caTypeFloat,
caTypeEnum,
caTypeChar,
caTypeLong,
caTypeDouble,
caTypeNoAccess,
caTypeNative
} caDatatype;
/* You don't need to access anything in epicsPV_priv.h directly
*/
#include "epicsPV_priv.h"
/* create PV and optionally link it to an EPICS channel
* normally, you call createPV with channelName but without
* preferredDatatype to use the native datatype of the channel
* you may read back datatype after connection
* if channelName is NULL you must call PVlink later
* a callback can be installed to track connection state changes
* connectionUp is 1 when the PV connected, 0 when it disconnected
* userarg is an arbitrary pointer that will be provided with the callback
*/
#define PVcreate(channelName) PVcreateWithTypeAndCallback(channelName, caTypeNative, NULL, NULL)
#define PVcreateWithType(channelName, type) PVcreateWithTypeAndCallback(channelName, type, NULL, NULL)
#define PVcreateWithCallback(channelName, cb, userarg) PVcreateWithTypeAndCallback(name, caTypeNative, cb, userarg)
epicsPV PVcreateWithTypeAndCallback(const char* channelName, caDatatype preferredDatatype,
PVconnectionCallback cb, void* userarg);
/* destroy PV and free all resources
*/
void PVdestroy(epicsPV pv);
/* explititely (re-)link PV to a (different) EPICS channel
* an unlink PV from a channel
* it is normally done implicitely by PVcreate and PVdestroy
* note: linking does not yet send a search request to the
* network until PVwaitForConnect is called (probably implicitely by caget, caput, camonitor)
*/
#define linkPV(pv, channelName)linkPVwithType(pv, channelName, caTypeNative)
int PVlinkWithType(epicsPV pv, const char* channelName, caDatatype preferredDatatype);
void PVunlink(epicsPV pv);
/* wait until one or all PVs are connected
* timeoutSec = 0.0 just sends connect requests but does not wait
* timeoutSec < 0.0 means wait forever
* returns remaining seconds
* calling this function is optional because it will be called
* implicitely before the first get or put on an unconnected PV
* using the get or put timeout
*/
double PVwaitForConnect(epicsPV pv, double timeoutSec);
#define PVwaitForConnectAll(timeoutSec) PVwaitForConnect(NULL, timeoutSec)
/* return channel name (what you provided to PVlink or PVcreate)
*/
#define PVname(pv) ((pv)->channel?ca_name((pv)->channel):"")
/* return error status of PV
* see $(EPICS_BASE)/include/caerr.h for error codes
*/
#define PVerrorStatus(pv) ((pv)->status)
#define PVerrorStatusString(pv) (ca_message((pv)->status))
/* return connection state
* see $(EPICS_BASE)/include/cadef.h for valid values
*/
#define PVconnectionState(pv) ((pv)->channel?ca_state((pv)->channel):cs_never_conn)
#define PVconnectionStateString(pv) PVconnectionStateStrings[PVconnectionState(pv)]
/* The following functions return information which is available
* as soon as the PV is connected.
*/
/* return currently used data type
*/
#define PVdatatype(pv) ((pv)->usedDatatype)
#define PVdatatypeString(pv) PVdataTypeStrings[PVdatatype(pv)]
/* return number of elements for array data
*/
#define PVnumberOfElements(pv) ((pv)->channel?ca_element_count((pv)->channel):0)
/* return units and precision (.EGU and .PREC fields)
* if PV does not have units or precision it returns "" and/or 0
*/
#define PVunits(pv) ((pv)->units)
#define PVprecision(pv) ((pv)->precision)
/* return access rights (might change at run-time)
*/
#define PVhasReadAccess(pv) ((pv)->channel?ca_read_access((pv)->channel):0)
#define PVhasWriteAccess(pv) ((pv)->channel?ca_write_access((pv)->channel):0)
/* get value from remote server
* do caget with as many PVs as possible in parallel to increase performance
*/
#define caget(pvs...) cagetList(PV_DEFAULT_GET_TIMEOUT_SEC, pvs, NULL)
#define cagetWithTimeout(timeoutSec, pvs...) cagetList(timeoutSec, pvs, NULL)
/* The following functions return information which is available
* after a successful get() or a monitor.
*/
/* return alarm severity and status (.SEVR and .STAT fields)
* see $(EPICS_BASE)/include/alarm.h for valid values
* not conencted PV returns epicsSevInvalid/epicsAlarmNone
*/
#define PValarmSeverity(pv) ((pv)->STRING?(pv)->STRING->severity:epicsSevInvalid)
#define PValarmSeverityString(pv) epicsAlarmSeverityStrings[PValarmSeverity(pv)]
#define PValarmStatus(pv) ((pv)->STRING?(pv)->STRING->status:epicsAlarmUDF)
#define PValarmStatusString(pv) epicsAlarmConditionStrings[PValarmStatus(pv)]
/* return time of record processing (.TIME field) as (epicsTimeStamp*)
* see $(EPICS_BASE)/include/epicsTime.h for epicsTimeStamp
*/
extern epicsTimeStamp PVinvalidTimestamp;
#define PVtimestamp(pv) &((pv)->STRING?(pv)->STRING->stamp:PVinvalidTimestamp)
/* return value of pv as long double or string
* for arrays use PVto*Element to access each element
*/
long PVtoLongElement(epicsPV pv, unsigned long index);
#define PVtoLong(pv) PVtoLongElement(pv,0)
double PVtoDoubleElement(epicsPV pv, unsigned long index);
#define PVtoDouble(pv) PVtoDoubleElement(pv,0)
/* flags for toString() */
const char* PVtoStringElement(epicsPV pv, int flags, unsigned long index);
#define PVtoStringWithUnits(pv) PVtoStringElement(pv,PV_WITHUNITS,0)
#define PVtoString(pv) PVtoStringElement(pv,0,0)
#define caputDouble(pv1, value1...) caputDoubleList(0.0, pv1, value1)
#define caputWaitDouble(timeoutSec, pv1, val1, ...) caputDoubleList(timeoutSec, pv1, value1)
int caputDoubleList(double timeoutSec, int flags, epicsPV pv1, double val1, ...);
#define caputLong(pv1, val1, ...)
#define caputString(pv1, val1, ...)
#endif