Improve devSup example

This commit is contained in:
Andrew Johnson
2018-10-22 16:00:16 -05:00
parent 1893cb4f54
commit ea0556e471
2 changed files with 95 additions and 52 deletions
+73 -39
View File
@@ -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
View File
@@ -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*/