static long cvt_dbaddr(DBADDR *paddr) { aSubRecord *prec = (aSubRecord *)paddr->precord; int fieldIndex = dbGetFieldIndex(paddr); if (fieldIndex >= aSubRecordA && fieldIndex <= aSubRecordU) { int offset = fieldIndex - aSubRecordA; paddr->pfield = (&prec->a )[offset]; paddr->no_elements = (&prec->noa)[offset]; paddr->field_type = (&prec->fta)[offset]; } else if (fieldIndex >= aSubRecordVALA && fieldIndex <= aSubRecordVALU) { int offset = fieldIndex - aSubRecordVALA; paddr->pfield = (&prec->vala)[offset]; paddr->no_elements = (&prec->nova)[offset]; paddr->field_type = (&prec->ftva)[offset]; } else { errlogPrintf("aSubRecord::cvt_dbaddr called for %s\n", prec->name); return 0; } paddr->dbr_field_type = paddr->field_type; paddr->field_size = dbValueSize(paddr->field_type); return 0; }
static long init_record(subArrayRecord *prec, int pass) { struct sadset *pdset; if (pass==0){ if (prec->malm <= 0) prec->malm = 1; if (prec->ftvl > DBF_ENUM) prec->ftvl = DBF_UCHAR; prec->bptr = callocMustSucceed(prec->malm, dbValueSize(prec->ftvl), "subArrayRecord calloc failed"); prec->nord = 0; return 0; } /* must have dset defined */ if (!(pdset = (struct sadset *)(prec->dset))) { recGblRecordError(S_dev_noDSET,(void *)prec,"sa: init_record"); return S_dev_noDSET; } /* must have read_sa function defined */ if ( (pdset->number < 5) || (pdset->read_sa == NULL) ) { recGblRecordError(S_dev_missingSup,(void *)prec,"sa: init_record"); return S_dev_missingSup; } if (pdset->init_record) return (*pdset->init_record)(prec); return 0; }
static void monitor(aSubRecord *prec) { int i; unsigned short monitor_mask; monitor_mask = recGblResetAlarms(prec) | DBE_VALUE | DBE_LOG; /* Post events for VAL field */ if (prec->val != prec->oval) { db_post_events(prec, &prec->val, monitor_mask); prec->oval = prec->val; } /* Event posting on VAL arrays depends on the setting of prec->eflg */ switch (prec->eflg) { case aSubEFLG_NEVER: break; case aSubEFLG_ON_CHANGE: for (i = 0; i < NUM_ARGS; i++) { epicsUInt32 alen = dbValueSize((&prec->ftva)[i]) * (&prec->neva)[i]; void *povl = (&prec->ovla)[i]; void *pval = (&prec->vala)[i]; if (memcmp(povl, pval, alen)) { memcpy(povl, pval, alen); db_post_events(prec, pval, monitor_mask); } } break; case aSubEFLG_ALWAYS: for (i = 0; i < NUM_ARGS; i++) db_post_events(prec, (&prec->vala)[i], monitor_mask); break; } return; }
static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, epicsUInt32 *pon, const char **fldnames, void **pval, void **povl) { int i; long status = 0; for (i = 0; i < NUM_ARGS; i++, pft++, pno++, pne++, pval++) { epicsUInt32 num; epicsUInt32 flen; if (*pft > DBF_ENUM) *pft = DBF_CHAR; if (*pno == 0) *pno = 1; flen = dbValueSize(*pft); num = *pno * flen; *pval = callocMustSucceed(*pno, flen, "aSubRecord::init_record"); *pne = *pno; if (povl) { if (num) *povl = callocMustSucceed(*pno, flen, "aSubRecord::init_record"); povl++; *pon++ = *pne; } } return status; }
static long add_record_waveform(dbCommon *praw) { waveformRecord *prec=(waveformRecord*)praw; long ret=0; try { assert(prec->inp.type==INST_IO); std::auto_ptr<priv> paddr(new priv); if (linkOptionsStore(eventdef, paddr.get(), prec->inp.value.instio.string, 0)) throw std::runtime_error("Couldn't parse link string"); mrf::Object *O=mrf::Object::getObject(paddr->obj); if(!O) { errlogPrintf("%s: failed to find object '%s'\n", prec->name, paddr->obj); return S_db_errArg; } paddr->priv=dynamic_cast<dataBufTx*>(O); if(!paddr->priv) throw std::runtime_error("Failed to lookup device"); // scratch space for endian swap if needed if(dbValueSize(prec->ftvl)>1 && dbValueSize(prec->ftvl)<=8) paddr->scratch = new epicsUInt8[prec->nelm*dbValueSize(prec->ftvl)]; else paddr->scratch = 0; // prec->dpvt is set again to indicate // This also serves to indicate successful // initialization to other dset functions prec->dpvt = paddr.release(); return 0; } catch(std::runtime_error& e) { recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); ret=S_dev_noDevice; } catch(std::exception& e) { recGblRecordError(S_db_noMemory, (void*)prec, e.what()); ret=S_db_noMemory; } return ret; }
static long cvt_dbaddr(DBADDR *paddr) { waveformRecord *prec = (waveformRecord *) paddr->precord; paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); paddr->dbr_field_type = prec->ftvl; return 0; }
//=============================================================================================== //=============================================================================================== static long init_aao(struct aaoRecord *paao) { double values[200]; ///??? int i; struct vmeio *pvmeio = (struct vmeio *) &(paao->out.value); unsigned short* card = (unsigned short*) &pvmeio->card; unsigned short* signal = (unsigned short*) &pvmeio->signal; unsigned slot = (*card)>>8; unsigned chassis = (*card) - ((slot)<<8) ; unsigned command = (*signal)>>8; unsigned channel = (*signal) - ((command)<<8); block_until_crate_read(chassis); //printf("1nelm=%d %d %p %p %s \n", paao->nelm,paao->nord,(double *) paao->val , (double *) paao->bptr, paao->name ); IocGetValue( chassis, slot, channel, command, values); //printf("2nelm=%d %d %p %p %s \n", paao->nelm,paao->nord,(double *) paao->val , (double *) paao->bptr, paao->name ); if(!(paao->bptr)) paao->bptr = callocMustSucceed(paao->nelm, dbValueSize(paao->ftvl), "aao: buffer calloc failed"); if(command==JLAB_SET_THRESHOLD /*&& strstr(paao->name,"B_SCALERS000_Sl13_Ch15")*/ ){ // paao->val=(double *)malloc(sizeof(double)*10); // paao->bptr = callocMustSucceed(paao->nelm, dbValueSize(paao->ftvl), // "aao: buffer calloc failed"); //printf("nelm=%d %d %p %p %s %d %d\n", paao->nelm,paao->nord,(double *) paao->val , (double *) paao->bptr, paao->name, (int)values[0], (int)values[1] ); //((double *)(paao->bptr))[0]=1; ((double*)paao->bptr)[0]=-1; /// undefined type of threshold last set (does not need initialization) ((double*)paao->bptr)[1]=values[0]; ((double*)paao->bptr)[2]=values[1]; } else if(command==JLAB_SET_READ_MODE){ for(i=0;i<MODE_PARS_NUMBER;i++){ ((double*)paao->bptr)[i]=values[i]; } } paao->nord=paao->nelm; return 0; }
static long write_waveform(waveformRecord* prec) { if (!prec->dpvt) return -1; try { priv *paddr=static_cast<priv*>(prec->dpvt); epicsUInt32 capacity=paddr->priv->lenMax(); const long esize=dbValueSize(prec->ftvl); epicsUInt32 requested=prec->nord*esize; if (requested > capacity) requested=capacity; epicsUInt8 *buf; if(esize==1 || esize>8) buf=static_cast<epicsUInt8*>(prec->bptr); else { buf=paddr->scratch; for(size_t i=0; i<requested; i+=esize) { switch(esize) { case 2: *(epicsUInt16*)(buf+i) = htons( *(epicsUInt16*)((char*)prec->bptr+i) ); break; case 4: *(epicsUInt32*)(buf+i) = htonl( *(epicsUInt32*)((char*)prec->bptr+i) ); break; case 8: #if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG *(epicsUInt32*)(buf+i) = *(epicsUInt32*)((char*)prec->bptr+i); *(epicsUInt32*)(buf+i+4) = *(epicsUInt32*)((char*)prec->bptr+i+4); #else *(epicsUInt32*)(buf+i+4) = htonl( *(epicsUInt32*)((char*)prec->bptr+i) ); *(epicsUInt32*)(buf+i) = htonl( *(epicsUInt32*)((char*)prec->bptr+i+4) ); #endif break; } } } paddr->priv->dataSend(paddr->proto,requested,buf); return 0; } catch(std::exception& e) { recGblRecordError(S_db_noMemory, (void*)prec, e.what()); return S_db_noMemory; } }
long dbBufferSize(short dbr_type, long options, long no_elements) { long nbytes=0; nbytes += dbValueSize(dbr_type) * no_elements; if (options & DBR_STATUS) nbytes += dbr_status_size; if (options & DBR_UNITS) nbytes += dbr_units_size; if (options & DBR_PRECISION) nbytes += dbr_precision_size; if (options & DBR_TIME) nbytes += dbr_time_size; if (options & DBR_ENUM_STRS) nbytes += dbr_enumStrs_size; if (options & DBR_GR_LONG) nbytes += dbr_grLong_size; if (options & DBR_GR_DOUBLE) nbytes += dbr_grDouble_size; if (options & DBR_CTRL_LONG) nbytes += dbr_ctrlLong_size; if (options & DBR_CTRL_DOUBLE) nbytes += dbr_ctrlDouble_size; if (options & DBR_AL_LONG) nbytes += dbr_alLong_size; if (options & DBR_AL_DOUBLE) nbytes += dbr_alDouble_size; return(nbytes); }
static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, const char **fldnames, void **pval, void **povl) { int i; long status = 0; for (i = 0; i < NUM_ARGS; i++, pft++, pno++, pne++, pval++) { epicsUInt32 num; epicsUInt32 flen; if (*pft > DBF_ENUM) *pft = DBF_CHAR; if (*pno == 0) *pno = 1; flen = dbValueSize(*pft); num = *pno * flen; if (num > MAX_ARRAY_SIZE) { epicsPrintf("Link %s - Array too large! %d Bytes (max: %d)\n", fldnames[i], num, MAX_ARRAY_SIZE); *pno = num = 0; status = S_db_errArg; } else *pval = (char *)callocMustSucceed(*pno, flen, "aSubRecord::init_record"); *pne = *pno; if (povl) { if (num) *povl = (char *)callocMustSucceed(*pno, flen, "aSubRecord::init_record"); povl++; } } return status; }
static long init_record(waveformRecord *prec, int pass) { struct wfdset *pdset; if (pass==0) { if (prec->nelm <= 0) prec->nelm = 1; if (prec->ftvl > DBF_ENUM) prec->ftvl = DBF_UCHAR; prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), "waveform calloc failed"); if (prec->nelm == 1) { prec->nord = 1; } else { prec->nord = 0; } return 0; } /* wf.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 dset defined */ if (!(pdset = (struct wfdset *)(prec->dset))) { recGblRecordError(S_dev_noDSET,(void *)prec,"wf: init_record"); return S_dev_noDSET; } /* must have read_wf function defined */ if ((pdset->number < 5) || (pdset->read_wf == NULL)) { recGblRecordError(S_dev_missingSup,(void *)prec,"wf: init_record"); return S_dev_missingSup; } if (! pdset->init_record) return 0; return (*pdset->init_record)(prec); }
static void monitor(waveformRecord *prec) { unsigned short monitor_mask = 0; unsigned int hash = 0; monitor_mask = recGblResetAlarms(prec); if (prec->mpst == waveformPOST_Always) monitor_mask |= DBE_VALUE; if (prec->apst == waveformPOST_Always) monitor_mask |= DBE_LOG; /* Calculate hash if we are interested in OnChange events. */ if ((prec->mpst == waveformPOST_OnChange) || (prec->apst == waveformPOST_OnChange)) { hash = epicsMemHash((char *)prec->bptr, prec->nord * dbValueSize(prec->ftvl), 0); /* Only post OnChange values if the hash is different. */ if (hash != prec->hash) { if (prec->mpst == waveformPOST_OnChange) monitor_mask |= DBE_VALUE; if (prec->apst == waveformPOST_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); } }
static long mergePvs(aSubRecord *pasub) { // output: waveform, avg, rms, min, max, std, var void *pval = pasub->vala; int i = 0; int szi = 1; double s1 = 0.0; double s2 = 0.0; double xmin = DBL_MAX; double xmax = DBL_MIN; double xstd = 0.0, xvar = 0.0, xrms = 0.0; /* if (pasub->inpa.type == CONSTANT) goto finish; memcpy(pval, pasub->a, pasub->noa * sizeof(double)); pval += pasub->noa; */ if (pasub->inpa.type == CONSTANT) goto finish; assert(dbValueSize(pasub->ftva) == dbValueSize(pasub->fta)); szi = dbValueSize(pasub->ftva); /* fprintf(stderr, "OUTA: %s\n", pasub->outa.value.pv_link.pvname); */ /* fprintf(stderr, "OUTB: %s\n", pasub->outb.value.pv_link.pvname); */ MERGE_INP(pval, pasub->inpa, pasub->a, pasub->noa*szi); MERGE_INP(pval, pasub->inpb, pasub->b, pasub->nob*szi); MERGE_INP(pval, pasub->inpc, pasub->c, pasub->noc*szi); MERGE_INP(pval, pasub->inpd, pasub->d, pasub->nod*szi); MERGE_INP(pval, pasub->inpe, pasub->e, pasub->noe*szi); MERGE_INP(pval, pasub->inpf, pasub->f, pasub->nof*szi); MERGE_INP(pval, pasub->inpg, pasub->g, pasub->nog*szi); MERGE_INP(pval, pasub->inph, pasub->h, pasub->noh*szi); MERGE_INP(pval, pasub->inpi, pasub->i, pasub->noi*szi); MERGE_INP(pval, pasub->inpj, pasub->j, pasub->noj*szi); MERGE_INP(pval, pasub->inpk, pasub->k, pasub->nok*szi); MERGE_INP(pval, pasub->inpl, pasub->l, pasub->nol*szi); MERGE_INP(pval, pasub->inpm, pasub->m, pasub->nom*szi); MERGE_INP(pval, pasub->inpn, pasub->n, pasub->non*szi); MERGE_INP(pval, pasub->inpo, pasub->o, pasub->noo*szi); MERGE_INP(pval, pasub->inpp, pasub->p, pasub->nop*szi); MERGE_INP(pval, pasub->inpq, pasub->q, pasub->noq*szi); MERGE_INP(pval, pasub->inpr, pasub->r, pasub->nor*szi); MERGE_INP(pval, pasub->inps, pasub->s, pasub->nos*szi); MERGE_INP(pval, pasub->inpt, pasub->t, pasub->not*szi); MERGE_INP(pval, pasub->inpu, pasub->u, pasub->nou*szi); stats: if (pasub->ftva == epicsFloat64T) { double *pdval = (double*) pasub->vala; for (i = 0; i < pasub->nova; ++i) { s1 += pdval[i]; s2 += pdval[i] * pdval[i]; if (pdval[i] < xmin) xmin = pdval[i]; if (pdval[i] > xmax) xmax = pdval[i]; } } else if (pasub->ftva == epicsFloat32T) { float *pfval = (float*) pasub->vala; for (i = 0; i < pasub->nova; ++i) { s1 += pfval[i]; s2 += pfval[i] * pfval[i]; if (pfval[i] < xmin) xmin = pfval[i]; if (pfval[i] > xmax) xmax = pfval[i]; } } else if (pasub->ftva == epicsUInt8T) { epicsUInt8 *pfval = (epicsUInt8*) pasub->vala; for (i = 0; i < pasub->nova; ++i) { s1 += pfval[i]; s2 += pfval[i] * pfval[i]; if (pfval[i] < xmin) xmin = pfval[i]; if (pfval[i] > xmax) xmax = pfval[i]; } } else { fprintf(stderr, "Unknow ftva: %d (%d %d %d %d)\n", pasub->ftva, epicsUInt8T, epicsInt8T, epicsUInt16T, epicsInt16T); goto finish; } double ss = s1; s2 /= pasub->nova; s1 /= pasub->nova; xrms = sqrt(s2); xvar = s2 - s1 * s1; xstd = sqrt(xvar); /* sum, avg, rms, min, max, std, var */ if (pasub->outb.type == CONSTANT) goto finish; *((double*)pasub->valb) = ss; if (pasub->outc.type == CONSTANT) goto finish; memcpy(pasub->valc, &s1, sizeof(double)); if (pasub->outd.type == CONSTANT) goto finish; memcpy(pasub->vald, &xrms, sizeof(double)); if (pasub->oute.type == CONSTANT) goto finish; memcpy(pasub->vale, &xmin, sizeof(double)); if (pasub->outf.type == CONSTANT) goto finish; memcpy(pasub->valf, &xmax, sizeof(double)); if (pasub->outg.type == CONSTANT) goto finish; memcpy(pasub->valg, &xstd, sizeof(double)); if (pasub->outh.type == CONSTANT) goto finish; memcpy(pasub->valh, &xvar, sizeof(double)); finish: return 0; }