From d0f7d4850b6ac124386ef5bed806af388bf7e2ca Mon Sep 17 00:00:00 2001 From: "Janet B. Anderson" Date: Thu, 24 Oct 1991 17:08:55 +0000 Subject: [PATCH] new record --- src/rec/recHistogram.c | 457 +++++++++++++++++++++++++---------------- 1 file changed, 279 insertions(+), 178 deletions(-) diff --git a/src/rec/recHistogram.c b/src/rec/recHistogram.c index 3a1eb83af..0025ae020 100644 --- a/src/rec/recHistogram.c +++ b/src/rec/recHistogram.c @@ -1,10 +1,10 @@ /* recHistogram.c */ /* share/src/rec $Id$ */ - + /* recHistogram.c - Record Support Routines for Histogram records */ /* - * Author: Janet Anderson - * Date: 5/20/91 + * Author: Janet Anderson + * Date: 5/20/91 * * Experimental Physics and Industrial Control System (EPICS) * @@ -29,28 +29,28 @@ * * Modification Log: * ----------------- - * .01 mm-dd-yy iii Comment + * .01 10-14-91 jba Added dev sup crtl fld and wd timer */ +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Create RSET - Record Support Entry Table*/ #define report NULL @@ -72,192 +72,249 @@ long get_array_info(); #define get_alarm_double NULL struct rset histogramRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double }; + RSETNUMBER, + report, + initialize, + init_record, + process, + special, + get_value, + cvt_dbaddr, + get_array_info, + put_array_info, + get_units, + get_precision, + get_enum_str, + get_enum_strs, + put_enum_str, + get_graphic_double, + get_control_double, + get_alarm_double }; +struct histogramdset { /* histogram input dset */ + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_histogram;/*(0,1,2)=> success and */ + /*(add_count,don't continue, don't add_count)*/ + /* if add_count then sgnl added to array */ + DEVSUPFUN special_linconv; +}; + +/* control block for callback*/ +struct callback { + void (*callback)(); + int priority; + struct dbAddr dbAddr; + WDOG_ID wd_id; + void (*process)(); +}; + +void callbackRequest(); void monitor(); +void convert(); +long add_count(); +long clear_histogram(); + +static void wdCallback(pcallback) + struct callback *pcallback; +{ + struct histogramRecord *phistogram=(struct histogramRecord *)(pcallback->dbAddr.precord); + float wait_time; + + /* force post events for any count change */ + if(phistogram->mcnt>0){ + dbScanLock(phistogram); + tsLocalTime(&phistogram->time); + db_post_events(phistogram,&phistogram->bptr,DBE_VALUE); + phistogram->mcnt=0; + dbScanUnlock(phistogram); + } + + if(phistogram->sdel>0) { + /* start new watchdog timer on monitor */ + wait_time = (float)(phistogram->sdel * vxTicksPerSecond); + wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); + } + + return; +} -static long put_count(phistogram) - struct histogramRecord *phistogram; -{ - double width,temp; - unsigned long *pdest; - int i; - - if(phistogram->llim >= phistogram->ulim) { - if (phistogram->nsevstat = SOFT_ALARM; - phistogram->sevr = VALID_ALARM; - return(-1); - } - } - if(phistogram->sgnlllim || phistogram->sgnl >= phistogram->ulim) return(0); - width=(phistogram->ulim-phistogram->llim)/phistogram->nelm; - temp=phistogram->sgnl-phistogram->llim; - for (i=1;i<=phistogram->nelm;i++){ - if (temp<=(double)i*width) break; - } - pdest=phistogram->bptr+i-1; - if ( *pdest==ULONG_MAX) *pdest=0.0; - /*if ( *pdest==4294967294) *pdest=0.0; */ - (*pdest)++; - phistogram->mcnt++; - return(0); -} -static long init_histogram(phistogram) - struct histogramRecord *phistogram; -{ - int i; - for (i=0;i<=phistogram->nelm-1;i++) - *(phistogram->bptr+i)=0.0; - phistogram->init=0; - phistogram->mcnt=phistogram->mdel; - return(0); -} static long init_record(phistogram) - struct histogramRecord *phistogram; + struct histogramRecord *phistogram; { - struct histogramdset *pdset; - long status; + struct histogramdset *pdset; + long status; + struct callback *pcallback=(struct callback *)(phistogram->wdog); + float wait_time; + void (*process)(); - /* allocate space for array */ - /* This routine may get called twice. Once by cvt_dbaddr. Once by iocInit*/ - if(phistogram->bptr==NULL) { - if(phistogram->nelm<=0) phistogram->nelm=1; - phistogram->bptr = (unsigned long *)calloc(phistogram->nelm,sizeof(long)); - } - /* this initialization may not be necessary*/ - /* initialize the array */ - init_histogram(phistogram); + /* This routine may get called twice. Once by cvt_dbaddr. Once by iocInit*/ - phistogram->udf = FALSE; + if(phistogram->wdog==NULL && phistogram->sdel!=0) { + /* initialize a watchdog timer */ + pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); + phistogram->wdog = (caddr_t)pcallback; + pcallback->callback = wdCallback; + pcallback->priority = priorityLow; + if(dbNameToAddr(phistogram->name,&(pcallback->dbAddr))) { + logMsg("dbNameToAddr failed in init_record for recHistogram\n"); + exit(1); + } + pcallback->wd_id = wdCreate(); + pcallback->process = process; + + /* start new watchdog timer on monitor */ + wait_time = (float)(phistogram->sdel * vxTicksPerSecond); + wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); + } - /* initialize the array element number if CONSTANT and nonzero */ - if (phistogram->svl.type == CONSTANT && phistogram->svl.value.value != 0.){ - phistogram->sgnl = phistogram->svl.value.value; + /* allocate space for histogram array */ + if(phistogram->bptr==NULL) { + if(phistogram->nelm<=0) phistogram->nelm=1; + phistogram->bptr = (unsigned long *)calloc(phistogram->nelm,sizeof(long)); + } - /* increment frequency in array */ - put_count(phistogram); - } - return(0); + /* calulate width of array element */ + phistogram->wdth=(phistogram->ulim-phistogram->llim)/phistogram->nelm; + + if(!(pdset = (struct histogramdset *)(phistogram->dset))) { + recGblRecordError(S_dev_noDSET,phistogram,"histogram: init_record"); + return(S_dev_noDSET); + } + /* must have read_histogram function defined */ + if( (pdset->number < 6) || (pdset->read_histogram == NULL) ) { + recGblRecordError(S_dev_missingSup,phistogram,"histogram: init_record"); + return(S_dev_missingSup); + } + + /* call device support init_record */ + if( pdset->init_record ) { + if((status=(*pdset->init_record)(phistogram,process))) return(status); + } + return(0); } static long process(paddr) - struct dbAddr *paddr; + struct dbAddr *paddr; { - struct histogramRecord *phistogram=(struct histogramRecord *)(paddr->precord); - struct histogramdset *pdset = (struct histogramdset *)(phistogram->dset); - long status=0; - long options=0; - long nRequest=1; + struct histogramRecord *phistogram=(struct histogramRecord *)(paddr->precord); + struct histogramdset *pdset = (struct histogramdset *)(phistogram->dset); + long status; - phistogram->pact = TRUE; + if( (pdset==NULL) || (pdset->read_histogram==NULL) ) { + phistogram->pact=TRUE; + recGblRecordError(S_dev_missingSup,phistogram,"read_histogram"); + return(S_dev_missingSup); + } - /* fetch the array element number */ - if(phistogram->svl.type == DB_LINK){ - status=dbGetLink(&(phistogram->svl.value.db_link),phistogram,DBR_DOUBLE, - &(phistogram->sgnl),&options,&nRequest); - if(status!=0) { - if (phistogram->nsevstat = READ_ALARM; - phistogram->sevr = VALID_ALARM; - } - } - } - /* increment frequency in histogram array */ - if(status==0) put_count(phistogram); + /*pact must not be set true until read_histogram is called*/ + status=(*pdset->read_histogram)(phistogram); + phistogram->pact = TRUE; - tsLocalTime(&phistogram->time); + /* status is one if an asynchronous record is being processed*/ + if (status==1) return(0); - /* check event list */ - monitor(phistogram); + tsLocalTime(&phistogram->time); - /* process the forward scan link record */ - if (phistogram->flnk.type==DB_LINK) dbScanPassive(phistogram->flnk.value.db_link.pdbAddr); + if(status==0)add_count(phistogram); + else if(status==2)status=0; - phistogram->pact=FALSE; - return(0); + /* check event list */ + monitor(phistogram); + + /* process the forward scan link record */ + if (phistogram->flnk.type==DB_LINK) dbScanPassive(phistogram->flnk.value.db_link.pdbAddr); + + phistogram->pact=FALSE; + return(status); } static long special(paddr,after) - struct dbAddr *paddr; - int after; + struct dbAddr *paddr; + int after; { - struct histogramRecord *phistogram = (struct histogramRecord *)(paddr->precord); - int special_type = paddr->special; + struct histogramRecord *phistogram = (struct histogramRecord *)(paddr->precord); + struct histogramdset *pdset = (struct histogramdset *) (phistogram->dset); + int special_type = paddr->special; - if(!after) return(0); - switch(special_type) { - case(SPC_RESET): - init_histogram(phistogram); - return(0); - default: - recGblDbaddrError(S_db_badChoice,paddr,"histogram: special"); - return(S_db_badChoice); - } + if(!after) return(0); + switch(special_type) { + case(SPC_CALC): + if(phistogram->cmd <=1){ + clear_histogram(phistogram); + phistogram->cmd =0; + } else if (phistogram->cmd ==2){ + phistogram->csta=TRUE; + phistogram->cmd =0; + } else if (phistogram->cmd ==3){ + phistogram->csta=FALSE; + phistogram->cmd =0; + } + return(0); + case(SPC_MOD): + /* increment frequency in histogram array */ + add_count(phistogram); + return(0); + case(SPC_RESET): + phistogram->wdth=(phistogram->ulim-phistogram->llim)/phistogram->nelm; + clear_histogram(phistogram); + return(0); + default: + recGblDbaddrError(S_db_badChoice,paddr,"histogram: special"); + return(S_db_badChoice); + } } + static void monitor(phistogram) - struct histogramRecord *phistogram; + struct histogramRecord *phistogram; { - unsigned short monitor_mask; - short stat,sevr,nsta,nsev; + unsigned short monitor_mask; + short stat,sevr,nsta,nsev; + struct callback *pcallback=(struct callback *)(phistogram->dpvt); + + /* get previous stat and sevr and new stat and sevr*/ + stat=phistogram->stat; + sevr=phistogram->sevr; + nsta=phistogram->nsta; + nsev=phistogram->nsev; + /*set current stat and sevr*/ + phistogram->stat = nsta; + phistogram->sevr = nsev; + phistogram->nsta = 0; + phistogram->nsev = 0; + + /* Flags which events to fire on the value field */ + monitor_mask = 0; + + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(phistogram,&phistogram->stat,DBE_VALUE); + db_post_events(phistogram,&phistogram->sevr,DBE_VALUE); + } - /* get previous stat and sevr and new stat and sevr*/ - stat=phistogram->stat; - sevr=phistogram->sevr; - nsta=phistogram->nsta; - nsev=phistogram->nsev; - /*set current stat and sevr*/ - phistogram->stat = nsta; - phistogram->sevr = nsev; - phistogram->nsta = 0; - phistogram->nsev = 0; + /* post events for count change */ + if(phistogram->mcnt>phistogram->mdel){ + /* post events for count change */ + monitor_mask |= DBE_VALUE; + /* reset counts since monitor */ + phistogram->mcnt = 0; + } + /* send out monitors connected to the value field */ + if(monitor_mask) db_post_events(phistogram,phistogram->bptr,monitor_mask); - /* Flags which events to fire on the value field */ - monitor_mask = 0; - - /* alarm condition changed this scan */ - if (stat!=nsta || sevr!=nsev) { - /* post events for alarm condition change*/ - monitor_mask = DBE_ALARM; - /* post stat and nsev fields */ - db_post_events(phistogram,&phistogram->stat,DBE_VALUE); - db_post_events(phistogram,&phistogram->sevr,DBE_VALUE); - } - - /* check for count change */ - if(phistogram->mcnt - phistogram->mdel>=0){ - /* post events for count change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - phistogram->mcnt = 0; - } - - /* send out monitors connected to the value field */ - if(monitor_mask) db_post_events(phistogram,phistogram->bptr,monitor_mask); - return; + return; } - + static long get_value(phistogram,pvdes) struct histogramRecord *phistogram; - struct valueDes *pvdes; + struct valueDes *pvdes; { pvdes->no_elements=phistogram->nelm; @@ -265,7 +322,7 @@ static long get_value(phistogram,pvdes) pvdes->field_type = DBF_ULONG; return(0); } - + static long cvt_dbaddr(paddr) struct dbAddr *paddr; { @@ -283,8 +340,8 @@ static long cvt_dbaddr(paddr) static long get_array_info(paddr,no_elements,offset) struct dbAddr *paddr; - long *no_elements; - long *offset; + long *no_elements; + long *offset; { struct histogramRecord *phistogram=(struct histogramRecord *)paddr->precord; @@ -292,3 +349,47 @@ static long get_array_info(paddr,no_elements,offset) *offset = 0; return(0); } + +static long add_count(phistogram) + struct histogramRecord *phistogram; +{ + double temp; + unsigned long *pdest; + int i; + double sgnl; + + if(phistogram->csta==FALSE) return(0); + + if(phistogram->llim >= phistogram->ulim) { + if (phistogram->nsevstat = SOFT_ALARM; + phistogram->sevr = VALID_ALARM; + return(-1); + } + } + if(phistogram->sgnlllim || phistogram->sgnl >= phistogram->ulim) return(0); + + temp=phistogram->sgnl-phistogram->llim; + for (i=1;i<=phistogram->nelm;i++){ + if (temp<=(double)i*phistogram->wdth) break; + } + pdest=phistogram->bptr+i-1; + if ( *pdest==ULONG_MAX) *pdest=0.0; + (*pdest)++; + phistogram->mcnt++; + + return(0); +} + +static long clear_histogram(phistogram) + struct histogramRecord *phistogram; +{ + int i; + + for (i=0;i<=phistogram->nelm-1;i++) + *(phistogram->bptr+i)=0.0; + phistogram->mcnt=phistogram->mdel+1; + phistogram->udf=FALSE; + + return(0); +}