Merge branch 'impr-sim-mode-2' into 3.17
This commit is contained in:
@@ -17,6 +17,18 @@
|
||||
|
||||
-->
|
||||
|
||||
<h3>Simulation mode improvements</h3>
|
||||
|
||||
<p>Records that support simulation mode have two new fields, <tt>SSCN</tt>
|
||||
(Simulation Scan Mode) and <tt>SDLY</tt> (Simulation Delay). <tt>SSCN</tt> is a
|
||||
menu field that provides an alternate value for the <tt>SCAN</tt> field to be
|
||||
used while the record is in simulation mode. This is especially useful for I/O
|
||||
scanned records, for which simulation mode was not working at all. Setting
|
||||
<tt>SDLY</tt> to a positive value makes the record process asynchronously in
|
||||
simulation mode, with the second stage processing happening after the specified
|
||||
time (in seconds).</p>
|
||||
|
||||
|
||||
<h3>Extend the dbServer API with init/run/pause/stop methods</h3>
|
||||
|
||||
<p>This change permits IOCs to be built that omit the CA server (RSRV) by
|
||||
|
||||
+62
-3
@@ -29,9 +29,11 @@
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbAccessDefs.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbAddr.h"
|
||||
#include "dbBase.h"
|
||||
#include "dbCommon.h"
|
||||
#include "menuSimm.h"
|
||||
#include "dbEvent.h"
|
||||
#include "db_field_log.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -255,7 +257,12 @@ void recGblFwdLink(void *precord)
|
||||
|
||||
void recGblGetTimeStamp(void *pvoid)
|
||||
{
|
||||
dbCommon* prec = (dbCommon*)pvoid;
|
||||
recGblGetTimeStampSimm(pvoid, menuSimmNO, 0);
|
||||
}
|
||||
|
||||
void recGblGetTimeStampSimm(void *pvoid, const epicsEnum16 simm, struct link *siol)
|
||||
{
|
||||
dbCommon *prec = (dbCommon *)pvoid;
|
||||
struct link *plink = &prec->tsel;
|
||||
|
||||
if (!dbLinkIsConstant(plink)) {
|
||||
@@ -269,8 +276,22 @@ void recGblGetTimeStamp(void *pvoid)
|
||||
}
|
||||
if (prec->tse != epicsTimeEventDeviceTime) {
|
||||
if (epicsTimeGetEvent(&prec->time, prec->tse))
|
||||
errlogPrintf("recGblGetTimeStamp: epicsTimeGetEvent failed, %s.TSE = %d\n",
|
||||
prec->name, prec->tse);
|
||||
errlogPrintf("recGblGetTimeStampSimm: epicsTimeGetEvent failed, %s.TSE = %d\n",
|
||||
prec->name, prec->tse);
|
||||
} else {
|
||||
if (simm != menuSimmNO) {
|
||||
if (siol && !dbLinkIsConstant(siol)) {
|
||||
if (dbGetTimeStamp(siol, &prec->time))
|
||||
errlogPrintf("recGblGetTimeStampSimm: dbGetTimeStamp (sim mode) failed, %s.SIOL = %s\n",
|
||||
prec->name, siol->value.pv_link.pvname);
|
||||
return;
|
||||
} else {
|
||||
if (epicsTimeGetCurrent(&prec->time))
|
||||
errlogPrintf("recGblGetTimeStampSimm: epicsTimeGetCurrent (sim mode) failed for %s.\n",
|
||||
prec->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,3 +370,41 @@ static void getMaxRangeValues(short field_type, double *pupper_limit,
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void recGblSaveSimm(const epicsEnum16 sscn,
|
||||
epicsEnum16 *poldsimm, const epicsEnum16 simm) {
|
||||
if (sscn == USHRT_MAX) return;
|
||||
*poldsimm = simm;
|
||||
}
|
||||
|
||||
void recGblCheckSimm(struct dbCommon *pcommon, epicsEnum16 *psscn,
|
||||
const epicsEnum16 oldsimm, const epicsEnum16 simm) {
|
||||
if (*psscn == USHRT_MAX) return;
|
||||
if (simm != oldsimm) {
|
||||
epicsUInt16 scan = pcommon->scan;
|
||||
scanDelete(pcommon);
|
||||
pcommon->scan = *psscn;
|
||||
scanAdd(pcommon);
|
||||
*psscn = scan;
|
||||
}
|
||||
}
|
||||
|
||||
void recGblInitSimm(struct dbCommon *pcommon, epicsEnum16 *psscn,
|
||||
epicsEnum16 *poldsimm, epicsEnum16 *psimm, struct link *psiml) {
|
||||
if (dbLinkIsConstant(psiml)) {
|
||||
recGblSaveSimm(*psscn, poldsimm, *psimm);
|
||||
dbLoadLink(psiml, DBF_USHORT, psimm);
|
||||
recGblCheckSimm(pcommon, psscn, *poldsimm, *psimm);
|
||||
}
|
||||
}
|
||||
|
||||
long recGblGetSimm(struct dbCommon *pcommon, epicsEnum16 *psscn,
|
||||
epicsEnum16 *poldsimm, epicsEnum16 *psimm, struct link *psiml) {
|
||||
long status;
|
||||
|
||||
recGblSaveSimm(*psscn, poldsimm, *psimm);
|
||||
status = dbGetLink(psiml, DBR_USHORT, psimm, 0, 0);
|
||||
if (status) return status;
|
||||
recGblCheckSimm(pcommon, psscn, *poldsimm, *psimm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,8 +63,17 @@ epicsShareFunc void recGblInheritSevr(int msMode, void *precord, epicsEnum16 sta
|
||||
epicsEnum16 sevr);
|
||||
epicsShareFunc void recGblFwdLink(void *precord);
|
||||
epicsShareFunc void recGblGetTimeStamp(void *precord);
|
||||
epicsShareFunc void recGblGetTimeStampSimm(void *prec, const epicsEnum16 simm, struct link *siol);
|
||||
epicsShareFunc void recGblCheckDeadband(epicsFloat64 *poldval, const epicsFloat64 newval,
|
||||
const epicsFloat64 deadband, unsigned *monitor_mask, const unsigned add_mask);
|
||||
epicsShareFunc void recGblSaveSimm(const epicsEnum16 sscn,
|
||||
epicsEnum16 *poldsimm, const epicsEnum16 simm);
|
||||
epicsShareFunc void recGblCheckSimm(struct dbCommon *prec, epicsEnum16 *psscn,
|
||||
const epicsEnum16 oldsimm, const epicsEnum16 simm);
|
||||
epicsShareFunc void recGblInitSimm(struct dbCommon *prec, epicsEnum16 *psscn,
|
||||
epicsEnum16 *poldsimm, epicsEnum16 *psimm, struct link *psiml);
|
||||
epicsShareFunc long recGblGetSimm(struct dbCommon *prec, epicsEnum16 *psscn,
|
||||
epicsEnum16 *poldsimm, epicsEnum16 *psimm, struct link *psiml);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ long dbPutStringNum(DBENTRY *pdbentry, const char *pstring)
|
||||
return status;
|
||||
|
||||
index = dbGetNMenuChoices(pdbentry);
|
||||
if (value > index && index > 0)
|
||||
if (value > index && index > 0 && value < USHRT_MAX)
|
||||
return S_dbLib_badField;
|
||||
|
||||
*field = value;
|
||||
|
||||
+65
-29
@@ -31,6 +31,7 @@
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsString.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -40,6 +41,7 @@
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "cantProceed.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
#define GEN_SIZE_OFFSET
|
||||
@@ -52,7 +54,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
static long cvt_dbaddr(DBADDR *);
|
||||
static long get_array_info(DBADDR *, long *, long *);
|
||||
@@ -141,8 +143,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have read_aai function defined */
|
||||
if (pdset->number < 5 || pdset->read_aai == NULL) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "aai: init_record");
|
||||
@@ -169,7 +171,7 @@ static long process(struct dbCommon *pcommon)
|
||||
prec->pact = TRUE;
|
||||
|
||||
prec->udf = FALSE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
@@ -179,6 +181,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return status;
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == aaiRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "aai: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)paddr->precord;
|
||||
@@ -313,35 +335,49 @@ static void monitor(aaiRecord *prec)
|
||||
|
||||
static long readValue(aaiRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct aaidset *pdset = (struct aaidset *)prec->dset;
|
||||
struct aaidset *pdset = (struct aaidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_aai(prec);
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
return pdset->read_aai(prec);
|
||||
}
|
||||
|
||||
if (prec->simm == menuYesNoYES){
|
||||
/* Device suport is responsible for buffer
|
||||
which might be read-only so we may not be
|
||||
allowed to call dbGetLink on it.
|
||||
Maybe also device support has an advanced
|
||||
simulation mode.
|
||||
Thus call device now.
|
||||
*/
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return pdset->read_aai(prec);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
/* Device suport is responsible for buffer
|
||||
which might be read-only so we may not be
|
||||
allowed to call dbGetLink on it.
|
||||
Maybe also device support has an advanced
|
||||
simulation mode.
|
||||
Thus call device now.
|
||||
|
||||
Reading through SIOL is handled in Soft Channel Device Support
|
||||
*/
|
||||
status = pdset->read_aai(prec);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
+49
-22
@@ -76,28 +76,55 @@ recordtype(aai) {
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
|
||||
+65
-27
@@ -31,6 +31,7 @@
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsString.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "cantProceed.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
@@ -52,7 +54,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
static long cvt_dbaddr(DBADDR *);
|
||||
static long get_array_info(DBADDR *, long *, long *);
|
||||
@@ -141,7 +143,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have write_aao function defined */
|
||||
if (pdset->number < 5 || pdset->write_aao == NULL) {
|
||||
@@ -169,7 +171,7 @@ static long process(struct dbCommon *pcommon)
|
||||
prec->pact = TRUE;
|
||||
|
||||
prec->udf = FALSE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
@@ -179,6 +181,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return status;
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == aaoRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "aao: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)paddr->precord;
|
||||
@@ -313,33 +335,49 @@ static void monitor(aaoRecord *prec)
|
||||
|
||||
static long writeValue(aaoRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct aaodset *pdset = (struct aaodset *)prec->dset;
|
||||
struct aaodset *pdset = (struct aaodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE) {
|
||||
/* no asyn allowed, pact true means do not process */
|
||||
return 0;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_aao(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO) {
|
||||
return pdset->write_aao(prec);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES) {
|
||||
/* Device suport is responsible for buffer
|
||||
which might be write-only so we may not be
|
||||
allowed to call dbPutLink on it.
|
||||
Maybe also device support has an advanced
|
||||
simulation mode.
|
||||
Thus call device now.
|
||||
*/
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return pdset->write_aao(prec);
|
||||
}
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
/* Device suport is responsible for buffer
|
||||
which might be write-only so we may not be
|
||||
allowed to call dbPutLink on it.
|
||||
Maybe also device support has an advanced
|
||||
simulation mode.
|
||||
Thus call device now.
|
||||
|
||||
Writing through SIOL is handled in Soft Channel Device Support
|
||||
*/
|
||||
status = pdset->write_aao(prec);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
+49
-22
@@ -76,28 +76,55 @@ recordtype(aao) {
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
|
||||
+80
-66
@@ -24,6 +24,7 @@
|
||||
#include "errlog.h"
|
||||
#include "epicsMath.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cvtTable.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbScan.h"
|
||||
@@ -96,22 +97,21 @@ typedef struct aidset { /* analog input dset */
|
||||
DEVSUPFUN special_linconv;
|
||||
}aidset;
|
||||
|
||||
|
||||
static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime);
|
||||
static void convert(aiRecord *prec);
|
||||
static void monitor(aiRecord *prec);
|
||||
static long readValue(aiRecord *prec);
|
||||
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)pcommon;
|
||||
aidset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
recGblInitConstantLink(&prec->siol,DBF_DOUBLE,&prec->sval);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_DOUBLE, &prec->sval);
|
||||
|
||||
if(!(pdset = (aidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ai: init_record");
|
||||
@@ -147,8 +147,8 @@ static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)pcommon;
|
||||
aidset *pdset = (aidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_ai==NULL) ) {
|
||||
@@ -163,10 +163,13 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) convert(prec);
|
||||
else if (status==2) status=0;
|
||||
|
||||
if (status == 0) prec->udf = isnan(prec->val);
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec,&timeLast);
|
||||
/* check event list */
|
||||
@@ -187,27 +190,35 @@ static long special(DBADDR *paddr,int after)
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_LINCONV):
|
||||
if(pdset->number<6) {
|
||||
recGblDbaddrError(S_db_noMod,paddr,"ai: special");
|
||||
return(S_db_noMod);
|
||||
}
|
||||
prec->init=TRUE;
|
||||
if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) {
|
||||
double eoff = prec->eoff;
|
||||
double eslo = prec->eslo;
|
||||
long status;
|
||||
prec->eoff = prec->egul;
|
||||
status = (*pdset->special_linconv)(prec,after);
|
||||
if (eoff != prec->eoff)
|
||||
db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG);
|
||||
if (eslo != prec->eslo)
|
||||
db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG);
|
||||
return(status);
|
||||
}
|
||||
return(0);
|
||||
if(pdset->number<6) {
|
||||
recGblDbaddrError(S_db_noMod,paddr,"ai: special");
|
||||
return(S_db_noMod);
|
||||
}
|
||||
prec->init=TRUE;
|
||||
if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) {
|
||||
double eoff = prec->eoff;
|
||||
double eslo = prec->eslo;
|
||||
long status;
|
||||
prec->eoff = prec->egul;
|
||||
status = (*pdset->special_linconv)(prec,after);
|
||||
if (eoff != prec->eoff)
|
||||
db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG);
|
||||
if (eslo != prec->eslo)
|
||||
db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG);
|
||||
return(status);
|
||||
}
|
||||
return(0);
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == aiRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"ai: special");
|
||||
return(S_db_badChoice);
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"ai: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +453,6 @@ static void convert(aiRecord *prec)
|
||||
}else{
|
||||
prec->val = val;
|
||||
}
|
||||
prec->udf = isnan(prec->val);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -469,46 +479,50 @@ static void monitor(aiRecord *prec)
|
||||
|
||||
static long readValue(aiRecord *prec)
|
||||
{
|
||||
long status;
|
||||
aidset *pdset = (aidset *) (prec->dset);
|
||||
aidset *pdset = (aidset *)prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_ai)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status = dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
status = pdset->read_ai(prec);
|
||||
break;
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
case menuSimmYES:
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_DOUBLE, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* don't convert */
|
||||
} else {
|
||||
prec->rval = (long)floor(prec->sval);
|
||||
status = 0; /* convert RVAL */
|
||||
}
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (prec->simm == menuSimmNO){
|
||||
status=(*pdset->read_ai)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuSimmYES){
|
||||
status = dbGetLink(&(prec->siol),DBR_DOUBLE,&(prec->sval),0,0);
|
||||
if (status==0){
|
||||
prec->val=prec->sval;
|
||||
prec->udf=isnan(prec->val);
|
||||
}
|
||||
status=2; /* dont convert */
|
||||
}
|
||||
else if (prec->simm == menuSimmRAW){
|
||||
status = dbGetLink(&(prec->siol),DBR_DOUBLE,&(prec->sval),0,0);
|
||||
if (status==0) {
|
||||
prec->udf=isnan(prec->sval);
|
||||
if (!prec->udf) {
|
||||
prec->rval=(long)floor(prec->sval);
|
||||
}
|
||||
}
|
||||
status=0; /* convert since we've written RVAL */
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ simulation mode.
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim. Input Specification")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -476,12 +476,13 @@ simulation mode.
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim. Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
@@ -491,6 +492,32 @@ simulation mode.
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
=head2 Device Support Interface
|
||||
|
||||
+46
-27
@@ -24,6 +24,7 @@
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsMath.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cvtTable.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -94,7 +95,6 @@ struct aodset { /* analog input dset */
|
||||
epicsExportAddress(rset,aoRSET);
|
||||
|
||||
|
||||
|
||||
static void checkAlarms(aoRecord *);
|
||||
static long fetch_value(aoRecord *, double *);
|
||||
static void convert(aoRecord *, double);
|
||||
@@ -107,10 +107,11 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct aodset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
double value;
|
||||
long status = 0;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if(!(pdset = (struct aodset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ao: init_record");
|
||||
@@ -132,7 +133,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
if (pdset->init_record) {
|
||||
long status=(*pdset->init_record)(prec);
|
||||
status = (*pdset->init_record)(prec);
|
||||
if (prec->linr == menuConvertSLOPE) {
|
||||
prec->eoff = eoff;
|
||||
prec->eslo = eslo;
|
||||
@@ -228,7 +229,7 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
@@ -267,6 +268,14 @@ static long special(DBADDR *paddr, int after)
|
||||
return (status);
|
||||
}
|
||||
return (0);
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == aoRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"ao: special");
|
||||
return(S_db_badChoice);
|
||||
@@ -546,30 +555,40 @@ static void monitor(aoRecord *prec)
|
||||
|
||||
static long writeValue(aoRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct aodset *pdset = (struct aodset *) (prec->dset);
|
||||
struct aodset *pdset = (struct aodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_ao)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status = dbGetLink(&prec->siml,DBR_USHORT,&(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_ao(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_ao)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status = dbPutLink(&(prec->siol),DBR_DOUBLE,&(prec->oval),1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_DOUBLE, &prec->oval, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -528,26 +528,53 @@ information on these fields.
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
promptgroup("50 - Output")
|
||||
|
||||
+71
-41
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbFldTypes.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -43,7 +44,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -95,10 +96,11 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct bidset *pdset;
|
||||
long status;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval);
|
||||
if(!(pdset = (struct bidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"bi: init_record");
|
||||
return(S_dev_noDSET);
|
||||
@@ -135,8 +137,9 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
if(status==0) { /* convert rval to val */
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if(status==0) { /* convert rval to val */
|
||||
if(prec->rval==0) prec->val =0;
|
||||
else prec->val = 1;
|
||||
prec->udf = FALSE;
|
||||
@@ -153,6 +156,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
biRecord *prec = (biRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == biRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "bi: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static long get_enum_str(const DBADDR *paddr, char *pstring)
|
||||
{
|
||||
biRecord *prec=(biRecord *)paddr->precord;
|
||||
@@ -252,43 +275,50 @@ static void monitor(biRecord *prec)
|
||||
|
||||
static long readValue(biRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct bidset *pdset = (struct bidset *) (prec->dset);
|
||||
struct bidset *pdset = (struct bidset *)prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_bi)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status = dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
status = pdset->read_bi(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuSimmNO){
|
||||
status=(*pdset->read_bi)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuSimmYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_ULONG,&(prec->sval),0,0);
|
||||
if (status==0){
|
||||
prec->val=(unsigned short)prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
status=2; /* dont convert */
|
||||
}
|
||||
else if (prec->simm == menuSimmRAW){
|
||||
status=dbGetLink(&(prec->siol),DBR_ULONG,&(prec->sval),0,0);
|
||||
if (status==0){
|
||||
prec->rval=prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
status=0; /* convert since we've written RVAL */
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuSimmYES:
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* Don't convert */
|
||||
} else {
|
||||
prec->rval = (unsigned short) prec->sval;
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ recordtype(bi) {
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -89,19 +89,46 @@ recordtype(bi) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
+58
-28
@@ -45,7 +45,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -136,10 +136,9 @@ static long init_record(struct dbCommon *pcommon,int pass)
|
||||
long status = 0;
|
||||
myCallback *pcallback;
|
||||
|
||||
if (pass == 0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "bo: init_record");
|
||||
@@ -255,7 +254,8 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
if((prec->val==1) && (prec->high>0)){
|
||||
myCallback *pcallback;
|
||||
pcallback = (myCallback *)(prec->rpvt);
|
||||
@@ -270,7 +270,27 @@ static long process(struct dbCommon *pcommon)
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
boRecord *prec = (boRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == boRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "bo: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
#define indexof(field) boRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr, char *units)
|
||||
@@ -400,30 +420,40 @@ static void monitor(boRecord *prec)
|
||||
|
||||
static long writeValue(boRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct bodset *pdset = (struct bodset *) (prec->dset);
|
||||
struct bodset *pdset = (struct bodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_bo)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&prec->siml,DBR_USHORT, &prec->simm,0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_bo(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_bo)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbPutLink(&(prec->siol),DBR_USHORT, &(prec->val),1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -118,27 +118,54 @@ recordtype(bo) {
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID outpt action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
|
||||
+51
-32
@@ -22,6 +22,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbScan.h"
|
||||
@@ -97,9 +98,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct eventdset *pdset;
|
||||
long status=0;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_STRING, &prec->sval);
|
||||
|
||||
if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) )
|
||||
@@ -125,7 +126,7 @@ static long process(struct dbCommon *pcommon)
|
||||
|
||||
postEvent(prec->epvt);
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
@@ -142,10 +143,20 @@ static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
eventRecord *prec = (eventRecord *)paddr->precord;
|
||||
|
||||
if (dbGetFieldIndex(paddr) == eventRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!after) return 0;
|
||||
|
||||
if (dbGetFieldIndex(paddr) == eventRecordVAL) {
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -162,39 +173,47 @@ static void monitor(eventRecord *prec)
|
||||
|
||||
static long readValue(eventRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct eventdset *pdset = (struct eventdset *) (prec->dset);
|
||||
struct eventdset *pdset = (struct eventdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_event)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_event(prec);
|
||||
break;
|
||||
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->read_event)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_STRING,
|
||||
&(prec->sval),0,0);
|
||||
if (status==0) {
|
||||
if (strcmp(prec->sval, prec->val) != 0) {
|
||||
strcpy(prec->val, prec->sval);
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
prec->udf=FALSE;
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_STRING, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (strcmp(prec->sval, prec->val) != 0) {
|
||||
strcpy(prec->val, prec->sval);
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
}
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ recordtype(event) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -37,19 +37,46 @@ recordtype(event) {
|
||||
size(40)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
|
||||
wdogInit(prec);
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_DOUBLE, &prec->sval);
|
||||
|
||||
/* must have device support defined */
|
||||
@@ -228,7 +228,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status == 0)
|
||||
add_count(prec);
|
||||
@@ -246,6 +246,14 @@ static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
histogramRecord *prec = (histogramRecord *) paddr->precord;
|
||||
|
||||
if (paddr->special == SPC_MOD && dbGetFieldIndex(paddr) == histogramRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
|
||||
@@ -373,33 +381,44 @@ static long clear_histogram(histogramRecord *prec)
|
||||
static long readValue(histogramRecord *prec)
|
||||
{
|
||||
struct histogramdset *pdset = (struct histogramdset *) prec->dset;
|
||||
long status;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact) {
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_histogram(prec);
|
||||
return status;
|
||||
break;
|
||||
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_DOUBLE, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->sgnl = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return(status);
|
||||
|
||||
if (prec->simm == menuYesNoNO) {
|
||||
status = pdset->read_histogram(prec);
|
||||
return status;
|
||||
}
|
||||
if (prec->simm == menuYesNoYES) {
|
||||
status = dbGetLink(&prec->siol,DBR_DOUBLE, &prec->sval, 0, 0);
|
||||
if (status == 0)
|
||||
prec->sgnl = prec->sval;
|
||||
}
|
||||
else {
|
||||
status = -1;
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return status;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ recordtype(histogram) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -114,22 +114,49 @@ recordtype(histogram) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(HOPR,DBF_ULONG) {
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(HOPR,DBF_ULONG) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
|
||||
+66
-41
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
#define GEN_SIZE_OFFSET
|
||||
@@ -44,7 +46,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(dbCommon *, int);
|
||||
static long process(dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -100,17 +102,11 @@ static long init_record(dbCommon *pcommon, int pass)
|
||||
struct int64indset *pdset;
|
||||
long status;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
/* int64in.siml must be a CONSTANT or a PV_LINK or a DB_LINK */
|
||||
if (prec->siml.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
}
|
||||
|
||||
/* int64in.siol must be a CONSTANT or a PV_LINK or a DB_LINK */
|
||||
if (prec->siol.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siol,DBF_LONG,&prec->sval);
|
||||
}
|
||||
/* int64in.siml and .siol must be a CONSTANT or a PV_LINK or a DB_LINK */
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_INT64, &prec->sval);
|
||||
|
||||
if(!(pdset = (struct int64indset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64in: init_record");
|
||||
@@ -150,8 +146,9 @@ static long process(dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
if (status==0) prec->udf = FALSE;
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) prec->udf = FALSE;
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
@@ -163,7 +160,27 @@ static long process(dbCommon *pcommon)
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
int64inRecord *prec = (int64inRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == int64inRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "int64in: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
#define indexof(field) int64inRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr,char *units)
|
||||
@@ -381,36 +398,44 @@ static void monitor(int64inRecord *prec)
|
||||
|
||||
static long readValue(int64inRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct int64indset *pdset = (struct int64indset *) (prec->dset);
|
||||
struct int64indset *pdset = (struct int64indset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_int64in)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_int64in(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->read_int64in)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_LONG,
|
||||
&(prec->sval),0,0);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_INT64, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->val = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (status==0) {
|
||||
prec->val=prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ simulation mode.
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -273,21 +273,48 @@ simulation mode.
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
#include "menuIvoa.h"
|
||||
#include "menuOmsl.h"
|
||||
@@ -41,7 +43,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(dbCommon *, int);
|
||||
static long process(dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -98,10 +100,10 @@ static long init_record(dbCommon *pcommon, int pass)
|
||||
struct int64outdset *pdset;
|
||||
long status=0;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (prec->siml.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
}
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if(!(pdset = (struct int64outdset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64out: init_record");
|
||||
return(S_dev_noDSET);
|
||||
@@ -180,7 +182,7 @@ static long process(dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
@@ -192,6 +194,26 @@ static long process(dbCommon *pcommon)
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
int64outRecord *prec = (int64outRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == int64outRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "int64out: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
#define indexof(field) int64outRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr,char *units)
|
||||
@@ -352,35 +374,45 @@ static void monitor(int64outRecord *prec)
|
||||
if (monitor_mask)
|
||||
db_post_events(prec, &prec->val, monitor_mask);
|
||||
}
|
||||
|
||||
|
||||
static long writeValue(int64outRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct int64outdset *pdset = (struct int64outdset *) (prec->dset);
|
||||
struct int64outdset *pdset = (struct int64outdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_int64out)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
|
||||
if (!RTN_SUCCESS(status))
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_int64out(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_int64out)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbPutLink(&prec->siol,DBR_INT64,&prec->val,1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_INT64, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void convert(int64outRecord *prec, epicsInt64 value)
|
||||
|
||||
@@ -305,26 +305,53 @@ simulation mode.
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
|
||||
=head3 Invalid Alarm Output Action
|
||||
|
||||
|
||||
+63
-33
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
#define GEN_SIZE_OFFSET
|
||||
@@ -44,7 +46,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -99,10 +101,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct longinRecord *prec = (struct longinRecord *)pcommon;
|
||||
struct longindset *pdset = (struct longindset *) prec->dset;
|
||||
|
||||
if (pass==0)
|
||||
return(0);
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_LONG, &prec->sval);
|
||||
|
||||
if (!pdset) {
|
||||
@@ -149,8 +150,9 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
if (status==0) prec->udf = FALSE;
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) prec->udf = FALSE;
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
@@ -163,6 +165,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
longinRecord *prec = (longinRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == longinRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "longin: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
#define indexof(field) longinRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr,char *units)
|
||||
@@ -380,36 +402,44 @@ static void monitor(longinRecord *prec)
|
||||
|
||||
static long readValue(longinRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct longindset *pdset = (struct longindset *) (prec->dset);
|
||||
struct longindset *pdset = (struct longindset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_longin)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_longin(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->read_longin)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_LONG,
|
||||
&(prec->sval),0,0);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_LONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->val = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (status==0) {
|
||||
prec->val=prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ recordtype(longin) {
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -143,19 +143,46 @@ recordtype(longin) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
+58
-27
@@ -20,6 +20,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
#include "menuIvoa.h"
|
||||
#include "menuOmsl.h"
|
||||
@@ -41,7 +43,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -96,10 +98,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct longoutRecord *prec = (struct longoutRecord *)pcommon;
|
||||
struct longoutdset *pdset = (struct longoutdset *) prec->dset;
|
||||
|
||||
if (pass==0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "longout: init_record");
|
||||
@@ -183,7 +184,7 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
@@ -195,6 +196,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
longoutRecord *prec = (longoutRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == longoutRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "longout: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
#define indexof(field) longoutRecord##field
|
||||
|
||||
static long get_units(DBADDR *paddr,char *units)
|
||||
@@ -358,32 +379,42 @@ static void monitor(longoutRecord *prec)
|
||||
|
||||
static long writeValue(longoutRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct longoutdset *pdset = (struct longoutdset *) (prec->dset);
|
||||
struct longoutdset *pdset = (struct longoutdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_longout)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
|
||||
if (!RTN_SUCCESS(status))
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_longout(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_longout)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbPutLink(&prec->siol,DBR_LONG,&prec->val,1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_LONG, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void convert(longoutRecord *prec, epicsInt32 value)
|
||||
|
||||
@@ -150,27 +150,54 @@ recordtype(longout) {
|
||||
interest(3)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
|
||||
+34
-18
@@ -18,6 +18,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -56,7 +57,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
pdset = (lsidset *) prec->dset;
|
||||
if (!pdset) {
|
||||
@@ -104,7 +105,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
monitor(prec);
|
||||
|
||||
@@ -171,6 +172,15 @@ static long put_array_info(DBADDR *paddr, long nNew)
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
lsiRecord *prec = (lsiRecord *) paddr->precord;
|
||||
int special_type = paddr->special;
|
||||
|
||||
if (special_type == SPC_MOD && dbGetFieldIndex(paddr) == lsiRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
@@ -211,40 +221,46 @@ static void monitor(lsiRecord *prec)
|
||||
|
||||
static long readValue(lsiRecord *prec)
|
||||
{
|
||||
long status;
|
||||
lsidset *pdset = (lsidset *) prec->dset;
|
||||
struct lsidset *pdset = (struct lsidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
goto read;
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
read:
|
||||
status = pdset->read_string(prec);
|
||||
break;
|
||||
|
||||
case menuYesNoYES:
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
status = dbGetLinkLS(&prec->siol, prec->val, prec->sizv, &prec->len);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLinkLS(&prec->siol, prec->val, prec->sizv, &prec->len);
|
||||
if (status == 0) prec->udf = FALSE;
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
if (!status)
|
||||
prec->udf = FALSE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Create Record Support Entry Table*/
|
||||
/* Create Record Support Entry Table */
|
||||
|
||||
#define report NULL
|
||||
#define initialize NULL
|
||||
|
||||
@@ -67,11 +67,12 @@ recordtype(lsi) {
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(2)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
@@ -81,8 +82,34 @@ recordtype(lsi) {
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
+31
-12
@@ -19,6 +19,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -60,7 +61,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
pdset = (lsodset *) prec->dset;
|
||||
if (!pdset) {
|
||||
@@ -146,7 +147,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return status;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
monitor(prec);
|
||||
|
||||
@@ -213,6 +214,15 @@ static long put_array_info(DBADDR *paddr, long nNew)
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
lsoRecord *prec = (lsoRecord *) paddr->precord;
|
||||
int special_type = paddr->special;
|
||||
|
||||
if (special_type == SPC_MOD && dbGetFieldIndex(paddr) == lsoRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
@@ -253,26 +263,35 @@ static void monitor(lsoRecord *prec)
|
||||
|
||||
static long writeValue(lsoRecord *prec)
|
||||
{
|
||||
long status;
|
||||
lsodset *pdset = (lsodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
goto write;
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return(status);
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
write:
|
||||
status = pdset->write_string(prec);
|
||||
break;
|
||||
|
||||
case menuYesNoYES:
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
status = dbPutLink(&prec->siol,DBR_STRING, prec->val,1);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLinkLS(&prec->siol, prec->val, prec->len);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
|
||||
@@ -89,24 +89,51 @@ recordtype(lso) {
|
||||
menu(menuPost)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode link")
|
||||
prompt("Simulation Mode link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -44,7 +45,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -100,8 +101,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (pass == 0)
|
||||
return status;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "mbbiDirect: init_record");
|
||||
@@ -113,7 +113,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
|
||||
/* Initialize MASK if the user set NOBT instead */
|
||||
@@ -158,7 +158,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status == 0) {
|
||||
/* Convert RVAL to VAL */
|
||||
@@ -184,6 +184,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return status;
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == mbbiDirectRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "mbbiDirect: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor(mbbiDirectRecord *prec)
|
||||
{
|
||||
epicsUInt16 events = recGblResetAlarms(prec);
|
||||
@@ -219,42 +239,49 @@ static void monitor(mbbiDirectRecord *prec)
|
||||
static long readValue(mbbiDirectRecord *prec)
|
||||
{
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
return pdset->read_mbbi(prec);
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
return pdset->read_mbbi(prec);
|
||||
status = pdset->read_mbbi(prec);
|
||||
break;
|
||||
|
||||
case menuSimmYES:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->val = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* Don't convert */
|
||||
} else {
|
||||
prec->rval = prec->sval;
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
status = 2; /* Don't convert */
|
||||
break;
|
||||
|
||||
case menuSimmRAW:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->rval = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
status = 0; /* Convert RVAL */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ recordtype(mbbiDirect) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -58,21 +58,48 @@ recordtype(mbbiDirect) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(B0,DBF_UCHAR) {
|
||||
prompt("Bit 0")
|
||||
pp(TRUE)
|
||||
|
||||
+46
-34
@@ -22,6 +22,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -46,7 +47,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
static long special(DBADDR *, int);
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -117,8 +118,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (pass == 0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
pdset = (struct mbbidset *) prec->dset;
|
||||
if (!pdset) {
|
||||
@@ -131,7 +131,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
|
||||
/* Initialize MASK if the user set NOBT instead */
|
||||
@@ -172,7 +172,7 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status == 0) {
|
||||
/* Convert RVAL to VAL */
|
||||
@@ -215,20 +215,25 @@ static long special(DBADDR *paddr, int after)
|
||||
mbbiRecord *prec = (mbbiRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
|
||||
switch (paddr->special) {
|
||||
case SPC_MOD:
|
||||
init_common(prec);
|
||||
if (fieldIndex >= mbbiRecordZRST && fieldIndex <= mbbiRecordFFST) {
|
||||
int event = DBE_PROPERTY;
|
||||
|
||||
if (!after) return 0;
|
||||
init_common(prec);
|
||||
if (prec->val == fieldIndex - mbbiRecordZRST)
|
||||
event |= DBE_VALUE | DBE_LOG;
|
||||
db_post_events(prec, &prec->val, event);
|
||||
return 0;
|
||||
}
|
||||
if (fieldIndex == mbbiRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "mbbi: special");
|
||||
return S_db_badChoice;
|
||||
@@ -372,42 +377,49 @@ static void monitor(mbbiRecord *prec)
|
||||
static long readValue(mbbiRecord *prec)
|
||||
{
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
return pdset->read_mbbi(prec);
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
return pdset->read_mbbi(prec);
|
||||
status = pdset->read_mbbi(prec);
|
||||
break;
|
||||
|
||||
case menuSimmYES:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->val = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* Don't convert */
|
||||
} else {
|
||||
prec->rval = prec->sval;
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
status = 2; /* Don't convert */
|
||||
break;
|
||||
|
||||
case menuSimmRAW:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->rval = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
status = 0; /* Convert RVAL */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ recordtype(mbbi) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -460,19 +460,46 @@ recordtype(mbbi) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -102,8 +103,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct mbbodset *pdset = (struct mbbodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (pass == 0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "mbboDirect: init_record");
|
||||
@@ -115,7 +115,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -232,7 +233,8 @@ CONTINUE:
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
monitor(prec);
|
||||
|
||||
/* Wrap up */
|
||||
@@ -244,6 +246,15 @@ CONTINUE:
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
mbboDirectRecord *prec = (mbboDirectRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
|
||||
if (paddr->special == SPC_MOD && fieldIndex == mbboDirectRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
@@ -335,26 +346,40 @@ static void convert(mbboDirectRecord *prec)
|
||||
|
||||
static long writeValue(mbboDirectRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct mbbodset *pdset = (struct mbbodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
return pdset->write_mbbo(prec);
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
return pdset->write_mbbo(prec);
|
||||
status = pdset->write_mbbo(prec);
|
||||
break;
|
||||
|
||||
case menuYesNoYES:
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -185,26 +185,53 @@ recordtype(mbboDirect) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID outpt action")
|
||||
promptgroup("50 - Output")
|
||||
|
||||
+40
-18
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -135,7 +136,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -254,7 +256,8 @@ CONTINUE:
|
||||
return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
monitor(prec);
|
||||
|
||||
/* Wrap up */
|
||||
@@ -268,20 +271,25 @@ static long special(DBADDR *paddr, int after)
|
||||
mbboRecord *prec = (mbboRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
|
||||
if (!after)
|
||||
return 0;
|
||||
|
||||
switch (paddr->special) {
|
||||
case SPC_MOD:
|
||||
init_common(prec);
|
||||
if (fieldIndex >= mbboRecordZRST && fieldIndex <= mbboRecordFFST) {
|
||||
int event = DBE_PROPERTY;
|
||||
|
||||
if (!after) return 0;
|
||||
init_common(prec);
|
||||
if (prec->val == fieldIndex - mbboRecordZRST)
|
||||
event |= DBE_VALUE | DBE_LOG;
|
||||
db_post_events(prec, &prec->val, event);
|
||||
return 0;
|
||||
}
|
||||
if (fieldIndex == mbboRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "mbbo: special");
|
||||
return S_db_badChoice;
|
||||
@@ -427,26 +435,40 @@ static void convert(mbboRecord *prec)
|
||||
|
||||
static long writeValue(mbboRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct mbbodset *pdset = (struct mbbodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact)
|
||||
return pdset->write_mbbo(prec);
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
return pdset->write_mbbo(prec);
|
||||
status = pdset->write_mbbo(prec);
|
||||
break;
|
||||
|
||||
case menuYesNoYES:
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -465,27 +465,54 @@ recordtype(mbbo) {
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID outpt action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
#define GEN_SIZE_OFFSET
|
||||
@@ -42,7 +44,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -96,10 +98,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val));
|
||||
struct stringindset *pdset = (struct stringindset *) prec->dset;
|
||||
|
||||
if (pass==0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_STRING, prec->sval);
|
||||
|
||||
if (!pdset) {
|
||||
@@ -141,9 +142,9 @@ static long process(struct dbCommon *pcommon)
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
@@ -154,6 +155,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
stringinRecord *prec = (stringinRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == stringinRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "stringin: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor(stringinRecord *prec)
|
||||
{
|
||||
int monitor_mask = recGblResetAlarms(prec);
|
||||
@@ -174,35 +195,44 @@ static void monitor(stringinRecord *prec)
|
||||
|
||||
static long readValue(stringinRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct stringindset *pdset = (struct stringindset *) (prec->dset);
|
||||
struct stringindset *pdset = (struct stringindset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_stringin)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_stringin(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->read_stringin)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbGetLink(&(prec->siol),DBR_STRING,
|
||||
prec->sval,0,0);
|
||||
if (status==0) {
|
||||
strcpy(prec->val,prec->sval);
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_STRING, prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
strcpy(prec->val, prec->sval);
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ recordtype(stringin) {
|
||||
menu(stringinPOST)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
@@ -53,19 +53,46 @@ recordtype(stringin) {
|
||||
size(40)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
interest(1)
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "menuOmsl.h"
|
||||
#include "menuIvoa.h"
|
||||
#include "menuYesNo.h"
|
||||
@@ -44,7 +46,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
#define cvt_dbaddr NULL
|
||||
#define get_array_info NULL
|
||||
@@ -98,10 +100,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val));
|
||||
struct stringoutdset *pdset = (struct stringoutdset *) prec->dset;
|
||||
|
||||
if (pass==0)
|
||||
return 0;
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "stringout: init_record");
|
||||
@@ -179,13 +180,34 @@ static long process(struct dbCommon *pcommon)
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
monitor(prec);
|
||||
recGblFwdLink(prec);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
stringoutRecord *prec = (stringoutRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == stringoutRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "stringout: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor(stringoutRecord *prec)
|
||||
{
|
||||
int monitor_mask = recGblResetAlarms(prec);
|
||||
@@ -206,32 +228,40 @@ static void monitor(stringoutRecord *prec)
|
||||
|
||||
static long writeValue(stringoutRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct stringoutdset *pdset = (struct stringoutdset *) (prec->dset);
|
||||
struct stringoutdset *pdset = (struct stringoutdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_stringout)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_USHORT,
|
||||
&(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->write_stringout(prec);
|
||||
break;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_stringout)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbPutLink(&prec->siol,DBR_STRING,
|
||||
prec->val,1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
case menuYesNoYES: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbPutLink(&prec->siol, DBR_STRING, &prec->val, 1);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return(status);
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -54,27 +54,54 @@ recordtype(stringout) {
|
||||
menu(stringoutPOST)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(IVOA,DBF_MENU) {
|
||||
prompt("INVALID output action")
|
||||
promptgroup("50 - Output")
|
||||
interest(2)
|
||||
|
||||
@@ -104,6 +104,19 @@ regressTest_SRCS += regressTest_registerRecordDeviceDriver.cpp
|
||||
TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db ../regressHex.db ../regressLinkMS.db
|
||||
TESTS += regressTest
|
||||
|
||||
TARGETS += $(COMMON_DIR)/simmTest.dbd
|
||||
TARGETS += $(COMMON_DIR)/simmTest.db
|
||||
DBDDEPENDS_FILES += simmTest.dbd$(DEP)
|
||||
DBDDEPENDS_FILES += simmTest.db$(DEP)
|
||||
simmTest_DBD += base.dbd
|
||||
TESTPROD_HOST += simmTest
|
||||
simmTest_SRCS += simmTest.c
|
||||
simmTest_SRCS += simmTest_registerRecordDeviceDriver.cpp
|
||||
testHarness_SRCS += simmTest.c
|
||||
testHarness_SRCS += simmTest_registerRecordDeviceDriver.cpp
|
||||
TESTFILES += $(COMMON_DIR)/simmTest.dbd $(COMMON_DIR)/simmTest.db
|
||||
TESTS += simmTest
|
||||
|
||||
# epicsRunRecordTests runs all the test programs in a known working order.
|
||||
testHarness_SRCS += epicsRunRecordTests.c
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ int asTest(void);
|
||||
int linkRetargetLinkTest(void);
|
||||
int linkInitTest(void);
|
||||
int asyncSoftTest(void);
|
||||
int simmTest(void);
|
||||
|
||||
void epicsRunRecordTests(void)
|
||||
{
|
||||
@@ -41,5 +42,7 @@ void epicsRunRecordTests(void)
|
||||
|
||||
runTest(asyncSoftTest);
|
||||
|
||||
runTest(simmTest);
|
||||
|
||||
epicsExit(0); /* Trigger test harness */
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# no info
|
||||
record(ai, "ai-0") {
|
||||
}
|
||||
# only scan
|
||||
record(ai, "ai-1") {
|
||||
field(SSCN,"2 second")
|
||||
}
|
||||
# only delay
|
||||
record(ai, "ai-2") {
|
||||
field(SDLY,".234")
|
||||
}
|
||||
# scan and delay
|
||||
record(ai, "ai-3") {
|
||||
field(SSCN,"5 second")
|
||||
field(SDLY,".345")
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2017 ITER Organization
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbUnitTest.h>
|
||||
#include <testMain.h>
|
||||
#include <dbAccess.h>
|
||||
#include <epicsTime.h>
|
||||
#include <epicsThread.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include "recSup.h"
|
||||
#include "aiRecord.h"
|
||||
#include "aoRecord.h"
|
||||
#include "aaiRecord.h"
|
||||
#include "aaoRecord.h"
|
||||
#include "biRecord.h"
|
||||
#include "boRecord.h"
|
||||
#include "mbbiRecord.h"
|
||||
#include "mbboRecord.h"
|
||||
#include "mbbiDirectRecord.h"
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "longinRecord.h"
|
||||
#include "longoutRecord.h"
|
||||
#include "int64inRecord.h"
|
||||
#include "int64outRecord.h"
|
||||
#include "stringinRecord.h"
|
||||
#include "stringoutRecord.h"
|
||||
#include "lsiRecord.h"
|
||||
#include "lsoRecord.h"
|
||||
#include "eventRecord.h"
|
||||
#include "histogramRecord.h"
|
||||
#include "waveformRecord.h"
|
||||
|
||||
/*
|
||||
* Tests for simulation mode
|
||||
*/
|
||||
|
||||
void simmTest_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
static
|
||||
void startSimmTestIoc(const char *dbfile)
|
||||
{
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("simmTest.dbd", NULL, NULL);
|
||||
simmTest_registerRecordDeviceDriver(pdbbase);
|
||||
testdbReadDatabase(dbfile, NULL, NULL);
|
||||
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
}
|
||||
|
||||
static char *rawSupp[] = {
|
||||
"ai",
|
||||
"bi",
|
||||
"mbbi",
|
||||
"mbbiDirect",
|
||||
};
|
||||
|
||||
static
|
||||
int hasRawSimmSupport(const char *rectype) {
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(rawSupp)/sizeof(rawSupp[0])); i++)
|
||||
if (strcmp(rectype, rawSupp[i]) == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PVNAMELENGTH 60
|
||||
static char nameVAL[PVNAMELENGTH];
|
||||
static char nameB0[PVNAMELENGTH];
|
||||
static char nameRVAL[PVNAMELENGTH];
|
||||
static char nameSGNL[PVNAMELENGTH];
|
||||
static char nameSIMM[PVNAMELENGTH];
|
||||
static char nameSIML[PVNAMELENGTH];
|
||||
static char nameSVAL[PVNAMELENGTH];
|
||||
static char nameSIOL[PVNAMELENGTH];
|
||||
static char nameSCAN[PVNAMELENGTH];
|
||||
static char namePROC[PVNAMELENGTH];
|
||||
static char namePACT[PVNAMELENGTH];
|
||||
static char nameSTAT[PVNAMELENGTH];
|
||||
static char nameSEVR[PVNAMELENGTH];
|
||||
static char nameSIMS[PVNAMELENGTH];
|
||||
static char nameTSE[PVNAMELENGTH];
|
||||
static char nameSimmode[PVNAMELENGTH];
|
||||
static char nameSimval[PVNAMELENGTH];
|
||||
static char nameSimvalNORD[PVNAMELENGTH];
|
||||
static char nameSimvalLEN[PVNAMELENGTH];
|
||||
|
||||
#define SETNAME(field) strcpy(name ## field, name); strcat(name ## field, "." #field)
|
||||
static
|
||||
void setNames(const char *name)
|
||||
{
|
||||
SETNAME(VAL); SETNAME(B0); SETNAME(RVAL); SETNAME(SGNL);
|
||||
SETNAME(SVAL); SETNAME(SIMM); SETNAME(SIML); SETNAME(SIOL); SETNAME(SIMS);
|
||||
SETNAME(SCAN); SETNAME(PROC); SETNAME(PACT);
|
||||
SETNAME(STAT); SETNAME(SEVR); SETNAME(TSE);
|
||||
strcpy(nameSimmode, name); strcat(nameSimmode, ":simmode");
|
||||
strcpy(nameSimval, name); strcat(nameSimval, ":simval");
|
||||
strcpy(nameSimvalNORD, name); strcat(nameSimvalNORD, ":simval.NORD");
|
||||
strcpy(nameSimvalLEN, name); strcat(nameSimvalLEN, ":simval.LEN");
|
||||
}
|
||||
|
||||
/*
|
||||
* Parsing of info items and xsimm structure setting
|
||||
*/
|
||||
static
|
||||
void testSimmSetup(void)
|
||||
{
|
||||
aiRecord *precai;
|
||||
|
||||
testDiag("##### Simm initialization #####");
|
||||
|
||||
/* no config */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-0");
|
||||
testOk(precai->simpvt == NULL, "ai-0.SIMPVT = %p == NULL [no callback]", precai->simpvt);
|
||||
testOk(precai->sscn == USHRT_MAX, "ai-0.SSCN = %u == USHRT_MAX (not set)", precai->sscn);
|
||||
testOk(precai->sdly < 0., "ai-0.SDLY = %g < 0.0 (not set)", precai->sdly);
|
||||
|
||||
/* with SCAN */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-1");
|
||||
testOk(precai->sscn == 5, "ai-1.SSCN = %u == 5 (2 second)", precai->sscn);
|
||||
testOk(precai->sdly < 0., "ai-1.SDLY = %g < 0.0 (not set)", precai->sdly);
|
||||
|
||||
/* with DELAY */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-2");
|
||||
testOk(precai->sscn == USHRT_MAX, "ai-2.SSCN = %u == USHRT_MAX (not set)", precai->sscn);
|
||||
testOk(precai->sdly == 0.234, "ai-2.SDLY = %g == 0.234", precai->sdly);
|
||||
|
||||
/* with SCAN and DELAY */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-3");
|
||||
testOk(precai->sscn == 4, "ai-3.SSCN = %u == 4 (5 second)", precai->sscn);
|
||||
testOk(precai->sdly == 0.345, "ai-3.SDLY = %g == 0.345", precai->sdly);
|
||||
}
|
||||
|
||||
/*
|
||||
* SIMM triggered SCAN swapping, by writing to SIMM and through SIML
|
||||
*/
|
||||
|
||||
static
|
||||
void testSimmToggle(const char *name, epicsEnum16 *psscn)
|
||||
{
|
||||
testDiag("## SIMM toggle and SCAN swapping ##");
|
||||
|
||||
/* SIMM mode by setting the field */
|
||||
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
|
||||
testDiag("set SIMM to YES");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "YES");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
/* Change simm:SCAN when simmYES */
|
||||
testdbPutFieldOk(nameSCAN, DBR_USHORT, 3);
|
||||
|
||||
testDiag("set SIMM to NO");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "NO");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 3, "SSCN = %u == 3 (10 second)", *psscn);
|
||||
*psscn = 1;
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("set SIMM to RAW");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "RAW");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM to NO");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "NO");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
|
||||
/* SIMM mode through SIML */
|
||||
|
||||
testdbPutFieldOk(nameSIML, DBR_STRING, nameSimmode);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to YES");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 1);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to NO");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 0);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("set SIMM (via SIML -> simmode) to RAW");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 2);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to NO");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 0);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading from SVAL (direct write or through SIOL link)
|
||||
*/
|
||||
|
||||
static
|
||||
void testSvalRead(const char *name,
|
||||
const epicsTimeStamp *mytime,
|
||||
const epicsTimeStamp *svtime)
|
||||
{
|
||||
epicsTimeStamp last;
|
||||
|
||||
if (strcmp(name, "histogram") == 0)
|
||||
strcpy(nameVAL, nameSGNL);
|
||||
|
||||
if (strcmp(name, "aai") != 0 &&
|
||||
strcmp(name, "waveform") != 0 &&
|
||||
strcmp(name, "lsi") != 0) {
|
||||
|
||||
testDiag("## Reading from SVAL ##");
|
||||
|
||||
testDiag("in simmNO, SVAL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 0);
|
||||
if (strcmp(name, "stringin") == 0)
|
||||
testdbPutFieldOk(nameSVAL, DBR_STRING, "1");
|
||||
else
|
||||
testdbPutFieldOk(nameSVAL, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SVAL is used for VAL");
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 1);
|
||||
testDiag("No SIMS setting: STAT/SEVR == NO_ALARM");
|
||||
testdbGetFieldEqual(nameSTAT, DBR_STRING, "NO_ALARM");
|
||||
testdbGetFieldEqual(nameSEVR, DBR_USHORT, 0);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("in simmRAW, SVAL is used for RVAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameRVAL, DBR_USHORT, 1);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
}
|
||||
|
||||
testDiag("## Reading from SIOL->SVAL ##");
|
||||
|
||||
/* Set SIOL link to simval */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, nameSimval);
|
||||
|
||||
testDiag("in simmNO, SIOL->SVAL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 0);
|
||||
testdbPutFieldOk(nameSimval, DBR_LONG, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SIOL->SVAL is used for VAL");
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 3);
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 1);
|
||||
testDiag("SIMS is INVALID: STAT/SEVR == SIMM/INVALID");
|
||||
testdbGetFieldEqual(nameSTAT, DBR_STRING, "SIMM");
|
||||
testdbGetFieldEqual(nameSEVR, DBR_USHORT, 3);
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 0);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("in simmRAW, SIOL->SVAL is used for RVAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameRVAL, DBR_USHORT, 1);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
|
||||
/* My timestamp must be later than simval's */
|
||||
testOk(epicsTimeLessThan(svtime, mytime), "simval time < my time [TSE = 0]");
|
||||
|
||||
testDiag("for TSE=-2 (from device) and simmYES, take time stamp from IOC or input link");
|
||||
|
||||
/* Set simmYES */
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
|
||||
/* Set TSE to -2 (from device) and reprocess: timestamps is taken through SIOL from simval */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, -2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeEqual(svtime, mytime), "simval time == my time [TSE = -2]");
|
||||
last = *mytime;
|
||||
|
||||
/* With TSE=-2 and no SIOL, timestamp is taken from IOC */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, "");
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeLessThan(&last, mytime), "new time stamp from IOC [TSE = -2, no SIOL]");
|
||||
|
||||
/* Reset TSE */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Writing through SIOL link
|
||||
*/
|
||||
|
||||
static
|
||||
void testSiolWrite(const char *name,
|
||||
const epicsTimeStamp *mytime)
|
||||
{
|
||||
epicsTimeStamp now;
|
||||
|
||||
testDiag("## Writing through SIOL ##");
|
||||
|
||||
/* Set SIOL link to simval */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, nameSimval);
|
||||
|
||||
testDiag("in simmNO, SIOL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
if (strcmp(name, "mbboDirect") == 0)
|
||||
testdbPutFieldOk(nameB0, DBR_LONG, 1);
|
||||
else
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 1);
|
||||
|
||||
if (strcmp(name, "aao") == 0)
|
||||
testdbGetFieldEqual(nameSimvalNORD, DBR_USHORT, 0);
|
||||
else if (strcmp(name, "lso") == 0)
|
||||
testdbGetFieldEqual(nameSimvalLEN, DBR_USHORT, 0);
|
||||
else
|
||||
testdbGetFieldEqual(nameSimval, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SIOL is used to write VAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
if (strcmp(name, "mbboDirect") == 0)
|
||||
testdbPutFieldOk(nameB0, DBR_LONG, 1);
|
||||
else
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 1);
|
||||
testdbGetFieldEqual(nameSimval, DBR_USHORT, 1);
|
||||
|
||||
/* Set TSE to -2 (from device) and reprocess: timestamp is taken from IOC */
|
||||
epicsTimeGetCurrent(&now);
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, -2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "new time stamp from IOC [TSE = -2]");
|
||||
|
||||
/* Reset TSE */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous processing using simm:DELAY
|
||||
*/
|
||||
|
||||
static
|
||||
void testSimmDelay(const char *name,
|
||||
epicsFloat64 *psdly,
|
||||
const epicsTimeStamp *mytime)
|
||||
{
|
||||
epicsTimeStamp now;
|
||||
const double delay = 0.01; /* 10 ms */
|
||||
|
||||
testDiag("## Asynchronous processing with simm:DELAY ##");
|
||||
|
||||
/* Set delay to something just long enough */
|
||||
*psdly = delay;
|
||||
|
||||
/* Process in simmNO: synchronous */
|
||||
testDiag("simm:DELAY and simmNO processes synchronously");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
epicsTimeGetCurrent(&now);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "time stamp is recent");
|
||||
|
||||
/* Process in simmYES: asynchronous */
|
||||
testDiag("simm:DELAY and simmYES processes asynchronously");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 1);
|
||||
epicsTimeGetCurrent(&now);
|
||||
epicsThreadSleep(1.5*delay);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "time stamp taken from second pass processing");
|
||||
|
||||
/* Reset delay */
|
||||
*psdly = -1.;
|
||||
}
|
||||
|
||||
#define RUNALLTESTSREAD(type) \
|
||||
testDiag("################################################### Record Type " #type); \
|
||||
setNames(#type); \
|
||||
testSimmToggle(#type, &((type ## Record*)testdbRecordPtr(#type))->sscn); \
|
||||
testSvalRead(#type, &((type ## Record*)testdbRecordPtr(#type))->time, \
|
||||
&((type ## Record*)testdbRecordPtr(#type ":simval"))->time); \
|
||||
testSimmDelay(#type, &((type ## Record*)testdbRecordPtr(#type))->sdly, \
|
||||
&((type ## Record*)testdbRecordPtr(#type))->time)
|
||||
|
||||
#define RUNALLTESTSWRITE(type) \
|
||||
testDiag("################################################### Record Type " #type); \
|
||||
setNames(#type); \
|
||||
testSimmToggle(#type, &((type ## Record*)testdbRecordPtr(#type))->sscn); \
|
||||
testSiolWrite(#type, &((type ## Record*)testdbRecordPtr(#type))->time); \
|
||||
testSimmDelay(#type, &((type ## Record*)testdbRecordPtr(#type))->sdly, \
|
||||
&((type ## Record*)testdbRecordPtr(#type))->time)
|
||||
|
||||
static
|
||||
void testAllRecTypes(void)
|
||||
{
|
||||
RUNALLTESTSREAD(ai);
|
||||
RUNALLTESTSWRITE(ao);
|
||||
RUNALLTESTSREAD(aai);
|
||||
RUNALLTESTSWRITE(aao);
|
||||
RUNALLTESTSREAD(bi);
|
||||
RUNALLTESTSWRITE(bo);
|
||||
RUNALLTESTSREAD(mbbi);
|
||||
RUNALLTESTSWRITE(mbbo);
|
||||
RUNALLTESTSREAD(mbbiDirect);
|
||||
RUNALLTESTSWRITE(mbboDirect);
|
||||
RUNALLTESTSREAD(longin);
|
||||
RUNALLTESTSWRITE(longout);
|
||||
RUNALLTESTSREAD(int64in);
|
||||
RUNALLTESTSWRITE(int64out);
|
||||
RUNALLTESTSREAD(stringin);
|
||||
RUNALLTESTSWRITE(stringout);
|
||||
RUNALLTESTSREAD(lsi);
|
||||
RUNALLTESTSWRITE(lso);
|
||||
RUNALLTESTSREAD(event);
|
||||
RUNALLTESTSREAD(waveform);
|
||||
RUNALLTESTSREAD(histogram);
|
||||
}
|
||||
|
||||
|
||||
MAIN(simmTest)
|
||||
{
|
||||
testPlan(0);
|
||||
startSimmTestIoc("simmTest.db");
|
||||
|
||||
testSimmSetup();
|
||||
testAllRecTypes();
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
return testDone();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
file "simmTestSimple.template" {
|
||||
{ TYPE="ai" }
|
||||
{ TYPE="ao" }
|
||||
{ TYPE="bi" }
|
||||
{ TYPE="bo" }
|
||||
{ TYPE="mbbi" }
|
||||
{ TYPE="mbbo" }
|
||||
{ TYPE="mbbiDirect" }
|
||||
{ TYPE="mbboDirect" }
|
||||
{ TYPE="longin" }
|
||||
{ TYPE="longout" }
|
||||
{ TYPE="int64in" }
|
||||
{ TYPE="int64out" }
|
||||
{ TYPE="stringin" }
|
||||
{ TYPE="stringout" }
|
||||
{ TYPE="lsi" }
|
||||
{ TYPE="lso" }
|
||||
{ TYPE="event" }
|
||||
}
|
||||
file "simmTestArray.template" {
|
||||
{ TYPE="aai" }
|
||||
{ TYPE="aao" }
|
||||
{ TYPE="waveform" }
|
||||
}
|
||||
file "simmTestHistogram.template" {
|
||||
{ TYPE="histogram" }
|
||||
}
|
||||
file "simmSetup.db" {
|
||||
{}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# Array type records
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
field(FTVL,"SHORT")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record($(TYPE), "$(TYPE):simval") {
|
||||
field(FTVL,"SHORT")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
# Array type records
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record(ai, "$(TYPE):simval") {
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
}
|
||||
record($(TYPE), "$(TYPE):simval") {
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsString.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbFldTypes.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "errMdef.h"
|
||||
#include "recSup.h"
|
||||
#include "recGbl.h"
|
||||
#include "special.h"
|
||||
#include "cantProceed.h"
|
||||
#include "menuYesNo.h"
|
||||
|
||||
@@ -44,7 +46,7 @@
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *, int);
|
||||
static long process(struct dbCommon *);
|
||||
#define special NULL
|
||||
static long special(DBADDR *, int);
|
||||
#define get_value NULL
|
||||
static long cvt_dbaddr(DBADDR *);
|
||||
static long get_array_info(DBADDR *, long *, long *);
|
||||
@@ -95,7 +97,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
struct waveformRecord *prec = (struct waveformRecord *)pcommon;
|
||||
struct wfdset *pdset;
|
||||
|
||||
if (pass==0){
|
||||
if (pass == 0){
|
||||
if (prec->nelm <= 0)
|
||||
prec->nelm = 1;
|
||||
if (prec->ftvl > DBF_ENUM)
|
||||
@@ -110,7 +112,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have dset defined */
|
||||
if (!(pdset = (struct wfdset *)(prec->dset))) {
|
||||
@@ -144,9 +146,9 @@ static long process(struct dbCommon *pcommon)
|
||||
readValue(prec); /* read the new value */
|
||||
if (!pact && prec->pact) return 0;
|
||||
|
||||
prec->pact = TRUE;
|
||||
prec->udf = FALSE;
|
||||
recGblGetTimeStamp(prec);
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
monitor(prec);
|
||||
|
||||
@@ -157,6 +159,26 @@ static long process(struct dbCommon *pcommon)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *)(paddr->precord);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == waveformRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "waveform: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
static long cvt_dbaddr(DBADDR *paddr)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *) paddr->precord;
|
||||
@@ -304,43 +326,53 @@ static void monitor(waveformRecord *prec)
|
||||
|
||||
static long readValue(waveformRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct wfdset *pdset = (struct wfdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
return (*pdset->read_wf)(prec);
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO: {
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
status = (*pdset->read_wf)(prec);
|
||||
status = pdset->read_wf(prec);
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
return status;
|
||||
break;
|
||||
}
|
||||
|
||||
if (prec->simm == menuYesNoYES){
|
||||
case menuYesNoYES: {
|
||||
long nRequest = prec->nelm;
|
||||
|
||||
status = dbGetLink(&prec->siol, prec->ftvl, prec->bptr, 0, &nRequest);
|
||||
/* nord set only for db links: needed for old db_access */
|
||||
if (!dbLinkIsConstant(&prec->siol)) {
|
||||
prec->nord = nRequest;
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
if (status == 0)
|
||||
prec->udf=FALSE;
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, prec->ftvl, prec->bptr, 0, &nRequest);
|
||||
if (status == 0) prec->udf = FALSE;
|
||||
/* nord set only for db links: needed for old db_access */
|
||||
if (!dbLinkIsConstant(&prec->siol)) {
|
||||
prec->nord = nRequest;
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
} else {
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,26 +119,53 @@ recordtype(waveform) {
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Sim Input Specifctn")
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Sim Mode Location")
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Sim mode Alarm Svrty")
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("CALLBACK *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
|
||||
Reference in New Issue
Block a user