Merge branch 'impr-sim-mode-2' into 3.17

This commit is contained in:
Andrew Johnson
2017-11-02 16:37:42 -05:00
54 changed files with 2486 additions and 736 deletions
+12
View File
@@ -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
View File
@@ -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;
}
+9
View File
@@ -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
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+29 -2
View File
@@ -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
View File
@@ -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;
}
+30 -3
View File
@@ -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
View File
@@ -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;
}
+31 -4
View File
@@ -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
View File
@@ -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;
}
+32 -5
View File
@@ -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
View File
@@ -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;
}
+31 -4
View File
@@ -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")
}
}
+41 -22
View File
@@ -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;
}
+32 -5
View File
@@ -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
View File
@@ -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;
}
+30 -3
View File
@@ -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
+61 -29
View File
@@ -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)
+30 -3
View File
@@ -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
View File
@@ -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;
}
+31 -4
View File
@@ -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
View File
@@ -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)
+32 -5
View File
@@ -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
View File
@@ -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
+30 -3
View File
@@ -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
View File
@@ -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);
+30 -3
View File
@@ -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")
}
}
+56 -29
View File
@@ -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;
}
+30 -3
View File
@@ -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
View File
@@ -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;
}
+30 -3
View File
@@ -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")
}
}
+40 -15
View File
@@ -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;
}
+30 -3
View File
@@ -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
View File
@@ -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;
}
+32 -5
View File
@@ -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)
+63 -33
View File
@@ -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;
}
+31 -4
View File
@@ -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")
}
}
+60 -30
View File
@@ -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;
}
+31 -4
View File
@@ -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)
+13
View File
@@ -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
+3
View File
@@ -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 */
}
+16
View File
@@ -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")
}
+468
View File
@@ -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();
}
+30
View File
@@ -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" {
{}
}
+15
View File
@@ -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")
}
+10
View File
@@ -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")
}
+60 -28
View File
@@ -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;
}
+30 -3
View File
@@ -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")