Compare commits

..

21 Commits

Author SHA1 Message Date
Michael Davidsaver
46e74328dc minor 2016-03-24 14:41:43 -04:00
Michael Davidsaver
cb35889a20 dbCa: make private all functions which assume CA_LINK is really dbCa 2016-03-24 14:41:43 -04:00
Michael Davidsaver
29afb88006 add broken lset 2016-03-24 14:41:43 -04:00
Michael Davidsaver
bd8977c51d more stats 2016-03-24 14:41:43 -04:00
Michael Davidsaver
32c3231f5d link: not pv_link backend type
informational, and a hint at what pvt points to
2016-03-24 14:41:43 -04:00
Michael Davidsaver
33033e6027 more close CA_LINK 2016-03-24 14:41:43 -04:00
Michael Davidsaver
905c5e3336 lset version and report 2016-03-24 14:41:43 -04:00
Michael Davidsaver
47b3c68af1 dbLink: dbAddLinkHook hack
Add a hook for outside code the hijack CA_LINKs
2016-03-24 14:41:43 -04:00
Michael Davidsaver
4b3bdf31c2 iocInit: close CA_LINKs through lset 2016-03-24 14:41:43 -04:00
Michael Davidsaver
3740082b61 iocInit: announce "init" hooks during iocShutdown 2016-03-24 14:41:43 -04:00
Michael Davidsaver
7a1766279c dbLock: dbLockerAlloc() accept const array of non-const pointers 2016-03-24 13:42:49 -04:00
Andrew Johnson
cec0222c5a Merged Keenan Lang's iocsh-silent branch 2016-03-24 10:13:17 -05:00
Keenan Lang
394820318c Getting branch up to date with trunk 2016-03-21 10:01:11 -05:00
Michael Davidsaver
45db78981c iocInit: no need to break DB_LINK when isolated
This is being done to free the link private struct,
but dbDbRemoveLink() is not used to avoid the overhead
of splitting every lockset just before the PDB
is free'd.

No reason to do this for non-isolated until scans threads
are stopped.
2016-03-20 09:43:40 -04:00
Michael Davidsaver
7d94d05bb7 iocInit: special clear link set in doCloseLinks() 2016-03-19 17:15:08 -04:00
Keenan Lang
5c93eb6049 Updated Changelog 2016-03-15 16:04:57 -05:00
Keenan Lang
92bd217ade Updating example iocsh startup scripts 2016-03-07 14:38:59 -06:00
Keenan Lang
f0b5b52cef Whitespace 2016-03-07 14:14:33 -06:00
Keenan Lang
e0b578aff5 Eliminated @-sign echo disabling, replaced with ability to disable comment echoing with '#-' 2016-03-07 14:12:04 -06:00
Keenan Lang
0fd07d1632 Updated iocsh to allow user to select that lines from included scripts not be echoed. 2016-03-04 16:08:05 -06:00
Andrew Johnson
fbf6b6d3e5 The usual post-tag updates 2016-03-03 17:41:58 -06:00
36 changed files with 434 additions and 213 deletions

View File

@@ -47,7 +47,7 @@ EPICS_MODIFICATION = 0
EPICS_PATCH_LEVEL = 1
# This will end in -DEV between official releases
#EPICS_DEV_SNAPSHOT=-DEV
EPICS_DEV_SNAPSHOT=-DEV
#EPICS_DEV_SNAPSHOT=-pre1
#EPICS_DEV_SNAPSHOT=-pre1-DEV
#EPICS_DEV_SNAPSHOT=-pre2
@@ -56,7 +56,7 @@ EPICS_PATCH_LEVEL = 1
#EPICS_DEV_SNAPSHOT=-rc1-DEV
#EPICS_DEV_SNAPSHOT=-rc2
#EPICS_DEV_SNAPSHOT=-rc2-DEV
EPICS_DEV_SNAPSHOT=
#EPICS_DEV_SNAPSHOT=
# No changes should be needed below here

View File

@@ -3,11 +3,13 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>EPICS Base R3.16.0.1 Release Notes</title>
<title>EPICS Base R3.16.0.2 Release Notes</title>
</head>
<body lang="en">
<h1 align="center">EPICS Base Release 3.16.0.1</h1>
<h1 align="center">EPICS Base Release 3.16.0.2</h1>
<p style="color:red">This version of EPICS Base has not been released yet.</p>
<h2 align="center">Changes made on the 3.16 branch since 3.15.3</h2>
<!-- Insert new items immediately below this template ...
@@ -18,6 +20,24 @@
-->
<h3>Echoless comments in iocsh</h3>
<p>The way comments are parsed by the iocsh interpreter has changed. The
interpreter can be selectively disabled from echoing comments coming from
a script by starting those lines with '#-' rather than just '#'.</p>
<h2 align="center">Changes pulled from the 3.15 branch since 3.16.0.1</h2>
<!-- Insert inherited items immediately below here ... -->
<h2 align="center">Changes pulled from the 3.14 branch since 3.16.0.1</h2>
<!-- Insert inherited items immediately below here ... -->
<hr>
<h2 align="center">Changes in 3.16.0.1 made since 3.15.3</h2>
<h3>Build support for CapFast and dbst removed</h3>
<p>The build rules associated with the CapFast-related tools <tt>sch2edif</tt>
@@ -126,7 +146,6 @@ of its CALLBACK objects.</p>
<h2 align="center">Changes pulled from the 3.15 branch since 3.15.3</h2>
<!-- Insert inherited items immediately below here ... -->
<h3>CA server configuration changes</h3>
@@ -183,7 +202,6 @@ dbQuietMacroWarnings=1 <i>VxWorks</i>
<h2 align="center">Changes pulled from the 3.14 branch since 3.15.3</h2>
<!-- Insert inherited items immediately below here ... -->
<h3>RTEMS NTP Support Issue</h3>

View File

@@ -314,6 +314,7 @@ void dbCaAddLinkCallback(struct link *plink,
plink->lset = &dbCa_lset;
plink->type = CA_LINK;
plink->value.pv_link.pvt = pca;
plink->value.pv_link.backend = "ca";
addAction(pca, CA_CONNECT);
epicsMutexUnlock(pca->lock);
}
@@ -332,6 +333,7 @@ void dbCaRemoveLink(struct dbLocker *locker, struct link *plink)
epicsMutexMustLock(pca->lock);
pca->plink = 0;
plink->value.pv_link.pvt = 0;
plink->value.pv_link.backend = NULL;
plink->value.pv_link.pvlMask = 0;
plink->type = PV_LINK;
plink->lset = NULL;
@@ -709,6 +711,8 @@ static void scanLinkOnce(dbCommon *prec, caLink *pca) {
}
static lset dbCa_lset = {
LSET_API_VERSION,
dbCaReportLink,
dbCaRemoveLink,
isConnected,
getDBFtype, getElements,

View File

@@ -20,6 +20,8 @@ extern "C" {
typedef void (*dbCaCallback)(void *userPvt);
epicsShareFunc void dbCaCallbackProcess(void *usrPvt);
#ifdef EPICS_DBCA_PRIVATE_API
epicsShareFunc void dbCaLinkInit(void); /* internal initialization for iocBuild() */
epicsShareFunc void dbCaLinkInitIsolated(void); /* internal initialization for iocBuildIsolated() */
epicsShareFunc void dbCaRun(void);
@@ -47,8 +49,10 @@ epicsShareFunc long dbCaPutLink(struct link *plink,short dbrType,
extern struct ca_client_context * dbCaClientContext;
#ifdef EPICS_DBCA_PRIVATE_API
epicsShareFunc void dbCaSync(void);
epicsShareFunc void dbCaReportLink(const struct link *plink, dbLinkReportInfo *pinfo);
epicsShareExtern void (*dbAddLinkHook)(struct link *link, short dbfType);
epicsShareFunc void dbSetBrokenLink(struct link *link, short dbfType);
#endif
/* These macros are for backwards compatibility */

View File

@@ -20,6 +20,7 @@
#include <string.h>
#include <errno.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbDefs.h"
#include "epicsEvent.h"
#include "epicsPrint.h"
@@ -52,7 +53,61 @@
#include "dbLock.h"
#include "link.h"
void dbCaReportLink(const struct link *plink, dbLinkReportInfo *pinfo)
{
caLink * const pca = (caLink *)plink->value.pv_link.pvt;
const char * fname = dbGetFieldName(pinfo->pentry),
* rname = dbGetRecordName(pinfo->pentry);
assert(pca);
epicsMutexLock(pca->lock);
assert(pca->plink==plink);
pinfo->connected = ca_field_type(pca->chid) != TYPENOTCONN;
pinfo->nWriteFail = pca->nNoWrite;
pinfo->nDisconnect = pca->nDisconnect;
if (pinfo->connected) {
pinfo->readable = ca_read_access(pca->chid);
pinfo->writable = ca_write_access(pca->chid);
if (pinfo->filter==dbLinkReportAll || pinfo->filter==dbLinkReportConnected) {
int rw = pinfo->readable |
pinfo->writable << 1;
static const char *rights[4] = {
"No Access", "Read Only",
"Write Only", "Read/Write"
};
int mask = plink->value.pv_link.pvlMask;
printf(LSET_REPORT_INDENT "%28s.%-4s ==> %-28s (%lu, %lu)\n",
rname,
fname,
plink->value.pv_link.pvname,
pca->nDisconnect,
pca->nNoWrite);
printf(LSET_REPORT_INDENT "%21s [%s%s%s%s] host %s, %s\n", "",
mask & pvlOptInpNative ? "IN" : " ",
mask & pvlOptInpString ? "IS" : " ",
mask & pvlOptOutNative ? "ON" : " ",
mask & pvlOptOutString ? "OS" : " ",
ca_host_name(pca->chid),
rights[rw]);
}
} else {
if (pinfo->filter==dbLinkReportAll || pinfo->filter==dbLinkReportDisconnected) {
printf(LSET_REPORT_INDENT "%28s.%-4s --> %-28s (%lu, %lu)\n",
rname,
fname,
plink->value.pv_link.pvname,
pca->nDisconnect,
pca->nNoWrite);
}
}
epicsMutexUnlock(pca->lock);
}
long dbcar(char *precordname, int level)
{
DBENTRY dbentry;
@@ -68,7 +123,7 @@ long dbcar(char *precordname, int level)
int noWriteAccess=0;
unsigned long nDisconnect=0;
unsigned long nNoWrite=0;
caLink *pca;
int j;
if (!precordname || precordname[0] == '\0' || !strcmp(precordname, "*")) {
@@ -90,50 +145,26 @@ long dbcar(char *precordname, int level)
dbScanLock(precord);
for (j=0; j<pdbRecordType->no_links; j++) {
pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[j]];
pdbentry->pflddes = pdbFldDes;
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
if (plink->type == CA_LINK) {
ncalinks++;
pca = (caLink *)plink->value.pv_link.pvt;
if (pca
&& pca->chid
&& (ca_field_type(pca->chid) != TYPENOTCONN)) {
nconnected++;
nDisconnect += pca->nDisconnect;
nNoWrite += pca->nNoWrite;
if (!ca_read_access(pca->chid)) noReadAccess++;
if (!ca_write_access(pca->chid)) noWriteAccess++;
if (level>1) {
int rw = ca_read_access(pca->chid) |
ca_write_access(pca->chid) << 1;
static const char *rights[4] = {
"No Access", "Read Only",
"Write Only", "Read/Write"
};
int mask = plink->value.pv_link.pvlMask;
printf("%28s.%-4s ==> %-28s (%lu, %lu)\n",
precord->name,
pdbFldDes->name,
plink->value.pv_link.pvname,
pca->nDisconnect,
pca->nNoWrite);
printf("%21s [%s%s%s%s] host %s, %s\n", "",
mask & pvlOptInpNative ? "IN" : " ",
mask & pvlOptInpString ? "IS" : " ",
mask & pvlOptOutNative ? "ON" : " ",
mask & pvlOptOutString ? "OS" : " ",
ca_host_name(pca->chid),
rights[rw]);
}
} else {
if (level>0) {
printf("%28s.%-4s --> %-28s (%lu, %lu)\n",
precord->name,
pdbFldDes->name,
plink->value.pv_link.pvname,
pca->nDisconnect,
pca->nNoWrite);
}
}
dbLinkReportInfo linfo;
memset(&linfo, 0, sizeof(linfo));
linfo.pentry = pdbentry;
if(level==0)
linfo.filter = dbLinkReportNone;
else if(level==1)
linfo.filter = dbLinkReportDisconnected;
else
linfo.filter = dbLinkReportAll;
if(level>2)
linfo.detailLevel = level-2;
dbReportLink(plink, &linfo);
nconnected += linfo.connected;
nDisconnect += linfo.nDisconnect;
noReadAccess += !linfo.readable;
noWriteAccess += !linfo.writable;
}
}
dbScanUnlock(precord);
@@ -190,7 +221,7 @@ void dbcaStats(int *pchans, int *pdiscon)
plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
if (plink->type == CA_LINK) {
ncalinks++;
if (dbCaIsLinkConnected(plink)) {
if (dbIsLinkConnected(plink)) {
nconnected++;
}
}

View File

@@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "cantProceed.h"
#include "cvtFast.h"
@@ -139,6 +140,8 @@ static long dbConstGetValue(struct link *plink, short dbrType, void *pbuffer,
}
static lset dbConst_lset = {
LSET_API_VERSION,
NULL,
NULL,
NULL,
NULL, dbConstGetNelements,
@@ -170,6 +173,7 @@ static long dbDbInitLink(struct link *plink, short dbfType)
pdbAddr = dbCalloc(1, sizeof(struct dbAddr));
*pdbAddr = dbaddr; /* structure copy */
plink->value.pv_link.pvt = pdbAddr;
plink->value.pv_link.backend = "db";
ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode);
/* merging into the same lockset is deferred to the caller.
* cf. initPVLinks()
@@ -184,6 +188,7 @@ static void dbDbAddLink(dbLocker *locker, struct link *plink, short dbfType, DBA
plink->lset = &dbDb_lset;
plink->type = DB_LINK;
plink->value.pv_link.pvt = ptarget;
plink->value.pv_link.backend = "db";
ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode);
/* target record is already locked in dbPutFieldLink() */
@@ -194,6 +199,7 @@ static void dbDbRemoveLink(dbLocker *locker, struct link *plink)
{
DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt;
plink->value.pv_link.pvt = 0;
plink->value.pv_link.backend = NULL;
plink->value.pv_link.getCvt = 0;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.lastGetdbrType = 0;
@@ -431,6 +437,8 @@ static void dbDbScanFwdLink(struct link *plink)
}
static lset dbDb_lset = {
LSET_API_VERSION,
NULL,
dbDbRemoveLink,
dbDbIsConnected,
dbDbGetDBFtype, dbDbGetElements,
@@ -442,8 +450,87 @@ static lset dbDb_lset = {
dbDbScanFwdLink
};
static void dbBrokenReportLink(const struct link *plink, dbLinkReportInfo *pinfo)
{
const char * fname = dbGetFieldName(pinfo->pentry),
* rname = dbGetRecordName(pinfo->pentry);
if (pinfo->filter==dbLinkReportAll || pinfo->filter==dbLinkReportDisconnected) {
printf("%28s.%-4s --> %-28s <invalid link type>\n",
rname,
fname,
plink->value.pv_link.pvname);
}
}
static void dbBrokenRemoveLink(dbLocker *locker, struct link *plink)
{
assert(!plink->value.pv_link.pvt);
plink->value.pv_link.pvt = 0;
plink->value.pv_link.backend = NULL;
plink->value.pv_link.getCvt = 0;
plink->value.pv_link.pvlMask = 0;
plink->value.pv_link.lastGetdbrType = 0;
plink->type = PV_LINK;
plink->lset = NULL;
}
static lset broken_lset = {
LSET_API_VERSION,
dbBrokenReportLink,
dbBrokenRemoveLink
};
/***************************** Generic Link API *****************************/
void dbSetBrokenLink(struct link *plink, short dbfType)
{
plink->lset = &broken_lset;
plink->type = CA_LINK;
plink->value.pv_link.pvt = NULL;
plink->value.pv_link.backend = "invalid";
}
static
void dbCaAddLinkHook(struct link *plink, short dbfType)
{
dbCaAddLink(NULL, plink, dbfType);
}
void (*dbAddLinkHook)(struct link *link, short dbfType) = &dbCaAddLinkHook;
/* initialize CA_LINK with possibly custom lset */
static
void customlset(struct link *plink, short dbfType)
{
int oops = 0;
plink->lset = NULL;
if(dbAddLinkHook)
(*dbAddLinkHook)(plink, dbfType);
if((plink->lset==NULL) ^ (plink->type==PV_LINK)) {
oops = 1;
errlogPrintf("custom link types must set both type and lset.\n");
}
if(plink->lset && plink->lset->version!=LSET_API_VERSION) {
oops = 1;
errlogPrintf("custom link types must set .version to LSET_API_VERSION (%u) not %u\n",
LSET_API_VERSION, plink->lset->version);
}
if(oops)
{
plink->lset = NULL;
plink->type = PV_LINK;
plink->value.pv_link.pvt = NULL; /* leaking */
}
if(!plink->lset)
dbSetBrokenLink(plink, dbfType); /* install "invalid" lset as fallback */
assert(plink->lset);
assert(plink->type==CA_LINK);
assert(plink->lset->version==LSET_API_VERSION);
}
void dbInitLink(struct link *plink, short dbfType)
{
struct dbCommon *precord = plink->precord;
@@ -469,7 +556,7 @@ void dbInitLink(struct link *plink, short dbfType)
if (dbfType == DBF_INLINK)
plink->value.pv_link.pvlMask |= pvlOptInpNative;
dbCaAddLink(NULL, plink, dbfType);
customlset(plink, dbfType);
if (dbfType == DBF_FWDLINK) {
char *pperiod = strrchr(plink->value.pv_link.pvname, '.');
@@ -508,7 +595,7 @@ void dbAddLink(dbLocker *locker, struct link *plink, short dbfType, DBADDR *ptar
if (dbfType == DBF_INLINK)
plink->value.pv_link.pvlMask |= pvlOptInpNative;
dbCaAddLink(locker, plink, dbfType);
customlset(plink, dbfType);
if (dbfType == DBF_FWDLINK) {
char *pperiod = strrchr(plink->value.pv_link.pvname, '.');
@@ -537,6 +624,15 @@ void dbRemoveLink(dbLocker *locker, struct link *plink)
}
}
void dbReportLink(const struct link *plink, dbLinkReportInfo *pinfo)
{
lset *plset = plink->lset;
if (plset && plset->reportLink) {
plset->reportLink(plink, pinfo);
}
}
int dbIsLinkConnected(const struct link *plink)
{
lset *plset = plink->lset;

View File

@@ -26,8 +26,37 @@ extern "C" {
#endif
struct dbLocker;
struct DBENTRY;
#define LSET_API_VERSION 1
#define LSET_REPORT_INDENT ""
typedef enum {
dbLinkReportNone,
dbLinkReportAll,
dbLinkReportConnected,
dbLinkReportDisconnected,
} dbLinkReportFilter;
typedef struct {
/* from caller */
dbLinkReportFilter filter;
int detailLevel;
struct DBENTRY *pentry;
unsigned clearstats:1; /* after reporting, zero stat counters */
/* callee fills in current state */
unsigned connected:1; /* is this link connected to it's underlying data source */
unsigned readable:1; /* would a dbGetLink() succeed at this moment */
unsigned writable:1; /* would a dbPutLink() succeed at this moment */
/* callee fills in statistics */
unsigned nDisconnect; /* number of times this link has entered a not connected state */
unsigned nEvents; /* number of times new data has been received from the underlying data source */
unsigned nWriteFail; /* number of times dbPutLink() has failed for this link */
} dbLinkReportInfo;
typedef struct lset {
unsigned version; /* must be set to LSET_API_VERSION */
void (*reportLink)(const struct link *plink, dbLinkReportInfo *pinfo);
void (*removeLink)(struct dbLocker *locker, struct link *plink);
int (*isConnected)(const struct link *plink);
int (*getDBFtype)(const struct link *plink);
@@ -58,6 +87,8 @@ epicsShareFunc long dbLoadLink(struct link *plink, short dbrType,
void *pbuffer);
epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct link *plink);
epicsShareFunc void dbReportLink(const struct link *plink, dbLinkReportInfo *pinfo);
epicsShareFunc long dbGetNelements(const struct link *plink, long *nelements);
epicsShareFunc int dbIsLinkConnected(const struct link *plink);
epicsShareFunc int dbGetLinkDBFtype(const struct link *plink);

View File

@@ -328,7 +328,7 @@ int dbLockUpdateRefs(dbLocker *locker, int update)
}
void dbLockerPrepare(struct dbLocker *locker,
struct dbCommon **precs,
struct dbCommon * const *precs,
size_t nrecs)
{
size_t i;
@@ -348,7 +348,7 @@ void dbLockerPrepare(struct dbLocker *locker,
dbLockUpdateRefs(locker, 1);
}
dbLocker *dbLockerAlloc(dbCommon **precs,
dbLocker *dbLockerAlloc(dbCommon * const *precs,
size_t nrecs,
unsigned int flags)
{

View File

@@ -27,7 +27,7 @@ typedef struct dbLocker dbLocker;
epicsShareFunc void dbScanLock(struct dbCommon *precord);
epicsShareFunc void dbScanUnlock(struct dbCommon *precord);
epicsShareFunc dbLocker *dbLockerAlloc(struct dbCommon **precs,
epicsShareFunc dbLocker *dbLockerAlloc(struct dbCommon * const *precs,
size_t nrecs,
unsigned int flags);

View File

@@ -96,7 +96,7 @@ epicsShareFunc void dbLockDecRef(lockSet *ls);
* nrecs must be <=DBLOCKER_NALLOC.
*/
void dbLockerPrepare(struct dbLocker *locker,
struct dbCommon **precs,
struct dbCommon * const *precs,
size_t nrecs);
void dbLockerFinalize(dbLocker *);

View File

@@ -48,6 +48,14 @@ typedef enum {
initHookAfterDatabasePaused,
initHookAfterIocPaused, /* End of iocPause command */
initHookAtIocShutdown, /* Start of iocShutdown */
initHookAfterCaLinkClose,
initHookAfterScanShutdown,
initHookAfterCallbackShutdown,
initHookAfterCaServerStopped,
initHookAfterDatabaseStopped,
initHookAfterIocShutdown, /* End of iocShutdown */
/* Deprecated states, provided for backwards compatibility.
* These states are announced at the same point they were before,
* but will not be repeated if the IOC gets paused and restarted.

View File

@@ -13,6 +13,7 @@
#include <string.h>
#include <math.h>
#define EPICS_DBCA_PRIVATE_API
#include "epicsString.h"
#include "dbUnitTest.h"
#include "epicsThread.h"

View File

@@ -47,7 +47,7 @@ extern "C" {
typedef dbBase DBBASE;
typedef struct{
typedef struct DBENTRY {
DBBASE *pdbbase;
dbRecordType *precordType;
dbFldDes *pflddes;

View File

@@ -85,6 +85,7 @@ struct pv_link {
LINKCVT getCvt; /* input conversion function */
short pvlMask; /* Options mask */
short lastGetdbrType; /* last dbrType for DB or CA get */
const char *backend;/* informational string describing the backend */
};
/* structure of a VME io channel */

View File

@@ -23,6 +23,7 @@
#include <errno.h>
#include <limits.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbDefs.h"
#include "ellLib.h"
#include "envDefs.h"
@@ -641,12 +642,13 @@ static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord,
dbScanLock(precord);
locked = 1;
}
dbCaRemoveLink(NULL, plink);
dbRemoveLink(NULL, plink);
} else if (plink->type == DB_LINK) {
} else if (iocBuildMode==buildIsolated && plink->type == DB_LINK) {
/* free link, but don't split lockset like dbDbRemoveLink() */
free(plink->value.pv_link.pvt);
plink->type = PV_LINK;
plink->lset = NULL;
}
}
@@ -687,13 +689,20 @@ static void doFreeRecord(dbRecordType *pdbRecordType, dbCommon *precord,
int iocShutdown(void)
{
if (iocState == iocVirgin || iocState == iocStopped) return 0;
initHookAnnounce(initHookAtIocShutdown); // TODO: iterate hooks in reverse
iterateRecords(doCloseLinks, NULL);
initHookAnnounce(initHookAfterCaLinkClose);
if (iocBuildMode==buildIsolated) {
/* stop and "join" threads */
scanStop();
initHookAnnounce(initHookAfterScanShutdown);
callbackStop();
initHookAnnounce(initHookAfterCallbackShutdown);
}
dbCaShutdown(); /* must be before dbFreeRecord and dbChannelExit */
initHookAnnounce(initHookAfterCaServerStopped);
/* placeholder, RSRV will eventually stop here */
initHookAnnounce(initHookAfterDatabaseStopped);
if (iocBuildMode==buildIsolated) {
/* free resources */
scanCleanup();
@@ -707,6 +716,7 @@ int iocShutdown(void)
}
iocState = iocStopped;
iocBuildMode = buildRSRV;
initHookAnnounce(initHookAfterIocShutdown);
return 0;
}

View File

@@ -611,12 +611,13 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
/*
* Ignore comment lines other than to echo
* them if they came from a script. This
* avoids macLib errors from comments.
* them if they came from a script (disable echoing
* with '#-'). This avoids macLib errors from comments.
*/
if (c == '#') {
if ((prompt == NULL) && (commandLine == NULL))
puts(raw);
if (raw[icin + 1] != '-')
puts(raw);
continue;
}
@@ -635,10 +636,12 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
}
/*
* Echo non-empty lines read from a script
* Echo non-empty lines read from a script.
* Comments delineated with '#-' aren't echoed.
*/
if ((prompt == NULL) && *line && (commandLine == NULL))
puts(line);
if ((c != '#') || (line[icin + 1] != '-'))
puts(line);
/*
* Ignore lines that became a comment or empty after macro expansion

View File

@@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
@@ -55,7 +56,7 @@ static long write_ao(aoRecord *prec)
long status;
if(prec->pact) return(0);
if(plink->type!=CA_LINK) {
if(plink->type!=CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink,DBR_DOUBLE,&prec->oval,1);
return(status);
}

View File

@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbLock.h"
@@ -55,7 +56,7 @@ static long write_bo(boRecord *prec)
long status;
if(prec->pact) return(0);
if(plink->type!=CA_LINK) {
if(plink->type!=CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink,DBR_USHORT,&prec->val,1);
return(status);
}

View File

@@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
@@ -49,7 +50,7 @@ static long write_calcout(calcoutRecord *prec)
long status;
if (prec->pact) return 0;
if (plink->type != CA_LINK) {
if (plink->type != CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink, DBR_DOUBLE, &prec->oval, 1);
return status;
}

View File

@@ -18,6 +18,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
@@ -52,7 +53,7 @@ static long write_longout(longoutRecord *prec)
long status;
if(prec->pact) return(0);
if(plink->type!=CA_LINK) {
if(plink->type!=CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink,DBR_LONG,&prec->val,1);
return(status);
}

View File

@@ -10,6 +10,9 @@
* Date: 30 Nov 2012
*/
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbAccess.h"
#include "recGbl.h"
@@ -31,7 +34,7 @@ static long write_string(lsoRecord *prec)
len = 1;
}
if (plink->type != CA_LINK)
if (plink->type != CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0)
return dbPutLink(plink, dtyp, prec->val, len);
status = dbCaPutLinkCallback(plink, dtyp, prec->val, len,

View File

@@ -13,7 +13,9 @@
*/
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbAccess.h"
#include "recGbl.h"
@@ -29,7 +31,7 @@ static long write_mbbo(mbboDirectRecord *prec)
if (prec->pact)
return 0;
if (plink->type != CA_LINK) {
if (plink->type != CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink, DBR_USHORT, &prec->val, 1);
return status;
}

View File

@@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
@@ -51,7 +52,7 @@ static long write_mbbo(mbboRecord *prec)
long status;
if(prec->pact) return(0);
if(plink->type!=CA_LINK) {
if(plink->type!=CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
status = dbPutLink(plink,DBR_USHORT,&prec->val,1);
return(status);
}

View File

@@ -10,6 +10,9 @@
* Date: 28 Sept 2012
*/
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbAccess.h"
#include "recGbl.h"
@@ -31,7 +34,7 @@ static long write_string(printfRecord *prec)
len = 1;
}
if (plink->type != CA_LINK)
if (plink->type != CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0)
return dbPutLink(plink, dtyp, prec->val, len);
status = dbCaPutLinkCallback(plink, dtyp, prec->val, len,

View File

@@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
@@ -52,7 +53,7 @@ static long write_stringout(stringoutRecord *prec)
if (prec->pact) return 0;
if (plink->type != CA_LINK) {
if (plink->type != CA_LINK || strcmp(plink->value.pv_link.backend,"ca")!=0) {
return dbPutLink(plink, DBR_STRING, &prec->val, 1);
}

View File

@@ -1,7 +1,7 @@
#!../../bin/_ARCH_/_APPNAME_
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
< envPaths
@@ -16,10 +16,10 @@ dbLoadTemplate "db/user.substitutions"
dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_"
dbLoadRecords "db/dbSubExample.db", "user=_USER_"
## Set this to see messages from mySub
#- Set this to see messages from mySub
#var mySubDebug 1
## Run this to trace the stages of iocInit
#- Run this to trace the stages of iocInit
#traceIocInit
cd "${TOP}/iocBoot/${IOC}"

View File

@@ -1,7 +1,7 @@
## Example RTEMS startup script
#- Example RTEMS startup script
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths
@@ -14,10 +14,10 @@ dbLoadTemplate("db/user.substitutions")
dbLoadRecords("db/_APPNAME_Version.db", "user=_USER_")
dbLoadRecords("db/dbSubExample.db", "user=_USER_")
## Set this to see messages from mySub
#- Set this to see messages from mySub
#var mySubDebug 1
## Run this to trace the stages of iocInit
#- Run this to trace the stages of iocInit
#traceIocInit
iocInit

View File

@@ -1,7 +1,7 @@
## Example vxWorks startup file
#- Example vxWorks startup file
## The following is needed if your board support package doesn't at boot time
## automatically cd to the directory containing its startup script
#- The following is needed if your board support package doesn't at boot time
#- automatically cd to the directory containing its startup script
#cd "_TOP_/iocBoot/_IOC_"
< cdCommands
@@ -9,8 +9,8 @@
cd topbin
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
ld 0,0, "_APPNAME_.munch"
## Register all support components
@@ -23,10 +23,10 @@ dbLoadTemplate "db/user.substitutions"
dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_"
dbLoadRecords "db/dbSubExample.db", "user=_USER_"
## Set this to see messages from mySub
#- Set this to see messages from mySub
#mySubDebug = 1
## Run this to trace the stages of iocInit
#- Run this to trace the stages of iocInit
#traceIocInit
cd startup

View File

@@ -1,26 +1,26 @@
#Instructions for creating and using a real nfsCommands file
#
# in order to use nfs do the following:
# 1) Create hostAdd and nfsMount commands for each nfs server
# 2) In each st.cmd file add the following two commands BEFORE any load commands
# ../nfs.cmd
# cd "<iocname>
#
# The hostAdd command has the form:
# hostAdd("<host>","xxx.xxx.xxx.xxx")
#
# You can also mount subdirectories as follows:
# nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#
# For example assume
#
# host is mercury with inet address 155.77.2.56
# You want to mount the directory (which is a file system of mercury)
# /home/mercury5/iocinfo
# as
# /iocinfo
#
# The commands would be
#
# hostAdd("mercury","155.77.2.56")
# nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")

View File

@@ -1,29 +1,29 @@
#Instructions for creating and using a real nfsCommands file
#
# in order to use nfs do the following:
# 1) Create hostAdd and nfsMount commands for each nfs server
# 2) In each st.cmd file add the following two commands BEFORE any load commands
# ../nfs.cmd
# cd "<iocname>
#
# The hostAdd command has the form:
# hostAdd("<host>","xxx.xxx.xxx.xxx")
#
# The nfsMount command has the form:
# nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#
# You can also mount subdirectories as follows:
# nfsMountAll("<host>")
#
# For example assume
#
# host is mercury with inet address 155.77.2.56
# You want to mount the directory (which is a file system of mercury)
# /home/mercury5/iocinfo
# as
# /iocinfo
#
# The commands would be
#
# hostAdd("mercury","155.77.2.56")
# nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The nfsMount command has the form:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- You can also mount subdirectories as follows:
#- nfsMountAll("<host>")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")

View File

@@ -1,7 +1,7 @@
#!../../bin/_ARCH_/_APPNAME_
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
< envPaths

View File

@@ -1,7 +1,7 @@
#!../../bin/_ARCH_/_APPNAME_
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths

View File

@@ -1,7 +1,7 @@
## Example RTEMS startup script
#- Example RTEMS startup script
## You may have to change _APPNAME_ to something else
## everywhere it appears in this file
#- You may have to change _APPNAME_ to something else
#- everywhere it appears in this file
#< envPaths

View File

@@ -1,7 +1,7 @@
## Example vxWorks startup file
#- Example vxWorks startup file
## The following is needed if your board support package doesn't at boot time
## automatically cd to the directory containing its startup script
#- The following is needed if your board support package doesn't at boot time
#- automatically cd to the directory containing its startup script
#cd "_TOP_/iocBoot/_IOC_"
< cdCommands

View File

@@ -1,29 +1,29 @@
#Instructions for creating and using a real nfsCommands file
#
# in order to use nfs do the following:
# 1) Create hostAdd and nfsMount commands for each nfs server
# 2) In each st.cmd file add the following two commands BEFORE any load commands
# ../nfs.cmd
# cd "<iocname>
#
# The hostAdd command has the form:
# hostAdd("<host>","xxx.xxx.xxx.xxx")
#
# The vxWorks nfsMount command has the form:
# nfsMount("<host>")
#
# You can also mount subdirectories as follows:
# nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#
# For example assume
#
# host is mercury with inet address 155.77.2.56
# You want to mount the directory (which is a file system of mercury)
# /home/mercury5/iocinfo
# as
# /iocinfo
#
# The commands would be
#
# hostAdd("mercury","155.77.2.56")
# nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The vxWorks nfsMount command has the form:
#- nfsMount("<host>")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")

View File

@@ -1,29 +1,29 @@
#Instructions for creating and using a real nfsCommands file
#
# in order to use nfs do the following:
# 1) Create hostAdd and nfsMount commands for each nfs server
# 2) In each st.cmd file add the following two commands BEFORE any load commands
# ../nfs.cmd
# cd "<iocname>
#
# The hostAdd command has the form:
# hostAdd("<host>","xxx.xxx.xxx.xxx")
#
# The vxWorks nfsMount command has the form:
# nfsMount("<host>")
#
# You can also mount subdirectories as follows:
# nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#
# For example assume
#
# host is mercury with inet address 155.77.2.56
# You want to mount the directory (which is a file system of mercury)
# /home/mercury5/iocinfo
# as
# /iocinfo
#
# The commands would be
#
# hostAdd("mercury","155.77.2.56")
# nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")
#- Instructions for creating and using a real nfsCommands file
#-
#- in order to use nfs do the following:
#- 1) Create hostAdd and nfsMount commands for each nfs server
#- 2) In each st.cmd file add the following two commands BEFORE any load commands
#- ../nfs.cmd
#- cd "<iocname>
#-
#- The hostAdd command has the form:
#- hostAdd("<host>","xxx.xxx.xxx.xxx")
#-
#- The vxWorks nfsMount command has the form:
#- nfsMount("<host>")
#-
#- You can also mount subdirectories as follows:
#- nfsMount("<host>", "/xxx/xxx/xxx", "/xxx")
#-
#- For example assume
#-
#- host is mercury with inet address 155.77.2.56
#- You want to mount the directory (which is a file system of mercury)
#- /home/mercury5/iocinfo
#- as
#- /iocinfo
#-
#- The commands would be
#-
#- hostAdd("mercury","155.77.2.56")
#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo")