Improve devSup example
This commit is contained in:
+73
-39
@@ -6,7 +6,11 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devSup.h Device Support */
|
||||
/** @file devSup.h
|
||||
*
|
||||
* @brief Device support routines
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 6-1-90
|
||||
@@ -21,80 +25,110 @@
|
||||
/* structures defined elsewhere */
|
||||
struct dbCommon;
|
||||
struct devSup;
|
||||
struct ioscan_head; /* aka IOSCANPVT */
|
||||
typedef struct ioscan_head *IOSCANPVT;
|
||||
struct link; /* aka DBLINK */
|
||||
|
||||
/** Type safe alternative to 'struct dset'
|
||||
/** Type safe version of 'struct dset'
|
||||
*
|
||||
* Recommended usage
|
||||
* Recommended usage:
|
||||
*
|
||||
* In Makefile:
|
||||
@code
|
||||
long my_drv_init_record(dbCommon *prec);
|
||||
long my_drv_get_iointr_info(int deattach, dbCommon *prec, IOCSCANPVT* pscan);
|
||||
long my_longin_read(longinRecord *prec);
|
||||
typedef struct {
|
||||
typed_dset common;
|
||||
long (*read)(longinRecord *prec);
|
||||
} my_longin_dset;
|
||||
static const my_longin_dset devLiMyDrvName = {{
|
||||
5, // 4 from typed_dset + 1 more
|
||||
NULL,
|
||||
NULL,
|
||||
&my_drv_init_record,
|
||||
&my_drv_get_iointr_info
|
||||
},
|
||||
&my_longin_read
|
||||
USR_CFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
|
||||
@endcode
|
||||
*
|
||||
* In C source file:
|
||||
@code
|
||||
#include <devSup.h>
|
||||
#include <dbScan.h> // For IOCSCANPVT
|
||||
...
|
||||
#include <epicsExport.h> // defines epicsExportSharedSymbols
|
||||
...
|
||||
static long init_record(dbCommon *prec);
|
||||
static long get_iointr_info(int detach, dbCommon *prec, IOCSCANPVT* pscan);
|
||||
static long longin_read(longinRecord *prec);
|
||||
|
||||
const struct {
|
||||
dset common;
|
||||
long (*read)(longinRecord *prec);
|
||||
} devLiDevName = {
|
||||
{
|
||||
5, // 4 from dset + 1 from longinRecord
|
||||
NULL,
|
||||
NULL,
|
||||
&init_record,
|
||||
&get_iointr_info
|
||||
},
|
||||
&longin_read
|
||||
};
|
||||
epicsExportAddress(dset, devLiMyDrvName);
|
||||
epicsExportAddress(dset, devLiDevName);
|
||||
@endcode
|
||||
*/
|
||||
typedef struct typed_dset {
|
||||
/** Number of function pointers which follow. Must be >=4 */
|
||||
/** Number of function pointers which follow.
|
||||
* The value depends on the recordtype, but must be >=4 */
|
||||
long number;
|
||||
/** Called from dbior() */
|
||||
long (*report)(int lvl);
|
||||
/** Called twice during iocInit().
|
||||
* First with phase=0 early, before init_record() and array field alloc.
|
||||
* Again with phase=1 after init_record()
|
||||
* First with @a after = 0 before init_record() or array field allocation.
|
||||
* Again with @a after = 1 after init_record() has finished.
|
||||
*/
|
||||
long (*init)(int phase);
|
||||
long (*init)(int after);
|
||||
/** Called once per record instance */
|
||||
long (*init_record)(struct dbCommon *prec);
|
||||
/** Called when SCAN="I/O Intr" on startup, or after SCAN is changed.
|
||||
*
|
||||
* Caller must assign third arguement (IOCSCANPVT*). eg.
|
||||
* Caller must assign the third arguement (IOCSCANPVT*). eg.
|
||||
@code
|
||||
struct mpvt {
|
||||
IOSCANPVT drvlist;
|
||||
};
|
||||
...
|
||||
// init code calls
|
||||
// init_record() routine calls
|
||||
scanIoInit(&pvt->drvlist);
|
||||
...
|
||||
long my_get_ioint_info(int deattach, struct dbCommon *prec, IOCSCANPVT* pscan) {
|
||||
long my_get_ioint_info(int detach, struct dbCommon *prec, IOCSCANPVT* pscan) {
|
||||
if(prec->dpvt)
|
||||
*pscan = &((mypvt*)prec->dpvt)->drvlist;
|
||||
@endcode
|
||||
*
|
||||
* When a particular record instance can/will only used a single scan list, then
|
||||
* the 'detach' argument should be ignored.
|
||||
* When a particular record instance can/will only used a single scan list,
|
||||
* the @a detach argument can be ignored.
|
||||
*
|
||||
* If this is not the case, then the following should be noted.
|
||||
* get_ioint_info() called with deattach=0 to fetch the scan list to which this record will be added.
|
||||
* Again with detach=1 to fetch the scan list from which this record will be removed.
|
||||
* Calls will be balanced.
|
||||
* A call with detach=0 will be matched by a call with detach=1.
|
||||
* + get_ioint_info() is called with @a detach = 0 to fetch the scan list to
|
||||
* which this record will be added.
|
||||
* + get_ioint_info() is called later with @a detach = 1 to fetch the scan
|
||||
* list from which this record should be removed.
|
||||
* + Calls will be balanced, so a call with @a detach = 0 will be followed
|
||||
* by one with @a detach = 1.
|
||||
*
|
||||
* @note get_ioint_info() will be called during IOC shutdown if the del_record()
|
||||
* extended callback is provided. (from 3.15.0.1)
|
||||
* @note get_ioint_info() will be called during IOC shutdown if the
|
||||
* dsxt::del_record() extended callback is defined. (from 3.15.0.1)
|
||||
*/
|
||||
long (*get_ioint_info)(int deattach, struct dbCommon *prec, struct ioscan_head** pscan);
|
||||
/*other functions are record dependent*/
|
||||
long (*get_ioint_info)(int detach, struct dbCommon *prec, IOSCANPVT* pscan);
|
||||
/* Any further functions are specified by the record type. */
|
||||
} typed_dset;
|
||||
|
||||
typedef struct dsxt { /* device support extension table */
|
||||
/** Device support extension table.
|
||||
*
|
||||
* Optional routines to allow run-time address modifications to be communicated
|
||||
* to device support, which must register a struct dsxt by calling devExtend()
|
||||
* from its init() routine.
|
||||
*/
|
||||
typedef struct dsxt {
|
||||
/** Optional, called to offer device support a new record to control.
|
||||
*
|
||||
* Routine may return a non-zero error code to refuse record.
|
||||
*/
|
||||
long (*add_record)(struct dbCommon *precord);
|
||||
/** Optional, called to remove record from device support control.
|
||||
*
|
||||
* Routine return a non-zero error code to refuse record removal.
|
||||
*/
|
||||
long (*del_record)(struct dbCommon *precord);
|
||||
/* Recordtypes are *not* allowed to extend this table */
|
||||
/* Only future Base releases may extend this table. */
|
||||
} dsxt;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+22
-13
@@ -6,7 +6,10 @@
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* drvSup.h Driver Support */
|
||||
/** @file drvSup.h
|
||||
*
|
||||
* @brief Driver support routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
@@ -18,6 +21,7 @@
|
||||
|
||||
#include "errMdef.h"
|
||||
|
||||
/** Driver entry table */
|
||||
typedef struct typed_drvet {
|
||||
/** Number of function pointers which follow. Must be >=2 */
|
||||
long number;
|
||||
@@ -25,23 +29,28 @@ typedef struct typed_drvet {
|
||||
long (*report)(int lvl);
|
||||
/** Called during iocInit() */
|
||||
long (*init)(void);
|
||||
/*other functions are device dependent*/
|
||||
/* Any further functions are driver-specific */
|
||||
} typed_drvet;
|
||||
|
||||
typedef long (*DRVSUPFUN) (); /* ptr to driver support function for use with plain/untyped drvet */
|
||||
#ifdef USE_TYPED_DRVET
|
||||
|
||||
#ifndef USE_TYPED_DRVET
|
||||
|
||||
typedef struct drvet { /* driver entry table */
|
||||
long number; /*number of support routines*/
|
||||
DRVSUPFUN report; /*print report*/
|
||||
DRVSUPFUN init; /*init support*/
|
||||
/*other functions are device dependent*/
|
||||
}drvet;
|
||||
#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) )
|
||||
typedef typed_drvet drvet;
|
||||
|
||||
#else
|
||||
typedef typed_drvet drvet;
|
||||
|
||||
/* These interfaces may eventually get deprecated */
|
||||
|
||||
typedef long (*DRVSUPFUN) (); /* ptr to driver support function */
|
||||
|
||||
typedef struct drvet { /* driver entry table */
|
||||
long number; /* number of support routines */
|
||||
DRVSUPFUN report; /* print report */
|
||||
DRVSUPFUN init; /* init support */
|
||||
/* Any further functions are driver-specific */
|
||||
} drvet;
|
||||
|
||||
#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) )
|
||||
|
||||
#endif /* USE_TYPED_DRVET */
|
||||
|
||||
#define S_drv_noDrvSup (M_drvSup| 1) /*SDR_DRVSUP: Driver support missing*/
|
||||
|
||||
Reference in New Issue
Block a user