Esempio n. 1
0
static void interruptCallbackInput(void *drvPvt, asynUser *pasynUser,
                epicsFloat64 value)
{
    devPvt *pPvt = (devPvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    ringBufferElement *rp;

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynFloat64::interruptCallbackInput new value=%f\n",
        pr->name, value);
    /* There is a problem.  A driver could be calling us with a value after
     * this record has registered for callbacks but before EPICS has set interruptAccept,
     * which means that scanIoRequest will return immediately.
     * This is very bad, because if we have pushed a value into the ring buffer
     * it won't get popped off because the record won't process.  The values
     * read the next time the record processes would then be stale.
     * We previously worked around this problem by waiting here for interruptAccept.
     * But that does not work if the callback is coming from the thread that is executing
     * iocInit, which can happen with synchronous drivers (ASYN_CANBLOCK=0) that do callbacks
     * when a value is written to them, which can happen in initRecord for an output record.
     * Instead we just return.  There will then be nothing in the ring buffer, so the first
     * read will do a read from the driver, which should be OK. */
    if (!interruptAccept) return;
    /* Note that we put a lock around epicsRingBytesPut and Get because we potentially have
     * more than one reader, since the reader is whatever thread is processing the record */
    epicsMutexLock(pPvt->mutexId);
    rp = &pPvt->ringBuffer[pPvt->ringHead];
    rp->value = value;
    rp->time = pasynUser->timestamp;
    rp->status = pasynUser->auxStatus;
    pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1;
    if (pPvt->ringHead == pPvt->ringTail) {
        /* There was no room in the ring buffer.  In the past we just threw away
         * the new value.  However, it is better to remove the oldest value from the
         * ring buffer and add the new one.  That way the final value the record receives
         * is guaranteed to be the most recent value */
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        pPvt->ringBufferOverflows++;
    } else {
        /* We only need to request the record to process if we added a new
         * element to the ring buffer, not if we just replaced an element. */
        scanIoRequest(pPvt->ioScanPvt);
    }
    epicsMutexUnlock(pPvt->mutexId);
}
epicsShareFunc int epicsShareAPI
epicsMessageQueuePending(epicsMessageQueueId pmsg)
{
    char *myInPtr, *myOutPtr;
    int nmsg;

    epicsMutexLock(pmsg->mutex);
    myInPtr = (char *)pmsg->inPtr;
    myOutPtr = (char *)pmsg->outPtr;
    if (pmsg->full)
        nmsg = pmsg->capacity;
    else if (myInPtr >= myOutPtr)
        nmsg = (myInPtr - myOutPtr) / pmsg->slotSize;
    else
        nmsg = pmsg->capacity  - (myOutPtr - myInPtr) / pmsg->slotSize;
    epicsMutexUnlock(pmsg->mutex);
    return nmsg;
}
Esempio n. 3
0
static void drvMK80S_timeoutCallback(asynUser* pasynMK80SUser)
{
	kuDebug (kuTRACE, "[drvMK80S_timeoutCallback] timeout \n");

    asynMK80SUserData* pasynMK80SUserData = (asynMK80SUserData*) pasynMK80SUser->userPvt;
    drvMK80SConfig* pdrvMK80SConfig = (drvMK80SConfig*) pasynMK80SUserData->pdrvMK80SConfig;

    pdrvMK80SConfig->status |= MK80SSTATUS_TIMEOUT_MASK;

    epicsMutexLock(pdrvMK80SConfig->lock);
    pdrvMK80SConfig->cbCount =0;
    pdrvMK80SConfig->timeoutCount++;
    epicsMutexUnlock(pdrvMK80SConfig->lock);

    scanIoRequest(pdrvMK80SConfig->ioScanPvt);

   return; 
}
Esempio n. 4
0
LOCAL long devSiTPG262Read_gst_str(drvTPG262Config* pdrvTPG262Config, int gauge_num, char* gst_str)
{
    TPG262_read* pTPG262_read = (TPG262_read*)pdrvTPG262Config->pTPG262_read;

    epicsMutexLock(pdrvTPG262Config->lock);
    switch(gauge_num){
        case 0:
            strcpy(gst_str, pTPG262_read->gst_str0);
            break;
        case 1:
            strcpy(gst_str, pTPG262_read->gst_str1);
            break;
        default:
            gst_str[0] = NULL;
    }
    epicsMutexUnlock(pdrvTPG262Config->lock);
    return 0;
}
Esempio n. 5
0
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsInt32 value)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    int count, size = sizeof(epicsInt32);

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::interruptCallbackOutput new value=%d\n",
        pr->name, value);
    epicsMutexLock(pPvt->mutexId);
    count = epicsRingBytesPut(pPvt->ringBuffer, (char *)&value, size);
    if (count != size) {
        pPvt->ringBufferOverflows++;
    }
    epicsMutexUnlock(pPvt->mutexId);
    scanOnce(pr);
}
Esempio n. 6
0
static void interruptCallbackAverage(void *drvPvt, asynUser *pasynUser,
                epicsInt32 value)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    aiRecord *pai = (aiRecord *)pPvt->pr;

    if (pPvt->mask) {
        value &= pPvt->mask;
        if (pPvt->bipolar && (value & pPvt->signBit)) value |= ~pPvt->mask;
    }
    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::interruptCallbackAverage new value=%d\n",
         pai->name, value);
    epicsMutexLock(pPvt->ringBufferLock);
    pPvt->numAverage++; 
    pPvt->sum += (double)value;
    pPvt->result.status |= pasynUser->auxStatus;
    epicsMutexUnlock(pPvt->ringBufferLock);
}
Esempio n. 7
0
static long update_params(epidRecord *pepid)
{
    epidFastPvt *pPvt = (epidFastPvt *)pepid->dpvt;

    epicsMutexLock(pPvt->mutexId);
    /* If the user has changed the value of dt, requested time per point,
     * then update numAverage */
    if (pepid->dt != pPvt->timePerPointActual) {
        pPvt->timePerPointRequested = pepid->dt;
        computeNumAverage(pPvt);
    }
    /* Copy values from private structure to record */
    pepid->cval = pPvt->actual;
    pepid->err  = pPvt->error;
    pepid->oval = pPvt->output;
    pepid->p    = pPvt->P;
    pepid->i    = pPvt->I;
    pepid->d    = pPvt->D;
    pepid->dt   = pPvt->timePerPointActual;

    /* Copy values from record to private structure */
    pPvt->feedbackOn = pepid->fbon;
    pPvt->highLimit = pepid->drvh;
    pPvt->lowLimit = pepid->drvl;
    pPvt->KP = pepid->kp;
    pPvt->KI = pepid->ki;
    pPvt->KD = pepid->kd;
    pPvt->setPoint = pepid->val;
    epicsMutexUnlock(pPvt->mutexId);

    asynPrint(pPvt->pcallbackDataAsynUser, ASYN_TRACEIO_DEVICE,
              "devEpidFast::update_params, record=%s\n "
              "    feedback state %d, previous feedback state %d\n"
              "    cval=%f, err=%f, oval=%f,\n"
              "    P=%f, I=%f, D=%f, dt=%f\n",
              pepid->name,
              pPvt->feedbackOn, pPvt->prevFeedbackOn,
              pepid->cval, pepid->err, pepid->oval,
              pepid->p, pepid->i, pepid->d, pepid->dt);

    pepid->udf=0;
    return(0);
}
Esempio n. 8
0
LOCAL long devAiTPG262Read_prs(drvTPG262Config* pdrvTPG262Config, int gauge_num,double* prs)
{
    TPG262_read* pTPG262_read = (TPG262_read*)pdrvTPG262Config->pTPG262_read;

    epicsMutexLock(pdrvTPG262Config->lock);
    switch(gauge_num) {
        case 0:
            *prs = pTPG262_read->prs0;
            break;
        case 1:
            *prs = pTPG262_read->prs1;
            break;
        default:
            *prs = -1.;
    }
    epicsMutexUnlock(pdrvTPG262Config->lock);

    return 0;
}
Esempio n. 9
0
/** Finds an attribute by name; the search is case-insensitive.
  * \param[in] pName The name of the attribute to be found.
  * \return Returns a pointer to the attribute if found, NULL if not found. 
  */
NDAttribute* NDAttributeList::find(const char *pName)
{
  NDAttribute *pAttribute;
  NDAttributeListNode *pListNode;
  //const char *functionName = "NDAttributeList::find";

  epicsMutexLock(this->lock);
  pListNode = (NDAttributeListNode *)ellFirst(&this->list);
  while (pListNode) {
    pAttribute = pListNode->pNDAttribute;
    if (epicsStrCaseCmp(pAttribute->pName, pName) == 0) goto done;
    pListNode = (NDAttributeListNode *)ellNext(&pListNode->node);
  }
  pAttribute = NULL;

  done:
  epicsMutexUnlock(this->lock);
  return(pAttribute);
}
Esempio n. 10
0
static int motorAxisHome( AXIS_HDL pAxis, double min_velocity, double max_velocity, double acceleration, int forwards )
{
  int status = MOTOR_AXIS_ERROR;

  if (pAxis == NULL) status = MOTOR_AXIS_ERROR;
  else
    {
      if (epicsMutexLock( pAxis->axisMutex ) == epicsMutexLockOK) {
	status = motorAxisVelocity( pAxis, (forwards? max_velocity: -max_velocity), acceleration );
	pAxis->homing = 1;
	motorParam->setInteger( pAxis->params, motorAxisDone, 0 );
	motorParam->callCallback( pAxis->params );
	epicsMutexUnlock( pAxis->axisMutex );
	pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to home %s, min vel=%f, max_vel=%f, accel=%f",
		      pAxis->card, pAxis->axis, (forwards?"FORWARDS":"REVERSE"), min_velocity, max_velocity, acceleration );
      }
    }
  return status;
}
Esempio n. 11
0
static int motorAxisVelocityMove(  AXIS_HDL pAxis, double min_velocity, double velocity, double acceleration )
{
  int status = MOTOR_AXIS_ERROR;

  if (pAxis == NULL) status = MOTOR_AXIS_ERROR;
  else
    {
      if (epicsMutexLock( pAxis->axisMutex ) == epicsMutexLockOK)
	{
	  status = motorAxisVelocity( pAxis, velocity, acceleration );
	  motorParam->setInteger( pAxis->params, motorAxisDone, 0 );
	  motorParam->callCallback( pAxis->params );
	  epicsMutexUnlock( pAxis->axisMutex );
	  pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d move with velocity of %f, accel=%f",
                        pAxis->card, pAxis->axis, velocity, acceleration );
        }
    }
  return status;
}
Esempio n. 12
0
LOCAL long devBiGP307_read_bi_synchronous(biRecord *precord)
{
    devGP307dpvt *pdevGP307dpvt = (devGP307dpvt*)precord->dpvt;
    drvGP307Config *pdrvGP307Config = (drvGP307Config*)pdevGP307dpvt->pdrvGP307Config;
    GP307_read *pGP307_read = (GP307_read*)pdrvGP307Config->pGP307_read;

    switch(pdevGP307dpvt->param){
        case GP307DEVPARAM_STATUSCG0:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_CG0VALID_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        case GP307DEVPARAM_STATUSCG1:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_CG1VALID_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        case GP307DEVPARAM_STATUSIG:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_IGVALID_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        case GP307DEVPARAM_STATUSTIMEOUT:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_TIMEOUT_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        case GP307DEVPARAM_STATUSONOFFIG0:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_IG0ONOFF_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        case GP307DEVPARAM_STATUSONOFFIG1:
            epicsMutexLock(pdrvGP307Config->lock);
            precord->rval = (pGP307_read->status & GP307STATUS_IG1ONOFF_MASK)?1:0;
            epicsMutexUnlock(pdrvGP307Config->lock);
            break;
        default:
            precord->pact = TRUE;
            precord->udf = TRUE;
            return 0;
    }

    precord->val = precord->rval;
    precord->udf = FALSE;

    return 2; /* don't do any conversion */

}
Esempio n. 13
0
/* This is the function that is called back from the driver when a new readback
 * value is obtained */
static void dataCallback(void *drvPvt, asynUser *pasynUser, double readBack)
{
    epidFastPvt *pPvt = (epidFastPvt *)drvPvt;

    epicsMutexLock(pPvt->mutexId);
    /* No need to average if collecting every point */
    if (pPvt->numAverage == 1) {
        do_PID(pPvt, readBack);
        goto done;
    }
    pPvt->averageStore += readBack;
    if (++pPvt->accumulated < pPvt->numAverage) goto done;
    /* We have now collected the desired number of points to average */
    pPvt->averageStore /= pPvt->accumulated;
    do_PID(pPvt, pPvt->averageStore);
    pPvt->averageStore = 0.;
    pPvt->accumulated = 0;
done:
    epicsMutexUnlock(pPvt->mutexId);
}
Esempio n. 14
0
epicsShareFunc boolean seqQueueGetF(QUEUE q, seqQueueFunc *get, void *arg)
{
    if (q->wr == q->rd) {
        if (!q->overflow) {
            return TRUE;
        }
        epicsMutexLock(q->mutex);
        get(arg, q->buffer + q->rd * q->elemSize, q->elemSize);
        /* check again, a put might have intervened */
        if (q->wr == q->rd && q->overflow)
            q->overflow = FALSE;
        else
            q->rd = (q->rd + 1) % q->numElems;
        epicsMutexUnlock(q->mutex);
    } else {
        get(arg, q->buffer + q->rd * q->elemSize, q->elemSize);
        q->rd = (q->rd + 1) % q->numElems;
    }
    return FALSE;
}
Esempio n. 15
0
/* Create a PLC entry:
 * name : identifier
 * ip_address: DNS name or dot-notation
 */
eip_bool drvEtherIP_define_PLC(const char *PLC_name,
                               const char *ip_addr, int slot)
{
    PLC *plc;

    epicsMutexLock(drvEtherIP_private.lock);
    plc = get_PLC(PLC_name, true);
    if (plc)
    {
    	if (plc->ip_addr)
    	{
    		EIP_printf(1, "Redefining IP address of PLC %s?\n", PLC_name);
    		free(plc->ip_addr);
    	}
    	plc->ip_addr = EIP_strdup(ip_addr);
        plc->slot = slot;
    }
    epicsMutexUnlock(drvEtherIP_private.lock);
    return plc  &&  plc->ip_addr;
}
Esempio n. 16
0
/** Reports on the properties of the attribute list.
  * \param[in] details Level of report details desired; if >10 calls NDAttribute::report() for each attribute.
  */
int NDAttributeList::report(int details)
{
  NDAttribute *pAttribute;
  NDAttributeListNode *pListNode;
  
  epicsMutexLock(this->lock);
  printf("\n");
  printf("NDAttributeList: address=%p:\n", this);
  printf("  number of attributes=%d\n", this->count());
  if (details > 10) {
    pListNode = (NDAttributeListNode *) ellFirst(&this->list);
    while (pListNode) {
      pAttribute = (NDAttribute *)pListNode->pNDAttribute;
      pAttribute->report(details);
      pListNode = (NDAttributeListNode *) ellNext(&pListNode->node);
    }
  }
  epicsMutexUnlock(this->lock);
  return ND_SUCCESS;
}
Esempio n. 17
0
/** Base method for reading a file
  * Creates the file name with NDPluginBase::createFileName, then calls the pure virtual functions openFile,
  * readFile and closeFile in the derived class.  Does callbacks with the NDArray that was read in. */
asynStatus NDPluginFile::readFileBase(void)
{
    asynStatus status = asynSuccess;
    char fullFileName[MAX_FILENAME_LEN];
    int dataType=0;
    NDArray *pArray=NULL;
    static const char* functionName = "readFileBase";

    status = (asynStatus)createFileName(MAX_FILENAME_LEN, fullFileName);
    if (status) { 
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
              "%s:%s error creating full file name, fullFileName=%s, status=%d\n", 
              driverName, functionName, fullFileName, status);
        return(status);
    }
    
    /* Call the readFile method in the derived class */
    /* Do this with the main lock released since it is slow */
    this->unlock();
    epicsMutexLock(this->fileMutexId);
    status = this->openFile(fullFileName, NDFileModeRead, pArray);
    status = this->readFile(&pArray);
    status = this->closeFile();
    epicsMutexUnlock(this->fileMutexId);
    this->lock();
    
    /* If we got an error then return */
    if (status) return(status);
    
    /* Update the new values of dimensions and the array data */
    setIntegerParam(NDDataType, dataType);
    
    /* Call any registered clients */
    doCallbacksGenericPointer(pArray, NDArrayData, 0);

    /* Set the last array to be this one */
    this->pArrays[0]->release();
    this->pArrays[0] = pArray;    
    
    return(status);
}
Esempio n. 18
0
/** Copies all attributes from one attribute list to another.
  * It is efficient so that if the attribute already exists in the output
  * list it just copies the properties, and memory allocation is minimized.
  * The attributes are added to any existing attributes already present in the output list.
  * \param[out] pListOut A pointer to the output attribute list to copy to.
  */
int NDAttributeList::copy(NDAttributeList *pListOut)
{
  NDAttribute *pAttrIn, *pAttrOut, *pFound;
  NDAttributeListNode *pListNode;
  //const char *functionName = "NDAttributeList::copy";

  epicsMutexLock(this->lock);
  pListNode = (NDAttributeListNode *)ellFirst(&this->list);
  while (pListNode) {
    pAttrIn = pListNode->pNDAttribute;
    /* See if there is already an attribute of this name in the output list */
    pFound = pListOut->find(pAttrIn->pName);
    /* The copy function will copy the properties, and will create the attribute if pFound is NULL */
    pAttrOut = pAttrIn->copy(pFound);
    /* If pFound is NULL, then a copy created a new attribute, need to add it to the list */
    if (!pFound) pListOut->add(pAttrOut);
    pListNode = (NDAttributeListNode *)ellNext(&pListNode->node);
  }
  epicsMutexUnlock(this->lock);
  return(ND_SUCCESS);
}
Esempio n. 19
0
static int getCallbackValue(devPvt *pPvt)
{
    int ret = 0;
    epicsMutexLock(pPvt->ringBufferLock);
    if (pPvt->ringTail != pPvt->ringHead) {
        if (pPvt->ringBufferOverflows > 0) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_WARNING,
                "%s devAsynFloat64 getCallbackValue error, %d ring buffer overflows\n",
                                    pPvt->pr->name, pPvt->ringBufferOverflows);
            pPvt->ringBufferOverflows = 0;
        }
        pPvt->result = pPvt->ringBuffer[pPvt->ringTail];
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
            "%s devAsynFloat64::getCallbackValue from ringBuffer value=%f\n",
                                            pPvt->pr->name,pPvt->result.value);
        ret = 1;
    }
    epicsMutexUnlock(pPvt->ringBufferLock);
    return ret;
}
Esempio n. 20
0
static void devSNMPScanThread(void)
{
  ELLLIST *pdevSNMPList = &devSNMPList;
  devSNMPPvt *pSNMPPvt;

  while(!pdevSNMPList->count) {
    epicsThreadSleep(0.5);
  }

  while(TRUE)
    {
      pSNMPPvt = (devSNMPPvt*) ellFirst(pdevSNMPList);
      do {
	epicsMutexLock(pSNMPPvt->mutexId);
	//critical section
	epicsMutexUnlock(pSNMPPvt->mutexId);
	scanIoRequest(pSNMPPvt->ioScanPvt);
      } while( (pSNMPPvt = (devSNMPPvt*) ellNext(&pSNMPPvt->devSNMPNode)) );
      epicsThreadSleep(0.1);
    }
}
Esempio n. 21
0
/* After the PLC is defined with drvEtherIP_define_PLC,
 * tags can be added
 */
TagInfo *drvEtherIP_add_tag(PLC *plc, double period,
                            const char *string_tag, size_t elements)
{
    ScanList *list;
    TagInfo  *info;

    epicsMutexLock(plc->lock);
    if (find_PLC_tag(plc, string_tag, &list, &info))
    {   /* check if period is OK */
        if (list->period > period)
        {   /* current scanlist is too slow */
            remove_ScanList_TagInfo(list, info);
            list = get_PLC_ScanList(plc, period, true);
            if (!list)
            {
                epicsMutexUnlock(plc->lock);
                EIP_printf(2, "drvEtherIP: cannot create list at %g secs"
                           "for tag '%s'\n", period, string_tag);
                return 0;
            }
            add_ScanList_TagInfo(list, info);
        }
        if (info->elements < elements)  /* maximize element count */
            info->elements = elements;
    }
    else
    {   /* new tag */
        list = get_PLC_ScanList(plc, period, true);
        if (list)
            info = add_ScanList_Tag(list, string_tag, elements);
        else
        {
            EIP_printf(2, "drvEtherIP: cannot create list at %g secs"
                       "for tag '%s'\n", period, string_tag);
            info = 0;
        }
    }
    epicsMutexUnlock(plc->lock);
    return info;
}
Esempio n. 22
0
/* ------------------------------------------------------------
 * TagInfo
 * ------------------------------------------------------------ */
static void dump_TagInfo(const TagInfo *info, int level)
{
    char buffer[EIP_MAX_TAG_LENGTH];
    printf("*** Tag '%s' @ 0x%lX:\n", info->string_tag, (unsigned long)info);
    if (level > 3)
    {
        printf("  scanlist            : 0x%lX\n",
               (unsigned long)info->scanlist);
        EIP_copy_ParsedTag(buffer, info->tag);
        printf("  compiled tag        : '%s', %d elements\n",
        	   buffer, (unsigned)info->elements);
        printf("  cip read requ./resp.: %u / %u\n",
        	   (unsigned)info->cip_r_request_size, (unsigned)info->cip_r_response_size);
        printf("  cip write req./resp.: %u / %u\n",
        	   (unsigned)info->cip_w_request_size, (unsigned)info->cip_w_response_size);
        printf("  data_lock ID        : 0x%lX\n",
               (unsigned long) info->data_lock);
    }
    if (epicsMutexLock(info->data_lock) == epicsMutexLockOK)
    {
        if (level > 3)
        {
            printf("  data_size / valid   : %u / %u\n",
            	   (unsigned)info->data_size,  (unsigned)info->valid_data_size);
            printf("  do_write/is_writing : %s / %s\n",
                   (info->do_write ? "yes" : "no"),
                   (info->is_writing ? "yes" : "no"));
            EIP_printf(0, "  data                : ");
        }
        if (info->valid_data_size > 0)
            dump_raw_CIP_data(info->data, info->elements);
        else
            printf("-no data-\n");
        epicsMutexUnlock(info->data_lock);
    }
    else
        printf("  (CANNOT GET DATA LOCK!)\n");
    if (level > 3)
        printf("  transfer time       : %g secs\n", info->transfer_time);
}
Esempio n. 23
0
/** Base method for opening a file
  * Creates the file name with NDPluginBase::createFileName, then calls the pure virtual function openFile
  * in the derived class. */
asynStatus NDPluginFile::openFileBase(NDFileOpenMode_t openMode, NDArray *pArray)
{
    /* Opens a file for reading or writing */
    asynStatus status = asynSuccess;
    char fullFileName[MAX_FILENAME_LEN];
    char errorMessage[256];
    const char* functionName = "openFileBase";

    if (this->useAttrFilePrefix)
        this->attrFileNameSet();

    setIntegerParam(NDFileWriteStatus, NDFileWriteOK);
    setStringParam(NDFileWriteMessage, "");
    status = (asynStatus)createFileName(MAX_FILENAME_LEN, fullFileName);
    if (status) {
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
              "%s:%s error creating full file name, fullFileName=%s, status=%d\n", 
              driverName, functionName, fullFileName, status);
        setIntegerParam(NDFileWriteStatus, NDFileWriteError);
        setStringParam(NDFileWriteMessage, "Error creating full file name");
        return(status);
    }
    setStringParam(NDFullFileName, fullFileName);
    
    /* Call the openFile method in the derived class */
    epicsMutexLock(this->fileMutexId);
    status = this->openFile(fullFileName, openMode, pArray);
    if (status) {
        epicsSnprintf(errorMessage, sizeof(errorMessage)-1, 
            "Error opening file %s, status=%d", fullFileName, status);
        asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, 
              "%s:%s %s\n", 
              driverName, functionName, errorMessage);
        setIntegerParam(NDFileWriteStatus, NDFileWriteError);
        setStringParam(NDFileWriteMessage, errorMessage);
    }
    epicsMutexUnlock(this->fileMutexId);
    
    return(status);
}
Esempio n. 24
0
static int motorAxisMove( AXIS_HDL pAxis, double position, int relative, double min_velocity, double max_velocity, double acceleration )
{

  if (pAxis == NULL) return MOTOR_AXIS_ERROR;
  else
    {
      if (relative) position += pAxis->endpoint.axis[0].p + pAxis->enc_offset;

      /* Check to see if in hard limits */
      if ((pAxis->nextpoint.axis[0].p >= pAxis->hiHardLimit  &&  position > pAxis->nextpoint.axis[0].p) ||
          (pAxis->nextpoint.axis[0].p <= pAxis->lowHardLimit &&  position < pAxis->nextpoint.axis[0].p)  ) return MOTOR_AXIS_ERROR;
      else if (epicsMutexLock( pAxis->axisMutex ) == epicsMutexLockOK)
	{
	  route_pars_t pars;

	  if (pAxis->pDrv->movesDeferred == 0) { /*Normal move.*/
	    pAxis->endpoint.axis[0].p = position - pAxis->enc_offset;
	    pAxis->endpoint.axis[0].v = 0.0;
	  } else { /*Deferred moves.*/
	    pAxis->deferred_position = position;
	    pAxis->deferred_move = 1;
	    pAxis->deferred_relative = relative;
	  }
	  routeGetParams( pAxis->route, &pars );
	  if (max_velocity != 0) pars.axis[0].Vmax = fabs(max_velocity);
	  if (acceleration != 0) pars.axis[0].Amax = fabs(acceleration);
	  routeSetParams( pAxis->route, &pars ); 
	  
          motorParam->setInteger( pAxis->params, motorAxisDone, 0 );
	  motorParam->callCallback( pAxis->params );
	  epicsMutexUnlock( pAxis->axisMutex );

	  pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d move to %f, min vel=%f, max_vel=%f, accel=%f",
                        pAxis->card, pAxis->axis, position, min_velocity, max_velocity, acceleration );
	}

    }
  return MOTOR_AXIS_OK;
}
Esempio n. 25
0
static int motorAxisMove(AXIS_HDL pAxis, double position, int relative,
                         double min_velocity, double max_velocity, double acceleration)
{
    int status;
    char buff[100];
    char *moveCommand;

    if (pAxis == NULL)
        return MOTOR_AXIS_ERROR;

    PRINT(pAxis->logParam, FLOW, "Set card %d, axis %d move to %f, min vel=%f, max_vel=%f, accel=%f\n",
          pAxis->card, pAxis->axis, position, min_velocity, max_velocity, acceleration);

    if (relative) {
        moveCommand = "PR";
    } else {
        moveCommand = "PA";
    }
    sprintf(buff, "%dAC%.*f;%dVA%.*f;%d%s%.*f;",
            pAxis->axis+1, pAxis->maxDigits, acceleration * pAxis->stepSize,
            pAxis->axis+1, pAxis->maxDigits, max_velocity * pAxis->stepSize,
            pAxis->axis+1, moveCommand, pAxis->maxDigits, position * pAxis->stepSize);
    status = sendOnly(pAxis->pController, buff);
    if (status)
        return MOTOR_AXIS_ERROR;

    if (epicsMutexLock(pAxis->mutexId) == epicsMutexLockOK)
    {
        /* Insure that the motor record's next status update sees motorAxisDone = False. */
        motorParam->setInteger(pAxis->params, motorAxisDone, 0);
        motorParam->callCallback(pAxis->params);
        epicsMutexUnlock(pAxis->mutexId);
    }

    /* Send a signal to the poller task which will make it do a poll, and switch to the moving poll rate */
    epicsEventSignal(pAxis->pController->pollEventId);

    return MOTOR_AXIS_OK;
}
Esempio n. 26
0
void  drvEtherIP_add_callback (PLC *plc, TagInfo *info,
                               EIPCallback callback, void *arg)
{
    TagCallback *cb;
    epicsMutexLock(plc->lock);
    for (cb = DLL_first(TagCallback, &info->callbacks);
         cb;  cb = DLL_next(TagCallback, cb))
    {
        if (cb->callback == callback  &&  cb->arg == arg)
        {
            epicsMutexUnlock(plc->lock);
            return;
        }
    }
    /* Add new one */
    if (!(cb = (TagCallback *) malloc(sizeof (TagCallback))))
        return;
    cb->callback = callback;
    cb->arg      = arg;
    DLL_append(&info->callbacks, cb);
    epicsMutexUnlock(plc->lock);
}
Esempio n. 27
0
static int getCallbackValue(devPvt *pPvt)
{
    int ret = 0;
    static const char *functionName="getCallbackValue";

    epicsMutexLock(pPvt->devPvtLock);
    if (pPvt->ringTail != pPvt->ringHead) {
        if (pPvt->ringBufferOverflows > 0) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_WARNING,
                "%s %s::%s warning, %d ring buffer overflows\n",
                                    pPvt->pr->name, driverName, functionName,pPvt->ringBufferOverflows);
            pPvt->ringBufferOverflows = 0;
        }
        pPvt->result = pPvt->ringBuffer[pPvt->ringTail];
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
            "%s %s::%s from ringBuffer value=%f\n",
                                            pPvt->pr->name, driverName, functionName, pPvt->result.value);
        ret = 1;
    }
    epicsMutexUnlock(pPvt->devPvtLock);
    return ret;
}
Esempio n. 28
0
static int motorAxisInit(void)
{
    int controller, axis;

    for (controller = 0; controller < numMM4000Controllers; controller++)
    {
        AXIS_HDL pAxis;
        for (axis = 0; axis < pMM4000Controller[controller].numAxes; axis++)
        {
            pAxis = &pMM4000Controller[controller].pAxis[axis];
            if (!pAxis->mutexId)
                break;
            epicsMutexLock(pAxis->mutexId);

            /*Set GAIN_SUPPORT on so that at least, CNEN functions. */
            motorParam->setInteger(pAxis->params, motorAxisHasClosedLoop, 1);

            motorParam->callCallback(pAxis->params);
            epicsMutexUnlock(pAxis->mutexId);
        }
    }
    return(MOTOR_AXIS_OK);
}
Esempio n. 29
0
/*
 * get the access rights:
 * note that even though there is separate read and write access, the rights
 * as of R3.14.1 are actually [ NONE, READ, and READ/WRITE]. If this changes,
 * things could get interesting.
 */
static void
getAccessRights( struct access_rights_handler_args args)
{
	Channel *chan = ca_puser(args.chid);
	Connector *conp;
	int readAccess, writeAccess;

	readAccess = ca_read_access(chan->chan_id);
	writeAccess = ca_write_access(chan->chan_id);
	chan->writeAccess = writeAccess?1:0;
	chan->readAccess = readAccess?1:0;

	DEBUGP printf("Channel %s read %d write %d\n", chan->chan_name, readAccess, writeAccess);
	/*
	 * user now allowed to write to this PV
	 */
	epicsMutexLock( processFlag);
	for( conp=chan->first_connector; conp; conp=conp->next_chan)
	    if( conp->newAccess)
		(*conp->newAccess)(conp);
	epicsMutexUnlock( processFlag);
	
}
Esempio n. 30
0
static long processAiAverage(aiRecord *pr)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)pr->dpvt;
    double rval;

    epicsMutexLock(pPvt->mutexId);
    if (pPvt->numAverage == 0) {
        recGblSetSevr(pr, UDF_ALARM, INVALID_ALARM);
        pr->udf = 1;
        epicsMutexUnlock(pPvt->mutexId);
        return -2;
    }
    rval = pPvt->sum/pPvt->numAverage;
    /*round result*/
    rval += (pPvt->sum>0.0) ? 0.5 : -0.5;
    pr->rval = (epicsInt32) rval;
    pPvt->numAverage = 0;
    pPvt->sum = 0.;
    epicsMutexUnlock(pPvt->mutexId);
    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::processAiInt32Average rval=%d\n",pr->name, pr->rval);
    pr->udf = 0;
    return 0;
}