Example #1
0
long epicsShareAPI dbPutLinkValue(struct link *plink, short dbrType,
    const void *pbuffer, long nRequest)
{
    long status = 0;

    if (plink->type == DB_LINK) {
        struct dbCommon *psource = plink->value.pv_link.precord;
        struct pv_link *ppv_link = &plink->value.pv_link;
        DBADDR *paddr = (DBADDR *)ppv_link->pvt;
        dbCommon *pdest = paddr->precord;

        status = dbPut(paddr, dbrType, pbuffer, nRequest);
        inherit_severity(ppv_link,pdest,psource->nsta,psource->nsev);
        if (status) return status;

        if (paddr->pfield == (void *)&pdest->proc ||
            (ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) {
            /*if dbPutField caused asyn record to process */
            /* ask for reprocessing*/
            if (pdest->putf) {
                pdest->rpro = TRUE;
            } else { /* otherwise ask for the record to be processed*/
                status = dbScanLink(psource, pdest);
            }
        }
        if (status)
            recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
    } else if (plink->type == CA_LINK) {
        struct dbCommon *psource = plink->value.pv_link.precord;

        status = dbCaPutLink(plink, dbrType, pbuffer, nRequest);
        if (status < 0)
            recGblSetSevr(psource, LINK_ALARM, INVALID_ALARM);
    } else {
        cantProceed("dbPutLinkValue: Illegal link type");
    }
    return status;
}
Example #2
0
/** Constructor for NDPluginROIStat; most parameters are simply passed to NDPluginDriver::NDPluginDriver.
  * After calling the base class constructor this method sets reasonable default values for all of the
  * ROI parameters.
  * \param[in] portName The name of the asyn port driver to be created.
  * \param[in] queueSize The number of NDArrays that the input queue for this plugin can hold when
  *            NDPluginDriverBlockingCallbacks=0.  Larger queues can decrease the number of dropped arrays,
  *            at the expense of more NDArray buffers being allocated from the underlying driver's NDArrayPool.
  * \param[in] blockingCallbacks Initial setting for the NDPluginDriverBlockingCallbacks flag.
  *            0=callbacks are queued and executed by the callback thread; 1 callbacks execute in the thread
  *            of the driver doing the callbacks.
  * \param[in] NDArrayPort Name of asyn port driver for initial source of NDArray callbacks.
  * \param[in] NDArrayAddr asyn port driver address for initial source of NDArray callbacks.
  * \param[in] maxROIs The maximum number of ROIs this plugin supports. 1 is minimum.
  * \param[in] maxBuffers The maximum number of NDArray buffers that the NDArrayPool for this driver is
  *            allowed to allocate. Set this to -1 to allow an unlimited number of buffers.
  * \param[in] maxMemory The maximum amount of memory that the NDArrayPool for this driver is
  *            allowed to allocate. Set this to -1 to allow an unlimited amount of memory.
  * \param[in] priority The thread priority for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags.
  * \param[in] stackSize The stack size for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags.
  */
NDPluginROIStat::NDPluginROIStat(const char *portName, int queueSize, int blockingCallbacks,
                         const char *NDArrayPort, int NDArrayAddr, int maxROIs,
                         int maxBuffers, size_t maxMemory,
                         int priority, int stackSize)
    /* Invoke the base class constructor */
    : NDPluginDriver(portName, queueSize, blockingCallbacks,
             NDArrayPort, NDArrayAddr, maxROIs, NUM_NDPLUGIN_ROISTAT_PARAMS, maxBuffers, maxMemory,
             asynInt32ArrayMask | asynFloat64Mask | asynFloat64ArrayMask | asynGenericPointerMask,
             asynInt32ArrayMask | asynFloat64Mask | asynFloat64ArrayMask | asynGenericPointerMask,
             ASYN_MULTIDEVICE, 1, priority, stackSize)
{
  const char *functionName = "NDPluginROIStat::NDPluginROIStat";

  if (maxROIs < 1) {
    maxROIs = 1;
  }
  maxROIs_ = maxROIs;
  pROIs_ = new NDROI[maxROIs];
  if(!pROIs_) {cantProceed(functionName);}
  
  /* ROI general parameters */
  createParam(NDPluginROIStatFirstString,             asynParamInt32, &NDPluginROIStatFirst);
  createParam(NDPluginROIStatNameString,              asynParamOctet, &NDPluginROIStatName);
  createParam(NDPluginROIStatUseString,               asynParamInt32, &NDPluginROIStatUse);
  createParam(NDPluginROIStatResetString,             asynParamInt32, &NDPluginROIStatReset);
  createParam(NDPluginROIStatResetAllString,          asynParamInt32, &NDPluginROIStatResetAll);
  createParam(NDPluginROIStatBgdWidthString,          asynParamInt32, &NDPluginROIStatBgdWidth);
  
  /* ROI definition */
  createParam(NDPluginROIStatDim0MinString,           asynParamInt32, &NDPluginROIStatDim0Min);
  createParam(NDPluginROIStatDim0SizeString,          asynParamInt32, &NDPluginROIStatDim0Size);
  createParam(NDPluginROIStatDim0MaxSizeString,       asynParamInt32, &NDPluginROIStatDim0MaxSize);
  createParam(NDPluginROIStatDim1MinString,           asynParamInt32, &NDPluginROIStatDim1Min);
  createParam(NDPluginROIStatDim1SizeString,          asynParamInt32, &NDPluginROIStatDim1Size);
  createParam(NDPluginROIStatDim1MaxSizeString,       asynParamInt32, &NDPluginROIStatDim1MaxSize);
  createParam(NDPluginROIStatDim2MinString,           asynParamInt32, &NDPluginROIStatDim2Min);
  createParam(NDPluginROIStatDim2SizeString,          asynParamInt32, &NDPluginROIStatDim2Size);
  createParam(NDPluginROIStatDim2MaxSizeString,       asynParamInt32, &NDPluginROIStatDim2MaxSize);
  
  /* ROI statistics */
  createParam(NDPluginROIStatMinValueString,          asynParamFloat64, &NDPluginROIStatMinValue);
  createParam(NDPluginROIStatMaxValueString,          asynParamFloat64, &NDPluginROIStatMaxValue);
  createParam(NDPluginROIStatMeanValueString,         asynParamFloat64, &NDPluginROIStatMeanValue);
  createParam(NDPluginROIStatTotalString,             asynParamFloat64, &NDPluginROIStatTotal);
  createParam(NDPluginROIStatNetString,               asynParamFloat64, &NDPluginROIStatNet);

  /* Time series arrays */
  createParam(NDPluginROIStatTSControlString,           asynParamInt32, &NDPluginROIStatTSControl);
  createParam(NDPluginROIStatTSNumPointsString,         asynParamInt32, &NDPluginROIStatTSNumPoints);
  createParam(NDPluginROIStatTSCurrentPointString,      asynParamInt32, &NDPluginROIStatTSCurrentPoint);
  createParam(NDPluginROIStatTSAcquiringString,         asynParamInt32, &NDPluginROIStatTSAcquiring);
  createParam(NDPluginROIStatTSMinValueString,   asynParamFloat64Array, &NDPluginROIStatTSMinValue);
  createParam(NDPluginROIStatTSMaxValueString,   asynParamFloat64Array, &NDPluginROIStatTSMaxValue);
  createParam(NDPluginROIStatTSMeanValueString,  asynParamFloat64Array, &NDPluginROIStatTSMeanValue);
  createParam(NDPluginROIStatTSTotalString,      asynParamFloat64Array, &NDPluginROIStatTSTotal);
  createParam(NDPluginROIStatTSNetString,        asynParamFloat64Array, &NDPluginROIStatTSNet);
  createParam(NDPluginROIStatTSTimestampString,  asynParamFloat64Array, &NDPluginROIStatTSTimestamp);

  createParam(NDPluginROIStatLastString,              asynParamInt32, &NDPluginROIStatLast);
  
  //Note: params set to a default value here will overwrite a default database value

  /* Set the plugin type string */
  setStringParam(NDPluginDriverPluginType, "NDPluginROIStat");
  
  for (int roi=0; roi<maxROIs_; ++roi) {
    
    setIntegerParam(roi , NDPluginROIStatFirst,             0);
    setIntegerParam(roi , NDPluginROIStatLast,              0);

    setStringParam (roi,  NDPluginROIStatName,              "");
    setIntegerParam(roi , NDPluginROIStatUse,               0);
    
    setIntegerParam(roi , NDPluginROIStatDim0Min,           0);
    setIntegerParam(roi , NDPluginROIStatDim0Size,          0);
    setIntegerParam(roi , NDPluginROIStatDim0MaxSize,       0);
    setIntegerParam(roi , NDPluginROIStatDim1Min,           0);
    setIntegerParam(roi , NDPluginROIStatDim1Size,          0);
    setIntegerParam(roi , NDPluginROIStatDim1MaxSize,       0);
    setIntegerParam(roi , NDPluginROIStatDim2Min,           0);
    setIntegerParam(roi , NDPluginROIStatDim2Size,          0);
    setIntegerParam(roi , NDPluginROIStatDim2MaxSize,       0);
    
    setDoubleParam (roi , NDPluginROIStatMinValue,          0.0);
    setDoubleParam (roi , NDPluginROIStatMaxValue,          0.0);
    setDoubleParam (roi , NDPluginROIStatMeanValue,         0.0);
    setDoubleParam (roi , NDPluginROIStatTotal,             0.0);
    setDoubleParam (roi , NDPluginROIStatNet,               0.0);
    callParamCallbacks(roi);
  }

  numTSPoints_ = DEFAULT_NUM_TSPOINTS;
  setIntegerParam(NDPluginROIStatTSNumPoints, numTSPoints_);
  timeSeries_ = (double *)calloc(MAX_TIME_SERIES_TYPES*maxROIs_*numTSPoints_, sizeof(double));
  
  /* Try to connect to the array port */
  connectToArrayPort();

  callParamCallbacks();
  
}
Example #3
0
/** 
 * Callback function that is called by the NDArray driver with new NDArray data.
 * Computes statistics on the ROIs if NDPluginROIStatUse is 1.
 * If NDPluginROIStatNDArrayCallbacks is 1 then it also does NDArray callbacks.
 * \param[in] pArray The NDArray from the callback.
 */
void NDPluginROIStat::processCallbacks(NDArray *pArray)
{

  //This function is called with the mutex already locked.  
  //It unlocks it during long calculations when private structures don't need to be protected.
  
  int itemp = 0;
  int dim = 0;
  asynStatus status = asynSuccess;
  NDROI *pROI;
  int TSAcquiring;
  const char* functionName = "NDPluginROIStat::processCallbacks";
  NDROI_t *pROIs = new NDROI[maxROIs_];
  if(!pROIs) {cantProceed("%s",functionName);}

  /* Call the base class method */
  NDPluginDriver::beginProcessCallbacks(pArray);

  // This plugin only works with 1-D or 2-D arrays
  if ((pArray->ndims < 1) || (pArray->ndims > 2)) {
      asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
        "%s: error, number of array dimensions must be 1 or 2\n",
        functionName);
  }

  //Set NDArraySize params to the input pArray, because this plugin doesn't change them
  if (pArray->ndims > 0) setIntegerParam(NDArraySizeX, (int)pArray->dims[0].size);
  if (pArray->ndims > 1) setIntegerParam(NDArraySizeY, (int)pArray->dims[1].size);

  /* Loop over the ROIs in this driver */
  for (int roi=0; roi<maxROIs_; ++roi) {
    pROI = &pROIs[roi];
    getIntegerParam(roi, NDPluginROIStatUse, &pROI->use);
    if (!pROI->use) {
      continue;
    }

    /* Need to fetch all of these parameters while we still have the mutex */
    getIntegerParam(roi, NDPluginROIStatDim0Min,      &itemp); pROI->offset[0] = itemp;
    getIntegerParam(roi, NDPluginROIStatDim1Min,      &itemp); pROI->offset[1] = itemp;
    getIntegerParam(roi, NDPluginROIStatDim0Size,     &itemp); pROI->size[0] = itemp;
    getIntegerParam(roi, NDPluginROIStatDim1Size,     &itemp); pROI->size[1] = itemp;
    getIntegerParam(roi, NDPluginROIStatBgdWidth,     &itemp); pROI->bgdWidth = itemp;
    
    for (dim=0; dim<pArray->ndims; dim++) {
      pROI->offset[dim]  = MAX(pROI->offset[dim], 0);
      pROI->offset[dim]  = MIN(pROI->offset[dim], pArray->dims[dim].size-1);
      pROI->size[dim]    = MAX(pROI->size[dim], 1);
      pROI->size[dim]    = MIN(pROI->size[dim], pArray->dims[dim].size - pROI->offset[dim]);
      pROI->arraySize[dim] = (int)pArray->dims[dim].size;
    }
    
    /* Update the parameters that may have changed */
    setIntegerParam(roi, NDPluginROIStatDim0MaxSize, 0);
    setIntegerParam(roi, NDPluginROIStatDim1MaxSize, 0);
    if (pArray->ndims > 0) {
      setIntegerParam(roi, NDPluginROIStatDim0MaxSize, (int)pArray->dims[0].size);
      setIntegerParam(roi, NDPluginROIStatDim0Min,  (int)pROI->offset[0]);
      setIntegerParam(roi, NDPluginROIStatDim0Size, (int)pROI->size[0]);
    }
    if (pArray->ndims > 1) {
      setIntegerParam(roi, NDPluginROIStatDim1MaxSize, (int)pArray->dims[1].size);
      setIntegerParam(roi, NDPluginROIStatDim1Min,  (int)pROI->offset[1]);
      setIntegerParam(roi, NDPluginROIStatDim1Size, (int)pROI->size[1]);
    }
  }
        
  /* This function is called with the lock taken, and it must be set when we exit.
   * The following code can be exected without the mutex because we are not accessing elements of
   * pPvt that other threads can access. */
  this->unlock();
    
  for (int roi=0; roi<maxROIs_; ++roi) {
    pROI = &pROIs[roi];
    if (!pROI->use) {
      continue;
    }
    status = doComputeStatistics(pArray, pROI);
    if (status != asynSuccess) {
      asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
        "%s: doComputeStatistics failed. status=%d\n", 
        functionName, status);
    }
  }

  /* We must enter the loop and exit with the mutex locked */
  this->lock();

  getIntegerParam(NDPluginROIStatTSAcquiring, &TSAcquiring);

  for (int roi=0; roi<maxROIs_; ++roi) {
    pROI = &pROIs[roi];
    if (!pROI->use) {
      continue;
    }
    if (TSAcquiring) {
      double *pData = timeSeries_ + (roi * MAX_TIME_SERIES_TYPES * numTSPoints_);
      pData[TSMinValue*numTSPoints_ + currentTSPoint_]  = pROI->min;
      pData[TSMaxValue*numTSPoints_ + currentTSPoint_]  = pROI->max;
      pData[TSMeanValue*numTSPoints_ + currentTSPoint_] = pROI->mean;
      pData[TSTotal*numTSPoints_ + currentTSPoint_]     = pROI->total;
      pData[TSNet*numTSPoints_ + currentTSPoint_]       = pROI->net;
      pData[TSTimestamp*numTSPoints_ + currentTSPoint_] = pArray->timeStamp;
    }

    setDoubleParam(roi, NDPluginROIStatMinValue,    pROI->min);
    setDoubleParam(roi, NDPluginROIStatMaxValue,    pROI->max);
    setDoubleParam(roi, NDPluginROIStatMeanValue,   pROI->mean);
    setDoubleParam(roi, NDPluginROIStatTotal,       pROI->total);
    setDoubleParam(roi, NDPluginROIStatNet,         pROI->net);
    asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
          "%s ROI=%d, min=%f, max=%f, mean=%f, total=%f, net=%f\n",
          functionName, roi, pROI->min, pROI->max, pROI->mean, pROI->total, pROI->net);

    callParamCallbacks(roi);
  }

  if (TSAcquiring) {
    currentTSPoint_++;
    setIntegerParam(NDPluginROIStatTSCurrentPoint, currentTSPoint_);
    if (currentTSPoint_ >= numTSPoints_) {
      setIntegerParam(NDPluginROIStatTSAcquiring, 0);
      doTimeSeriesCallbacks();
    }
  }

  NDPluginDriver::endProcessCallbacks(pArray, true, true);
  callParamCallbacks();
  delete[] pROIs;
}
Example #4
0
long epicsShareAPI dbGetLinkValue(struct link *plink, short dbrType,
    void *pbuffer, long *poptions, long *pnRequest)
{
    long status = 0;

    if (plink->type == CONSTANT) {
        if (poptions) *poptions = 0;
        if (pnRequest) *pnRequest = 0;
    } else if (plink->type == DB_LINK) {
        struct pv_link *ppv_link = &(plink->value.pv_link);
        DBADDR         *paddr = ppv_link->pvt;
        dbCommon       *precord = plink->value.pv_link.precord;

        /* scan passive records with links that are process passive  */
        if (ppv_link->pvlMask&pvlOptPP) {
            dbCommon *pfrom = paddr->precord;
            unsigned char pact;

            pact = precord->pact;
            precord->pact = TRUE;
            status = dbScanPassive(precord,pfrom);
            precord->pact = pact;
            if (status) return status;
        }
        if(precord!= paddr->precord) {
            inherit_severity(ppv_link,precord,paddr->precord->stat,paddr->precord->sevr);
        }

        if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) {
            status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
        } else {
            unsigned short dbfType = paddr->field_type;
            long       no_elements = paddr->no_elements;

            if (dbrType < 0 || dbrType > DBR_ENUM ||
                dbfType > DBF_DEVICE) {
                status = S_db_badDbrtype;
                recGblRecordError(status, precord, "GetLinkValue Failed");
                recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
                return status;
            }
            /*  attempt to make a fast link */
            if ((!poptions || *poptions == 0) &&
                no_elements == 1 &&
                (!pnRequest || *pnRequest == 1) &&
                paddr->special != SPC_ATTRIBUTE) {
                ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType];
                status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr);
            } else {
                ppv_link->getCvt = 0;
                status = dbGet(paddr, dbrType, pbuffer, poptions, pnRequest, NULL);
            }
        }
        ppv_link->lastGetdbrType = dbrType;
        if (status) {
            recGblRecordError(status, precord, "dbGetLinkValue");
            recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
        }
    } else if (plink->type == CA_LINK) {
        struct dbCommon *precord = plink->value.pv_link.precord;
        const struct pv_link *pcalink = &plink->value.pv_link;
        epicsEnum16 sevr, stat;

        status=dbCaGetLink(plink,dbrType,pbuffer,&stat,&sevr,pnRequest);
        if (status) {
            recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM);
        } else {
            inherit_severity(pcalink,precord,stat,sevr);
        }
        if (poptions) *poptions = 0;
    } else {
        cantProceed("dbGetLinkValue: Illegal link type");
    }
    return status;
}
Example #5
0
static void registryInit(int tableSize)
{
    if(tableSize==0) tableSize = DEFAULT_TABLE_SIZE;
    gphInitPvt(&gphPvt,tableSize);
    if(!gphPvt) cantProceed("registry why did gphInitPvt fail\n");
}