From c4d0f1eb449d104f1ef72cebbb9cefa76b788239 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 06:22:15 -0700 Subject: [PATCH 1/8] fixed simulation mode, buffer allocation during initialization, corruption of NELM --- src/rec/aaiRecord.c | 118 +++++++++++++++++++++++++++--------------- src/rec/aaiRecord.dbd | 5 ++ 2 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/rec/aaiRecord.c b/src/rec/aaiRecord.c index 008a4f3d5..63572b5f2 100644 --- a/src/rec/aaiRecord.c +++ b/src/rec/aaiRecord.c @@ -9,7 +9,6 @@ /* recAai.c - Record Support Routines for Array Analog In records */ /* * Original Author: Dave Barker - * Date: 10/24/93 * * C E B A F * @@ -18,6 +17,8 @@ * * Copyright SURA CEBAF 1993. * + * Current Author: Dirk Zimoch + * Date: 27-MAY-2010 */ #include @@ -30,12 +31,14 @@ #include "epicsPrint.h" #include "alarm.h" #include "dbAccess.h" -#include "dbScan.h" #include "dbEvent.h" +#include "dbFldTypes.h" +#include "dbScan.h" #include "devSup.h" #include "errMdef.h" #include "recSup.h" #include "recGbl.h" +#include "cantProceed.h" #include "menuYesNo.h" #define GEN_SIZE_OFFSET #include "aaiRecord.h" @@ -84,43 +87,67 @@ rset aaiRSET={ epicsExportAddress(rset,aaiRSET); struct aaidset { /* aai dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_aai; /*returns: (-1,0)=>(failure,success)*/ + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_aai; /*returns: (-1,0)=>(failure,success)*/ }; static void monitor(aaiRecord *); static long readValue(aaiRecord *); - static long init_record(aaiRecord *prec, int pass) { - struct aaidset *pdset; long status; + struct aaidset *pdset = (struct aaidset *)(prec->dset); - if (pass == 0) { - if (prec->nelm <= 0) prec->nelm = 1; - return 0; - } - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); /* must have dset defined */ - if (!(pdset = (struct aaidset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET, (void *)prec, "aai: init_record"); + if (!pdset) { + recGblRecordError(S_dev_noDSET, prec, "aai: init_record"); return S_dev_noDSET; } + + if (pass == 0) { + if (prec->nelm <= 0) + prec->nelm = 1; + if (prec->ftvl > DBF_ENUM) + prec->ftvl = DBF_UCHAR; + if (prec->nelm == 1) { + prec->nord = 1; + } else { + prec->nord = 0; + } + + /* we must call pdset->init_record in pass 0 + because it may set prec->bptr which must + not change after links are established before pass 1 + */ + + if (pdset->init_record) { + /* init_record may set the bptr to point to the data */ + if ((status = pdset->init_record(prec))) + return status; + } + if (!prec->bptr) { + /* device support did not allocate memory so we must do it */ + prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), + "aai: buffer calloc failed"); + } + return 0; + } + + /* 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); + } + /* must have read_aai function defined */ if (pdset->number < 5 || pdset->read_aai == NULL) { - recGblRecordError(S_dev_missingSup, (void *)prec, "aai: init_record"); + recGblRecordError(S_dev_missingSup, prec, "aai: init_record"); return S_dev_missingSup; } - if (pdset->init_record) { - /* init_record sets the bptr to point to the data */ - if ((status = pdset->init_record(prec))) - return status; - } return 0; } @@ -132,14 +159,13 @@ static long process(aaiRecord *prec) if (pdset == NULL || pdset->read_aai == NULL) { prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, (void *)prec, "read_aai"); + recGblRecordError(S_dev_missingSup, prec, "read_aai"); return S_dev_missingSup; } if (pact) return 0; status = readValue(prec); /* read the new value */ - /* check if device support set pact */ if (!pact && prec->pact) return 0; prec->pact = TRUE; @@ -151,7 +177,7 @@ static long process(aaiRecord *prec) recGblFwdLink(prec); prec->pact = FALSE; - return 0; + return status; } static long get_value(aaiRecord *prec, struct valueDes *pvdes) @@ -166,7 +192,7 @@ static long cvt_dbaddr(DBADDR *paddr) { aaiRecord *prec = (aaiRecord *)paddr->precord; - paddr->pfield = (void *)(prec->bptr); + paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); @@ -178,7 +204,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaiRecord *prec = (aaiRecord *)paddr->precord; - *no_elements = prec->nelm; + *no_elements = prec->nord; *offset = 0; return 0; } @@ -187,7 +213,9 @@ static long put_array_info(DBADDR *paddr, long nNew) { aaiRecord *prec = (aaiRecord *)paddr->precord; - prec->nelm = nNew; + prec->nord = nNew; + if (prec->nord > prec->nelm) + prec->nord = prec->nelm; return 0; } @@ -204,7 +232,7 @@ static long get_precision(DBADDR *paddr, long *precision) aaiRecord *prec = (aaiRecord *)paddr->precord; *precision = prec->prec; - if (paddr->pfield == (void *)prec->bptr) return 0; + if (paddr->pfield == prec->bptr) return 0; recGblGetPrec(paddr, precision); return 0; } @@ -213,7 +241,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) { aaiRecord *prec = (aaiRecord *)paddr->precord; - if (paddr->pfield == (void *)prec->bptr) { + if (paddr->pfield == prec->bptr) { pgd->upper_disp_limit = prec->hopr; pgd->lower_disp_limit = prec->lopr; } else recGblGetGraphicDouble(paddr, pgd); @@ -224,7 +252,7 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) { aaiRecord *prec = (aaiRecord *)paddr->precord; - if (paddr->pfield == (void *)prec->bptr) { + if (paddr->pfield == prec->bptr) { pcd->upper_ctrl_limit = prec->hopr; pcd->lower_ctrl_limit = prec->lopr; } else recGblGetControlDouble(paddr, pcd); @@ -253,21 +281,25 @@ static long readValue(aaiRecord *prec) status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); if (status) - return(status); + return status; if (prec->simm == menuYesNoNO){ - /* Call dev support */ - status = pdset->read_aai(prec); - return status; + return pdset->read_aai(prec); } + if (prec->simm == menuYesNoYES){ - /* Simm processing split performed in devSup */ - /* Call dev support */ - status = pdset->read_aai(prec); - return status; + /* 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. + */ + recGblSetSevr(prec, SIMM_ALARM, prec->sims); + return pdset->read_aai(prec); } - status = -1; - recGblSetSevr(prec, SIMM_ALARM, INVALID_ALARM); - return status; + + recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); + return -1; } diff --git a/src/rec/aaiRecord.dbd b/src/rec/aaiRecord.dbd index b7b84f66e..ea2e107ed 100644 --- a/src/rec/aaiRecord.dbd +++ b/src/rec/aaiRecord.dbd @@ -82,4 +82,9 @@ recordtype(aai) { interest(2) menu(menuAlarmSevr) } + field(SIOL,DBF_INLINK) { + prompt("Sim Input Specifctn") + promptgroup(GUI_INPUTS) + interest(1) + } } From f6035fd823319c668681baf4c35e79e2764a4d05 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 06:22:35 -0700 Subject: [PATCH 2/8] fixed simulation mode, buffer allocation during initialization, corruption of NELM --- src/rec/aaoRecord.c | 112 +++++++++++++++++++++++++++--------------- src/rec/aaoRecord.dbd | 5 ++ 2 files changed, 78 insertions(+), 39 deletions(-) diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c index 954df058f..a1a24a302 100644 --- a/src/rec/aaoRecord.c +++ b/src/rec/aaoRecord.c @@ -9,7 +9,6 @@ /* recAao.c - Record Support Routines for Array Analog Out records */ /* * Original Author: Dave Barker - * Date: 10/28/93 * * C E B A F * @@ -18,6 +17,8 @@ * * Copyright SURA CEBAF 1993. * + * Current Author: Dirk Zimoch + * Date: 27-MAY-2010 */ #include @@ -30,12 +31,14 @@ #include "epicsPrint.h" #include "alarm.h" #include "dbAccess.h" +#include "dbEvent.h" #include "dbFldTypes.h" #include "dbScan.h" -#include "dbEvent.h" #include "devSup.h" +#include "errMdef.h" #include "recSup.h" #include "recGbl.h" +#include "cantProceed.h" #include "menuYesNo.h" #define GEN_SIZE_OFFSET #include "aaoRecord.h" @@ -84,43 +87,67 @@ rset aaoRSET={ epicsExportAddress(rset,aaoRSET); struct aaodset { /* aao dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_aao; /*returns: (-1,0)=>(failure,success)*/ + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_aao; /*returns: (-1,0)=>(failure,success)*/ }; static void monitor(aaoRecord *); static long writeValue(aaoRecord *); - static long init_record(aaoRecord *prec, int pass) { - struct aaodset *pdset; long status; + struct aaodset *pdset = (struct aaodset *)(prec->dset); - if (pass == 0) { - if (prec->nelm <= 0) prec->nelm = 1; - return 0; - } - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); /* must have dset defined */ - if (!(pdset = (struct aaodset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET, (void *)prec, "aao: init_record"); + if (!pdset) { + recGblRecordError(S_dev_noDSET, prec, "aao: init_record"); return S_dev_noDSET; } + + if (pass == 0) { + if (prec->nelm <= 0) + prec->nelm = 1; + if (prec->ftvl > DBF_ENUM) + prec->ftvl = DBF_UCHAR; + if (prec->nelm == 1) { + prec->nord = 1; + } else { + prec->nord = 0; + } + + /* we must call pdset->init_record in pass 0 + because it may set prec->bptr which must + not change after links are established before pass 1 + */ + + if (pdset->init_record) { + /* init_record may set the bptr to point to the data */ + if ((status = pdset->init_record(prec))) + return status; + } + if (!prec->bptr) { + /* device support did not allocate memory so we must do it */ + prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), + "aao: buffer calloc failed"); + } + return 0; + } + + /* 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); + } + /* must have write_aao function defined */ if (pdset->number < 5 || pdset->write_aao == NULL) { - recGblRecordError(S_dev_missingSup, (void *)prec, "aao: init_record"); + recGblRecordError(S_dev_missingSup, prec, "aao: init_record"); return S_dev_missingSup; } - if (pdset->init_record) { - /* init records sets the bptr to point to the data */ - if ((status = pdset->init_record(prec))) - return status; - } return 0; } @@ -132,13 +159,15 @@ static long process(aaoRecord *prec) if (pdset == NULL || pdset->write_aao == NULL) { prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, (void *)prec, "write_aao"); + recGblRecordError(S_dev_missingSup, prec, "write_aao"); return S_dev_missingSup; } if (pact) return 0; status = writeValue(prec); /* write the data */ + if (!pact && prec->pact) return 0; + prec->pact = TRUE; prec->udf = FALSE; recGblGetTimeStamp(prec); @@ -148,7 +177,7 @@ static long process(aaoRecord *prec) recGblFwdLink(prec); prec->pact = FALSE; - return 0; + return status; } static long get_value(aaoRecord *prec, struct valueDes *pvdes) @@ -163,7 +192,7 @@ static long cvt_dbaddr(DBADDR *paddr) { aaoRecord *prec = (aaoRecord *)paddr->precord; - paddr->pfield = (void *)(prec->bptr); + paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); @@ -175,7 +204,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaoRecord *prec = (aaoRecord *)paddr->precord; - *no_elements = prec->nelm; + *no_elements = prec->nord; *offset = 0; return 0; } @@ -184,7 +213,9 @@ static long put_array_info(DBADDR *paddr, long nNew) { aaoRecord *prec = (aaoRecord *)paddr->precord; - prec->nelm = nNew; + prec->nord = nNew; + if (prec->nord > prec->nelm) + prec->nord = prec->nelm; return 0; } @@ -210,7 +241,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) { aaoRecord *prec = (aaoRecord *)paddr->precord; - if (paddr->pfield == (void *)prec->bptr) { + if (paddr->pfield == prec->bptr) { pgd->upper_disp_limit = prec->hopr; pgd->lower_disp_limit = prec->lopr; } else recGblGetGraphicDouble(paddr,pgd); @@ -221,7 +252,7 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) { aaoRecord *prec = (aaoRecord *)paddr->precord; - if(paddr->pfield==(void *)prec->bptr){ + if(paddr->pfield == prec->bptr){ pcd->upper_ctrl_limit = prec->hopr; pcd->lower_ctrl_limit = prec->lopr; } else recGblGetControlDouble(paddr,pcd); @@ -253,17 +284,20 @@ static long writeValue(aaoRecord *prec) return status; if (prec->simm == menuYesNoNO) { - /* Call dev support */ - status = pdset->write_aao(prec); - return status; + return pdset->write_aao(prec); } if (prec->simm == menuYesNoYES) { - /* Call dev support */ - status = pdset->write_aao(prec); - return status; + /* 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. + */ + recGblSetSevr(prec, SIMM_ALARM, INVALID_ALARM); + return pdset->write_aao(prec); } - status = -1; - recGblSetSevr(prec, SIMM_ALARM, INVALID_ALARM); - return status; + recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); + return -1; } diff --git a/src/rec/aaoRecord.dbd b/src/rec/aaoRecord.dbd index 1952f8f5b..ad29fb648 100644 --- a/src/rec/aaoRecord.dbd +++ b/src/rec/aaoRecord.dbd @@ -82,4 +82,9 @@ recordtype(aao) { interest(2) menu(menuAlarmSevr) } + field(SIOL,DBF_OUTLINK) { + prompt("Sim Output Specifctn") + promptgroup(GUI_INPUTS) + interest(1) + } } From dd04abbc1c3dde3cb86b580a383e78b4e0a57c04 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 06:23:07 -0700 Subject: [PATCH 3/8] added aai/aao soft support --- src/dev/softDev/Makefile | 2 + src/dev/softDev/devAaiSoft.c | 87 ++++++++++++++++++++++++++++++++++++ src/dev/softDev/devAaoSoft.c | 82 +++++++++++++++++++++++++++++++++ src/dev/softDev/devSoft.dbd | 2 + src/misc/base.dbd | 2 + 5 files changed, 175 insertions(+) create mode 100644 src/dev/softDev/devAaiSoft.c create mode 100644 src/dev/softDev/devAaoSoft.c diff --git a/src/dev/softDev/Makefile b/src/dev/softDev/Makefile index d3a475011..6c4f11cb0 100644 --- a/src/dev/softDev/Makefile +++ b/src/dev/softDev/Makefile @@ -12,6 +12,8 @@ include $(TOP)/configure/CONFIG DBD += devSoft.dbd +LIBSRCS += devAaiSoft.c +LIBSRCS += devAaoSoft.c LIBSRCS += devAiSoft.c LIBSRCS += devAiSoftRaw.c LIBSRCS += devAoSoft.c diff --git a/src/dev/softDev/devAaiSoft.c b/src/dev/softDev/devAaiSoft.c new file mode 100644 index 000000000..06f62b5d9 --- /dev/null +++ b/src/dev/softDev/devAaiSoft.c @@ -0,0 +1,87 @@ +/*************************************************************************\ +* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* $Id$ + * devAaiSoft.c - Device Support Routines for soft Waveform Records + * + * Original Author: Bob Dalesio + * Current Author: Dirk Zimoch + * Date: 27-MAY-2010 + */ + +#include +#include +#include + +#include "alarm.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "recGbl.h" +#include "devSup.h" +#include "cantProceed.h" +#include "menuYesNo.h" +#include "aaiRecord.h" +#include "epicsExport.h" + +/* Create the dset for devAaiSoft */ +static long init_record(); +static long read_aai(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_aai; +} devAaiSoft = { + 5, + NULL, + NULL, + init_record, + NULL, + read_aai +}; +epicsExportAddress(dset,devAaiSoft); + +static long init_record(aaiRecord *prec) +{ + /* INP must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (prec->inp.type) { + case CONSTANT: + prec->nord = 0; + break; + case PV_LINK: + case DB_LINK: + case CA_LINK: + break; + default : + recGblRecordError(S_db_badField, (void *)prec, + "devAaiSoft (init_record) Illegal INP field"); + return(S_db_badField); + } + return 0; +} + +static long read_aai(aaiRecord *prec) +{ + long nRequest = prec->nelm; + + dbGetLink(prec->simm == menuYesNoYES ? &prec->siol : &prec->inp, + prec->ftvl, prec->bptr, 0, &nRequest); + if (nRequest > 0) { + prec->nord = nRequest; + prec->udf=FALSE; + if (prec->tsel.type == CONSTANT && + prec->tse == epicsTimeEventDeviceTime) + dbGetTimeStamp(&prec->inp, &prec->time); + } + + return 0; +} diff --git a/src/dev/softDev/devAaoSoft.c b/src/dev/softDev/devAaoSoft.c new file mode 100644 index 000000000..54263b4ca --- /dev/null +++ b/src/dev/softDev/devAaoSoft.c @@ -0,0 +1,82 @@ +/*************************************************************************\ +* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* $Id$ + * devAaoSoft.c - Device Support Routines for soft Waveform Records + * + * Original Author: Bob Dalesio + * Current Author: Dirk Zimoch + * Date: 27-MAY-2010 + */ + +#include +#include +#include + +#include "alarm.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "recGbl.h" +#include "devSup.h" +#include "cantProceed.h" +#include "menuYesNo.h" +#include "aaoRecord.h" +#include "epicsExport.h" + +/* Create the dset for devAaoSoft */ +static long init_record(); +static long write_aao(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_aao; +} devAaoSoft = { + 5, + NULL, + NULL, + init_record, + NULL, + write_aao +}; +epicsExportAddress(dset,devAaoSoft); + +static long init_record(aaoRecord *prec) +{ + /* OUT must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (prec->out.type) { + case CONSTANT: + prec->nord = 0; + break; + case PV_LINK: + case DB_LINK: + case CA_LINK: + break; + default : + recGblRecordError(S_db_badField, prec, + "devAaoSoft (init_record) Illegal OUT field"); + return(S_db_badField); + } + return 0; +} + +static long write_aao(aaoRecord *prec) +{ + long nRequest = prec->nelm; + dbPutLink(prec->simm == menuYesNoYES ? &prec->siol : &prec->out, + prec->ftvl, prec->bptr, nRequest); + if (nRequest>0) { + prec->nord = nRequest; + } + + return 0; +} diff --git a/src/dev/softDev/devSoft.dbd b/src/dev/softDev/devSoft.dbd index 28d235730..763ac47d5 100644 --- a/src/dev/softDev/devSoft.dbd +++ b/src/dev/softDev/devSoft.dbd @@ -1,3 +1,5 @@ +device(aai,CONSTANT,devAaiSoft,"Soft Channel") +device(aao,CONSTANT,devAaoSoft,"Soft Channel") device(ai,CONSTANT,devAiSoft,"Soft Channel") device(ao,CONSTANT,devAoSoft,"Soft Channel") device(bi,CONSTANT,devBiSoft,"Soft Channel") diff --git a/src/misc/base.dbd b/src/misc/base.dbd index 03408dbed..b7ea298e6 100644 --- a/src/misc/base.dbd +++ b/src/misc/base.dbd @@ -8,6 +8,8 @@ include "menuGlobal.dbd" include "menuConvert.dbd" # Record types +include "aaiRecord.dbd" +include "aaoRecord.dbd" include "aiRecord.dbd" include "aoRecord.dbd" include "aSubRecord.dbd" From 1691de69ba05a39abbeff418db67f5052e9b233f Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 07:44:03 -0700 Subject: [PATCH 4/8] NORD/NELM issues fixed --- src/dev/softDev/devAaoSoft.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dev/softDev/devAaoSoft.c b/src/dev/softDev/devAaoSoft.c index 54263b4ca..7f040d39e 100644 --- a/src/dev/softDev/devAaoSoft.c +++ b/src/dev/softDev/devAaoSoft.c @@ -71,12 +71,9 @@ static long init_record(aaoRecord *prec) static long write_aao(aaoRecord *prec) { - long nRequest = prec->nelm; + long nRequest = prec->nord; dbPutLink(prec->simm == menuYesNoYES ? &prec->siol : &prec->out, prec->ftvl, prec->bptr, nRequest); - if (nRequest>0) { - prec->nord = nRequest; - } return 0; } From 6960d4e5a4fa92d42e2e865a51475776d681b7a5 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 07:45:21 -0700 Subject: [PATCH 5/8] hash based value change monitor added (like in waveform) --- src/rec/aaiRecord.c | 39 +++++++++++++++++++++++++++++---------- src/rec/aaiRecord.dbd | 20 ++++++++++++++++++++ src/rec/aaoRecord.c | 42 ++++++++++++++++++++++++++++++++---------- src/rec/aaoRecord.dbd | 20 ++++++++++++++++++++ 4 files changed, 101 insertions(+), 20 deletions(-) diff --git a/src/rec/aaiRecord.c b/src/rec/aaiRecord.c index 63572b5f2..050271054 100644 --- a/src/rec/aaiRecord.c +++ b/src/rec/aaiRecord.c @@ -29,6 +29,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsString.h" #include "alarm.h" #include "dbAccess.h" #include "dbEvent.h" @@ -51,7 +52,7 @@ static long init_record(aaiRecord *, int); static long process(aaiRecord *); #define special NULL -static long get_value(aaiRecord *, struct valueDes *); +#define get_value NULL static long cvt_dbaddr(DBADDR *); static long get_array_info(DBADDR *, long *, long *); static long put_array_info(DBADDR *, long); @@ -180,14 +181,6 @@ static long process(aaiRecord *prec) return status; } -static long get_value(aaiRecord *prec, struct valueDes *pvdes) -{ - pvdes->no_elements = prec->nelm; - pvdes->pvalue = prec->bptr; - pvdes->field_type = prec->ftvl; - return 0; -} - static long cvt_dbaddr(DBADDR *paddr) { aaiRecord *prec = (aaiRecord *)paddr->precord; @@ -262,9 +255,35 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) static void monitor(aaiRecord *prec) { unsigned short monitor_mask; + unsigned int hash = 0; monitor_mask = recGblResetAlarms(prec); - monitor_mask |= (DBE_LOG | DBE_VALUE); + + if (prec->mpst == aaiPOST_Always) + monitor_mask |= DBE_VALUE; + if (prec->apst == aaiPOST_Always) + monitor_mask |= DBE_LOG; + + /* Calculate hash if we are interested in OnChange events. */ + if ((prec->mpst == aaiPOST_OnChange) || + (prec->apst == aaiPOST_OnChange)) { + hash = epicsMemHash(prec->bptr, + prec->nord * dbValueSize(prec->ftvl), 0); + + /* Only post OnChange values if the hash is different. */ + if (hash != prec->hash) { + if (prec->mpst == aaiPOST_OnChange) + monitor_mask |= DBE_VALUE; + if (prec->apst == aaiPOST_OnChange) + monitor_mask |= DBE_LOG; + + /* Store hash for next process. */ + prec->hash = hash; + /* Post HASH. */ + db_post_events(prec, &prec->hash, DBE_VALUE); + } + } + if (monitor_mask) db_post_events(prec, prec->bptr, monitor_mask); } diff --git a/src/rec/aaiRecord.dbd b/src/rec/aaiRecord.dbd index ea2e107ed..e94fecbac 100644 --- a/src/rec/aaiRecord.dbd +++ b/src/rec/aaiRecord.dbd @@ -7,6 +7,10 @@ # and higher are distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. #************************************************************************* +menu(aaiPOST) { + choice(aaiPOST_Always,"Always") + choice(aaiPOST_OnChange,"On Change") +} recordtype(aai) { include "dbCommon.dbd" field(VAL,DBF_NOACCESS) { @@ -87,4 +91,20 @@ recordtype(aai) { promptgroup(GUI_INPUTS) interest(1) } + field(MPST,DBF_MENU) { + prompt("Post Value Monitors") + promptgroup(GUI_DISPLAY) + interest(1) + menu(aaiPOST) + } + field(APST,DBF_MENU) { + prompt("Post Archive Monitors") + promptgroup(GUI_DISPLAY) + interest(1) + menu(aaiPOST) + } + field(HASH,DBF_ULONG) { + prompt("Hash of OnChange data.") + interest(3) + } } diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c index a1a24a302..8a97c7274 100644 --- a/src/rec/aaoRecord.c +++ b/src/rec/aaoRecord.c @@ -29,6 +29,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsString.h" #include "alarm.h" #include "dbAccess.h" #include "dbEvent.h" @@ -51,7 +52,7 @@ static long init_record(aaoRecord *, int); static long process(aaoRecord *); #define special NULL -static long get_value(aaoRecord *, struct valueDes *); +#define get_value NULL static long cvt_dbaddr(DBADDR *); static long get_array_info(DBADDR *, long *, long *); static long put_array_info(DBADDR *, long); @@ -180,18 +181,11 @@ static long process(aaoRecord *prec) return status; } -static long get_value(aaoRecord *prec, struct valueDes *pvdes) -{ - pvdes->no_elements = prec->nelm; - pvdes->pvalue = prec->bptr; - pvdes->field_type = prec->ftvl; - return 0; -} - static long cvt_dbaddr(DBADDR *paddr) { aaoRecord *prec = (aaoRecord *)paddr->precord; + printf("cvt_dbaddr\n"); paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; @@ -204,6 +198,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaoRecord *prec = (aaoRecord *)paddr->precord; + printf("get_array_info\n"); *no_elements = prec->nord; *offset = 0; return 0; @@ -213,6 +208,7 @@ static long put_array_info(DBADDR *paddr, long nNew) { aaoRecord *prec = (aaoRecord *)paddr->precord; + printf("put_array_info\n"); prec->nord = nNew; if (prec->nord > prec->nelm) prec->nord = prec->nelm; @@ -262,9 +258,35 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) static void monitor(aaoRecord *prec) { unsigned short monitor_mask; + unsigned int hash = 0; monitor_mask = recGblResetAlarms(prec); - monitor_mask |= (DBE_LOG | DBE_VALUE); + + if (prec->mpst == aaoPOST_Always) + monitor_mask |= DBE_VALUE; + if (prec->apst == aaoPOST_Always) + monitor_mask |= DBE_LOG; + + /* Calculate hash if we are interested in OnChange events. */ + if ((prec->mpst == aaoPOST_OnChange) || + (prec->apst == aaoPOST_OnChange)) { + hash = epicsMemHash(prec->bptr, + prec->nord * dbValueSize(prec->ftvl), 0); + + /* Only post OnChange values if the hash is different. */ + if (hash != prec->hash) { + if (prec->mpst == aaoPOST_OnChange) + monitor_mask |= DBE_VALUE; + if (prec->apst == aaoPOST_OnChange) + monitor_mask |= DBE_LOG; + + /* Store hash for next process. */ + prec->hash = hash; + /* Post HASH. */ + db_post_events(prec, &prec->hash, DBE_VALUE); + } + } + if (monitor_mask) db_post_events(prec, prec->bptr, monitor_mask); } diff --git a/src/rec/aaoRecord.dbd b/src/rec/aaoRecord.dbd index ad29fb648..60b9b773e 100644 --- a/src/rec/aaoRecord.dbd +++ b/src/rec/aaoRecord.dbd @@ -7,6 +7,10 @@ # and higher are distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. #************************************************************************* +menu(aaoPOST) { + choice(aaoPOST_Always,"Always") + choice(aaoPOST_OnChange,"On Change") +} recordtype(aao) { include "dbCommon.dbd" field(VAL,DBF_NOACCESS) { @@ -87,4 +91,20 @@ recordtype(aao) { promptgroup(GUI_INPUTS) interest(1) } + field(MPST,DBF_MENU) { + prompt("Post Value Monitors") + promptgroup(GUI_DISPLAY) + interest(1) + menu(aaoPOST) + } + field(APST,DBF_MENU) { + prompt("Post Archive Monitors") + promptgroup(GUI_DISPLAY) + interest(1) + menu(aaoPOST) + } + field(HASH,DBF_ULONG) { + prompt("Hash of OnChange data.") + interest(3) + } } From 87081ed7e30f01b93972bc1ea2d33e280b1a29ef Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 27 May 2010 08:31:13 -0700 Subject: [PATCH 6/8] removed temporary debug messages --- src/rec/aaoRecord.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c index 8a97c7274..33ba5a278 100644 --- a/src/rec/aaoRecord.c +++ b/src/rec/aaoRecord.c @@ -185,7 +185,6 @@ static long cvt_dbaddr(DBADDR *paddr) { aaoRecord *prec = (aaoRecord *)paddr->precord; - printf("cvt_dbaddr\n"); paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; @@ -198,7 +197,6 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaoRecord *prec = (aaoRecord *)paddr->precord; - printf("get_array_info\n"); *no_elements = prec->nord; *offset = 0; return 0; @@ -208,7 +206,6 @@ static long put_array_info(DBADDR *paddr, long nNew) { aaoRecord *prec = (aaoRecord *)paddr->precord; - printf("put_array_info\n"); prec->nord = nNew; if (prec->nord > prec->nelm) prec->nord = prec->nelm; From 595345a80fe0d84be0a4a635e16a50ba93ce1b02 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Fri, 28 May 2010 02:59:16 -0700 Subject: [PATCH 7/8] release notes updated --- documentation/RELEASE_NOTES.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9b3ce378e..8f0e4dfe0 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -11,6 +11,13 @@

Changes between 3.14.11 and 3.14.12

+

Record Types aai and aao

+

Fixed bug in memory allocation that caused crashes when linking other records +to aai or aao. +Fixed bug where NELM was modified instead of NORD. +Added Soft Channel device support. +Added SIOL link and proper simulation mode for Soft Channel support. +Added MPST, APST and HASH fields for monitor on change support like in waveform record.

Rewrite epicsThreadOnce()

From 7f7bc289f3f73a3ece5b009eaadbdb0ec6b6ee83 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 7 Jul 2010 19:20:01 +0200 Subject: [PATCH 8/8] Bugfix: use SIMS for simulation severity --- src/rec/aaoRecord.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c index 33ba5a278..1837618e4 100644 --- a/src/rec/aaoRecord.c +++ b/src/rec/aaoRecord.c @@ -313,7 +313,7 @@ static long writeValue(aaoRecord *prec) simulation mode. Thus call device now. */ - recGblSetSevr(prec, SIMM_ALARM, INVALID_ALARM); + recGblSetSevr(prec, SIMM_ALARM, prec->sims); return pdset->write_aao(prec); } recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);