466 lines
18 KiB
C
466 lines
18 KiB
C
/*************************************************************************\
|
|
* Copyright (c) 2010 The UChicago Argonne LLC, as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2002 The Regents of the University of California, as
|
|
* Operator of Los Alamos National Laboratory.
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
/* dbLink.h
|
|
*
|
|
* Created on: Mar 21, 2010
|
|
* Author: Andrew Johnson
|
|
*/
|
|
|
|
#ifndef INC_dbLink_H
|
|
#define INC_dbLink_H
|
|
|
|
#include "link.h"
|
|
#include "dbCoreAPI.h"
|
|
#include "epicsTypes.h"
|
|
#include "epicsTime.h"
|
|
#include "dbAddr.h"
|
|
#include "dbChannel.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct dbLocker;
|
|
|
|
/** @file dbLink.h
|
|
* @brief Link Support API
|
|
*
|
|
* Link support run-time API, all link types provide an lset which is used by
|
|
* the IOC database to control and operate the link. This file also declares the
|
|
* dbLink routines that IOC, record and device code can call to perform link
|
|
* operations.
|
|
*/
|
|
|
|
/** @brief callback routine for locked link operations
|
|
*
|
|
* Called by the lset::doLocked method to permit multiple link operations
|
|
* while the link instance is locked.
|
|
*
|
|
* @param plink the link
|
|
* @param priv context for the callback routine
|
|
*/
|
|
typedef long (*dbLinkUserCallback)(struct link *plink, void *priv);
|
|
|
|
/** @brief Link Support Entry Table
|
|
*
|
|
* This structure provides information about and methods for an individual link
|
|
* type. A pointer to this structure is included in every link's lset field, and
|
|
* is used to perform operations on the link. For JSON links the pointer is
|
|
* obtained by calling pjlink->pif->get_lset() at link initialization time,
|
|
* immediately before calling dbLinkOpen() to activate the link.
|
|
*/
|
|
typedef struct lset {
|
|
/* Characteristics of the link type */
|
|
|
|
/** @brief link constancy
|
|
*
|
|
* 1 means this is a constant link type whose value doesn't change.
|
|
* The link's value will be obtained using one of the methods loadScalar,
|
|
* loadLS or loadArray.
|
|
*/
|
|
const unsigned isConstant:1;
|
|
|
|
/** @brief link volatility
|
|
*
|
|
* 0 means the link is always connected.
|
|
*/
|
|
const unsigned isVolatile:1;
|
|
|
|
/** @brief activate link
|
|
*
|
|
* Optional, called whenever a JSON link is initialized or added at runtime.
|
|
*
|
|
* @param plink the link
|
|
*/
|
|
void (*openLink)(struct link *plink);
|
|
|
|
/** @brief deactivate link
|
|
*
|
|
* Optional, called whenever a link address is changed at runtime, or the
|
|
* IOC is shutting down.
|
|
*
|
|
* @param locker
|
|
* @param plink the link
|
|
*/
|
|
void (*removeLink)(struct dbLocker *locker, struct link *plink);
|
|
|
|
/* Constant link initialization and data type hinting */
|
|
|
|
/** @brief load constant scalar from link type
|
|
*
|
|
* Usually called during IOC initialization, constant link types must copy a
|
|
* scalar value of the indicated data type to the buffer provided and return
|
|
* 0. A non-constant link type can use this method call as an early hint
|
|
* that subsequent calls to dbGetLink() will request scalar data of the
|
|
* indicated type, although the type might change.
|
|
*
|
|
* @param plink the link
|
|
* @param dbrType data type code
|
|
* @param pbuffer where to put the value
|
|
* @returns 0 if a value was loaded, non-zero otherwise
|
|
*/
|
|
long (*loadScalar)(struct link *plink, short dbrType, void *pbuffer);
|
|
|
|
/** @brief load constant long string from link type
|
|
*
|
|
* Usually called during IOC initialization, constant link types must copy a
|
|
* nil-terminated string up to size characters long to the buffer provided,
|
|
* and write the length of that string to the plen location. A non-constant
|
|
* link type can use this as an early hint that subsequent calls to
|
|
* dbGetLink() will request long string data, although this might change.
|
|
*
|
|
* @param plink the link
|
|
* @param pbuffer where to put the string
|
|
* @param size length of pbuffer in chars
|
|
* @param plen set to number of chars written
|
|
* @returns status value
|
|
*/
|
|
long (*loadLS)(struct link *plink, char *pbuffer, epicsUInt32 size,
|
|
epicsUInt32 *plen);
|
|
|
|
/** @brief load constant array from link type
|
|
*
|
|
* Usually called during IOC initialization, constant link types must copy
|
|
* an array value of the indicated data type to the buffer provided, update
|
|
* the pnRequest location to indicate how many elements were loaded, and
|
|
* return 0. A non-constant link type can use this method call as an early
|
|
* hint that subsequent calls to dbGetLink() will request array data of the
|
|
* indicated type and max size, although the request might change.
|
|
*
|
|
* @param plink the link
|
|
* @param dbrType data type code
|
|
* @param pbuffer where to put the value
|
|
* @param pnRequest Max elements on entry, actual on exit
|
|
* @returns 0 if elements were loaded, non-zero otherwise
|
|
*/
|
|
long (*loadArray)(struct link *plink, short dbrType, void *pbuffer,
|
|
long *pnRequest);
|
|
|
|
/* Metadata */
|
|
|
|
/** @brief return link connection status
|
|
*
|
|
* Return an indication whether this link is connected or not. This routine
|
|
* is polled by the calcout and some external record types. Not required for
|
|
* non-volatile link types, which are by definition always connected.
|
|
*
|
|
* @param plink the link
|
|
* @returns 1 if connected, 0 if disconnected
|
|
*/
|
|
int (*isConnected)(const struct link *plink);
|
|
|
|
/** @brief get data type of link destination
|
|
*
|
|
* Called on both input and output links by long string support code to
|
|
* decide whether to use DBR_CHAR/DBR_UCHAR or DBR_STRING for a subsequent
|
|
* dbPutLink() or dbGetLink() call. Optional, but if not provided long
|
|
* strings cannot be transported over this link type, and no warning or
|
|
* error will appear to explain why. Not required for constant link types.
|
|
*
|
|
* @param plink the link
|
|
* @returns DBF_* type code, or -1 on error/disconnected link
|
|
*/
|
|
int (*getDBFtype)(const struct link *plink);
|
|
|
|
/* Get data */
|
|
|
|
/** @brief get array size of an input link
|
|
*
|
|
* Called on input links by the compress record type for memory allocation
|
|
* purposes, before using the dbGetLink() routine to fetch the actual
|
|
* array data.
|
|
*
|
|
* @param plink the link
|
|
* @param pnElements where to put the answer
|
|
* @returns status value
|
|
*/
|
|
long (*getElements)(const struct link *plink, long *pnElements);
|
|
|
|
/** @brief get value from an input link
|
|
*
|
|
* Called to fetch data from the link, which must be converted into the
|
|
* given data type and placed in the buffer indicated. The actual number of
|
|
* elements retrieved should be updated in the pnRequest location. If this
|
|
* method returns an error status value, the link's record will be placed
|
|
* into an Invalid severity / Link Alarm state by the dbGetLink() routine
|
|
* that calls this method.
|
|
*
|
|
* @param plink the link
|
|
* @param dbrType data type code
|
|
* @param pbuffer where to put the value
|
|
* @param pnRequest max elements on entry, actual on exit
|
|
* @returns status value
|
|
*/
|
|
long (*getValue)(struct link *plink, short dbrType, void *pbuffer,
|
|
long *pnRequest);
|
|
|
|
/** @brief get the control range for an output link
|
|
*
|
|
* Called to fetch the control range for the link target, as a pair of
|
|
* double values for the lowest and highest values that the target will
|
|
* accept. This method is not used at all by the IOC or built-in record
|
|
* types, although external record types may require it.
|
|
*
|
|
* @param plink the link
|
|
* @param lo lowest accepted value
|
|
* @param hi highest accepted value
|
|
* @returns status value
|
|
*/
|
|
long (*getControlLimits)(const struct link *plink, double *lo, double *hi);
|
|
|
|
/** @brief get the display range from an input link
|
|
*
|
|
* Called to fetch the display range for an input link target, as a pair of
|
|
* double values for the lowest and highest values that the PV expects to
|
|
* return. This method is used by several built-in record types to obtain
|
|
* the display range for their generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param lo lowest accepted value
|
|
* @param hi highest accepted value
|
|
* @returns status value
|
|
*/
|
|
long (*getGraphicLimits)(const struct link *plink, double *lo, double *hi);
|
|
|
|
/** @brief get the alarm limits from an input link
|
|
*
|
|
* Called to fetch the alarm limits for an input link target, as four
|
|
* double values for the warning and alarm levels that the PV checks its
|
|
* value against. This method is used by several built-in record types to
|
|
* obtain the alarm limits for their generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param lolo low alarm value
|
|
* @param lo low warning value
|
|
* @param hi high warning value
|
|
* @param hihi high alarm value
|
|
* @returns status value
|
|
*/
|
|
long (*getAlarmLimits)(const struct link *plink, double *lolo, double *lo,
|
|
double *hi, double *hihi);
|
|
|
|
/** @brief get the precision from an input link
|
|
*
|
|
* Called to fetch the precision for an input link target. This method is
|
|
* used by several built-in record types to obtain the precision for their
|
|
* generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param precision where to put the answer
|
|
* @returns status value
|
|
*/
|
|
long (*getPrecision)(const struct link *plink, short *precision);
|
|
|
|
/** @brief get the units string from an input link
|
|
*
|
|
* Called to fetch the units string for an input link target. This method is
|
|
* used by several built-in record types to obtain the units string for
|
|
* their generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param units where to put the answer
|
|
* @param unitsSize buffer size for the answer
|
|
* @returns status value
|
|
*/
|
|
long (*getUnits)(const struct link *plink, char *units, int unitsSize);
|
|
|
|
/** @brief get the alarm condition from an input link
|
|
*
|
|
* Called to fetch the alarm status and severity for an input link target.
|
|
* Either status or severity pointers may be NULL when that value is not
|
|
* needed by the calling code. This method is used by several built-in
|
|
* record types to obtain the alarm condition for their generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param status where to put the alarm status (or NULL)
|
|
* @param severity where to put the severity (or NULL)
|
|
* @returns status value
|
|
*
|
|
* @note Link types which provide getAlarm should also provided getAlarmMsg().
|
|
*/
|
|
long (*getAlarm)(const struct link *plink, epicsEnum16 *status,
|
|
epicsEnum16 *severity);
|
|
|
|
/** @brief get the time-stamp from an input link
|
|
*
|
|
* Called to fetch the time-stamp for an input link target. This method is
|
|
* used by many built-in device supports to obtain the precision for their
|
|
* generic input links.
|
|
*
|
|
* @param plink the link
|
|
* @param pstamp where to put the answer
|
|
* @returns status value
|
|
*/
|
|
long (*getTimeStamp)(const struct link *plink, epicsTimeStamp *pstamp);
|
|
|
|
/* Put data */
|
|
|
|
/** @brief put a value to an output link
|
|
*
|
|
* Called to send nRequest elements of type dbrType found at pbuffer to an
|
|
* output link target.
|
|
*
|
|
* @param plink the link
|
|
* @param dbrType data type code
|
|
* @param pbuffer where to put the value
|
|
* @param nRequest number of elements to send
|
|
* @returns status value
|
|
*/
|
|
long (*putValue)(struct link *plink, short dbrType,
|
|
const void *pbuffer, long nRequest);
|
|
|
|
/** @brief put a value to an output link with asynchronous completion
|
|
*
|
|
* Called to send nRequest elements of type dbrType found at pbuffer to an
|
|
* output link target. If the return status is zero, the link type will
|
|
* later indicate the put has completed by calling dbLinkAsyncComplete()
|
|
* from a background thread, which will be used to continue the record
|
|
* process operation from where it left off.
|
|
*
|
|
* @param plink the link
|
|
* @param dbrType data type code
|
|
* @param pbuffer where to put the value
|
|
* @param nRequest number of elements to send
|
|
* @returns status value
|
|
*/
|
|
long (*putAsync)(struct link *plink, short dbrType,
|
|
const void *pbuffer, long nRequest);
|
|
|
|
/* Process */
|
|
|
|
/** @brief trigger processing of a forward link
|
|
*
|
|
* Called to trigger processing of the record pointed to by a forward link.
|
|
* This routine is optional, but if not provided no warning message will be
|
|
* shown when called by dbScanFwdLink(). JSON link types that do not support
|
|
* this operation should return NULL from their jlif::alloc_jlink() method
|
|
* if it gets called with a dbfType of DBF_FWDLINK.
|
|
*
|
|
* @param plink the link
|
|
*/
|
|
void (*scanForward)(struct link *plink);
|
|
|
|
/* Atomicity */
|
|
|
|
/** @brief execute a callback routine with link locked
|
|
*
|
|
* Called on an input link when multiple link attributes need to be fetched
|
|
* in an atomic fashion. The link type must call the callback routine and
|
|
* prevent any background I/O from updating any cached link data until that
|
|
* routine returns. This method is used by most input device support to
|
|
* fetch the timestamp along with the value when the record's TSE field is
|
|
* set to epicsTimeEventDeviceTime.
|
|
*
|
|
* @param plink the link
|
|
* @param rtn routine to execute
|
|
* @returns status value
|
|
*/
|
|
long (*doLocked)(struct link *plink, dbLinkUserCallback rtn, void *priv);
|
|
|
|
/** @brief Extended version of getAlarm
|
|
*
|
|
* Equivalent of getAlarm() and also copy out alarm message string.
|
|
* The msgbuf argument may be NULL and/or msgbuflen==0, in which case
|
|
* the call must be the same as a call to getAlarm().
|
|
*
|
|
* Implementations must write a trailing nil to msgbuf whenever
|
|
* @code msgbuf!=NULL && msgbuflen>0 @endcode .
|
|
*
|
|
* @since UNRELEASED
|
|
*/
|
|
long (*getAlarmMsg)(const struct link *plink, epicsEnum16 *status,
|
|
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
|
|
|
|
/** @brief Extended version of getTimeStamp
|
|
*
|
|
* Equivalent of getTimeStamp() and also copy out time tag.
|
|
* ptag may be NULL.
|
|
*
|
|
* @since Added after UNRELEASED
|
|
*/
|
|
long (*getTimeStampTag)(const struct link *plink, epicsTimeStamp *pstamp, epicsInt32 *ptag);
|
|
} lset;
|
|
|
|
#define dbGetSevr(link, sevr) \
|
|
dbGetAlarm(link, NULL, sevr)
|
|
|
|
DBCORE_API const char * dbLinkFieldName(const struct link *plink);
|
|
|
|
DBCORE_API void dbInitLink(struct link *plink, short dbfType);
|
|
DBCORE_API void dbAddLink(struct dbLocker *locker, struct link *plink,
|
|
short dbfType, dbChannel *ptarget);
|
|
|
|
DBCORE_API void dbLinkOpen(struct link *plink);
|
|
DBCORE_API void dbRemoveLink(struct dbLocker *locker, struct link *plink);
|
|
|
|
DBCORE_API int dbLinkIsDefined(const struct link *plink); /* 0 or 1 */
|
|
DBCORE_API int dbLinkIsConstant(const struct link *plink); /* 0 or 1 */
|
|
DBCORE_API int dbLinkIsVolatile(const struct link *plink); /* 0 or 1 */
|
|
|
|
DBCORE_API long dbLoadLink(struct link *plink, short dbrType,
|
|
void *pbuffer);
|
|
DBCORE_API long dbLoadLinkArray(struct link *, short dbrType, void *pbuffer,
|
|
long *pnRequest);
|
|
|
|
DBCORE_API long dbGetNelements(const struct link *plink, long *pnElements);
|
|
DBCORE_API int dbIsLinkConnected(const struct link *plink); /* 0 or 1 */
|
|
DBCORE_API int dbGetLinkDBFtype(const struct link *plink);
|
|
DBCORE_API long dbTryGetLink(struct link *, short dbrType, void *pbuffer,
|
|
long *nRequest);
|
|
DBCORE_API long dbGetLink(struct link *, short dbrType, void *pbuffer,
|
|
long *options, long *nRequest);
|
|
DBCORE_API long dbGetControlLimits(const struct link *plink, double *low,
|
|
double *high);
|
|
DBCORE_API long dbGetGraphicLimits(const struct link *plink, double *low,
|
|
double *high);
|
|
DBCORE_API long dbGetAlarmLimits(const struct link *plink, double *lolo,
|
|
double *low, double *high, double *hihi);
|
|
DBCORE_API long dbGetPrecision(const struct link *plink, short *precision);
|
|
DBCORE_API long dbGetUnits(const struct link *plink, char *units,
|
|
int unitsSize);
|
|
DBCORE_API long dbGetAlarm(const struct link *plink, epicsEnum16 *status,
|
|
epicsEnum16 *severity);
|
|
/** Get link alarm and message string.
|
|
* To ensure the complete message string is copied, ensure @code msgbuflen >= sizeof (dbCommon::amsg) @endcode .
|
|
* A trailing nil will be added whenever @code msgbuflen > 0 @endcode .
|
|
* @since UNRELEASED
|
|
*/
|
|
DBCORE_API long dbGetAlarmMsg(const struct link *plink, epicsEnum16 *status,
|
|
epicsEnum16 *severity, char *msgbuf, size_t msgbuflen);
|
|
#define dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN) dbGetAlarmMsg(LINK, STAT, SEVR, BUF, BUFLEN)
|
|
DBCORE_API long dbGetTimeStamp(const struct link *plink,
|
|
epicsTimeStamp *pstamp);
|
|
/** @since UNRELEASED */
|
|
DBCORE_API long dbGetTimeStampTag(const struct link *plink,
|
|
epicsTimeStamp *pstamp, epicsInt32 *ptag);
|
|
#define dbGetTimeStampTag(LINK, STAMP, TAG) dbGetTimeStampTag(LINK, STAMP, TAG)
|
|
DBCORE_API long dbPutLink(struct link *plink, short dbrType,
|
|
const void *pbuffer, long nRequest);
|
|
DBCORE_API void dbLinkAsyncComplete(struct link *plink);
|
|
DBCORE_API long dbPutLinkAsync(struct link *plink, short dbrType,
|
|
const void *pbuffer, long nRequest);
|
|
DBCORE_API void dbScanFwdLink(struct link *plink);
|
|
|
|
DBCORE_API long dbLinkDoLocked(struct link *plink, dbLinkUserCallback rtn,
|
|
void *priv);
|
|
|
|
DBCORE_API long dbLoadLinkLS(struct link *plink, char *pbuffer,
|
|
epicsUInt32 size, epicsUInt32 *plen);
|
|
DBCORE_API long dbGetLinkLS(struct link *plink, char *pbuffer,
|
|
epicsUInt32 buffer_size, epicsUInt32 *plen);
|
|
DBCORE_API long dbPutLinkLS(struct link *plink, char *pbuffer,
|
|
epicsUInt32 len);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* INC_dbLink_H */
|