Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;

}
Пример #8
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;
}
}
Пример #9
0
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);
}
Пример #10
0
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;
}
Пример #11
0
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);
}
Пример #12
0
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);
    }
}
Пример #13
0
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;
}