iocInit: initialize links in iocBuild

Done before any driver, record, or device supports run.
Also before the hooks used by autosave.
This commit is contained in:
Michael Davidsaver
2014-08-01 11:28:10 -04:00
parent 200355bc00
commit 33804bd7ea
3 changed files with 77 additions and 7 deletions

View File

@@ -1888,6 +1888,65 @@ char * dbGetString(DBENTRY *pdbentry)
return (message);
}
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
{
short i;
for (i=0; i<rtyp->no_links; i++) {
dbLinkInfo link_info;
dbFldDes *pflddes = rtyp->papFldDes[rtyp->link_ind[i]];
DBLINK *plink = (DBLINK *)(((char *)prec) + pflddes->offset);
devSup *devsup = NULL;
/* link fields are zero'd on allocation.
* so are effectively CONSTANT, but with constantStr==NULL.
* Here we initialize them to have the correct link type,
* with zero values and empty (but non-NULL) strings.
*/
if(pflddes->isDevLink) {
devsup = (devSup *)ellNth(&rtyp->devList, prec->dtyp+1);
}
if(devsup)
plink->type = devsup->link_type;
else
plink->type = CONSTANT;
switch (plink->type) {
case CONSTANT: plink->value.constantStr = callocMustSucceed(1, 1, "init CONSTANT link"); break;
case PV_LINK: plink->value.pv_link.pvname = callocMustSucceed(1, 1, "init PV_LINK"); break;
case VME_IO: plink->value.vmeio.parm = pNullString; break;
case CAMAC_IO: plink->value.camacio.parm = pNullString; break;
case AB_IO: plink->value.abio.parm = pNullString; break;
case GPIB_IO: plink->value.gpibio.parm = pNullString; break;
case BITBUS_IO: plink->value.bitbusio.parm = pNullString; break;
case INST_IO: plink->value.instio.string = pNullString; break;
case BBGPIB_IO: plink->value.bbgpibio.parm = pNullString; break;
case VXI_IO: plink->value.vxiio.parm = pNullString; break;
}
if(!plink->text)
continue;
if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) {
/* This was already parsed once when ->text was set.
* Any syntax error messages were printed at that time.
*/
} else if(dbCanSetLink(plink, &link_info, devsup)!=0) {
errlogPrintf("Error: %s.%s: can't initialize link type %d with \"%s\" (type %d)\n",
prec->name, pflddes->name, plink->type, plink->text, link_info.ltype);
} else if(dbSetLink(plink, &link_info, devsup)) {
errlogPrintf("Error: %s.%s: failed to initialize link type %d with \"%s\" (type %d)\n",
prec->name, pflddes->name, plink->type, plink->text, link_info.ltype);
}
free(plink->text);
plink->text = NULL;
}
return 0;
}
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
{
char *pstr, *pend;

View File

@@ -51,6 +51,8 @@ typedef struct dbLinkInfo {
int hwnums[5];
} dbLinkInfo;
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec);
/* Parse link string. no record locks needed.
* on success caller must free pinfo->target
*/

View File

@@ -56,6 +56,8 @@
#include "dbCommon.h"
#include "dbLock.h"
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbStaticPvt.h"
#include "recGbl.h"
#include "dbNotify.h"
#include "dbCa.h"
@@ -82,7 +84,14 @@ static void initDatabase(void);
static void initialProcess(void);
static void exitDatabase(void *dummy);
/*
* Iterate through all record instances (but not aliases),
* calling a function for each one.
*/
typedef void (*recIterFunc)(dbRecordType *rtyp, dbCommon *prec, void *user);
static void iterateRecords(recIterFunc func, void *user);
/*
* Initialize EPICS on the IOC.
*/
@@ -122,8 +131,14 @@ static int iocBuild_1(void)
return 0;
}
static void prepareLinks(dbRecordType *rtyp, dbCommon *prec, void *junk)
{
dbInitRecordLinks(rtyp, prec);
}
static int iocBuild_2(void)
{
iterateRecords(prepareLinks, NULL);
initHookAnnounce(initHookAfterCaLinkInit);
initDrvSup();
@@ -413,12 +428,6 @@ static void finishDevSup(void)
}
}
}
/*
* Iterate through all record instances (but not aliases),
* calling a function for each one.
*/
typedef void (*recIterFunc)(dbRecordType *rtyp, dbCommon *prec, void *user);
static void iterateRecords(recIterFunc func, void *user)
{