Ejemplo n.º 1
0
static void interruptCallbackEnumBo(void *drvPvt, asynUser *pasynUser,
                char *strings[], int values[], int severities[], size_t nElements)
{
    devPvt *pPvt = (devPvt *)drvPvt;
    boRecord *pr = (boRecord *)pPvt->pr;

    if (!interruptAccept) return;
    dbScanLock((dbCommon*)pr);
    setEnums((char*)&pr->znam, NULL, &pr->zsv, 
             strings, NULL, severities, nElements, 2);
    db_post_events(pr, &pr->val, DBE_PROPERTY);
    dbScanUnlock((dbCommon*)pr);
}
Ejemplo n.º 2
0
static void interruptCallbackEnumMbbo(void *drvPvt, asynUser *pasynUser,
                char *strings[], int values[], int severities[], size_t nElements)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    mbboRecord *pr = (mbboRecord *)pPvt->pr;

    if (!interruptAccept) return;
    dbScanLock((dbCommon*)pr);
    setEnums((char*)&pr->zrst, (int*)&pr->zrvl, &pr->zrsv, 
             strings, values, severities, nElements, MAX_ENUM_STATES);
    db_post_events(pr, &pr->val, DBE_PROPERTY);
    dbScanUnlock((dbCommon*)pr);
}
Ejemplo n.º 3
0
/* Callback for bo, see ao_callback comments */
static void check_bo_callback(void *arg)
{
    boRecord      *rec = (boRecord *) arg;
    struct rset   *rset= (struct rset *)(rec->rset);
    DevicePrivate *pvt = (DevicePrivate *)rec->dpvt;
    unsigned long rval;
    eip_bool      process = false;

    /* We are about the check and even set val, & rval -> lock */
    dbScanLock((dbCommon *)rec);
    if (rec->pact)
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    /* Check if record's (R)VAL is current */
    if (!check_data((dbCommon *) rec))
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    if (get_bits((dbCommon *)rec, 1, &rval) &&
        (rec->udf || rec->sevr == INVALID_ALARM || rec->rval != rval))
    {
        if (rec->tpro)
            printf("'%s': got %lu from driver\n", rec->name, rval);
        if (!rec->udf  &&  pvt->special & SPCO_FORCE)
        {
            if (rec->tpro)
                printf("'%s': will re-write record's value %u\n",
                       rec->name, (unsigned int)rec->val);
        }
        else
        {   /* back-convert rval into val */
            rec->rval = rval;
            rec->val  = (rec->rval==0) ? 0 : 1;
            rec->udf = false;
            if (rec->tpro)
                printf("'%s': updated record to tag, val = %u\n",
                       rec->name, (unsigned int)rec->val);
        }
        process = true;
    }
    dbScanUnlock((dbCommon *)rec);
    /* Does record need processing and is not periodic? */
    if (process && rec->scan < SCAN_1ST_PERIODIC)
        scanOnce(rec);
}
Ejemplo n.º 4
0
/* ---------------------------------------------------------------------- */
void myCallback_devAiAsyncGpib(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  dsetLog(3, __FILE__ "[%d] -> %s \n", __LINE__, __func__ );

  callbackGetUser(p_record,p_callback);
  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);	
  dbScanUnlock(p_record);	

  dsetLog(3,  __FILE__ "[%d] <- %s \n", __LINE__, __func__ );
}
Ejemplo n.º 5
0
static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
    epicsTimeStamp now;
    epicsTimeGetCurrent(&now);

    /* If string or array, must make a copy (to ensure coherence between time and data) */
    if (pfl->type == dbfl_type_rec) {
        dbScanLock(dbChannelRecord(chan));
        dbChannelMakeArrayCopy(pvt, pfl, chan);
        dbScanUnlock(dbChannelRecord(chan));
    }

    pfl->time = now;
    return pfl;
}
Ejemplo n.º 6
0
static void checkLinksCallback(CALLBACK *arg)
{

    calcoutRecord *prec;
    rpvtStruct   *prpvt;

    callbackGetUser(prec, arg);
    prpvt = prec->rpvt;

    dbScanLock((dbCommon *)prec);
    prpvt->cbScheduled = 0;
    checkLinks(prec);
    dbScanUnlock((dbCommon *)prec);

}
Ejemplo n.º 7
0
static void myCallback_devAiAsyncGpib(CALLBACK *pcallback) {
  struct dbCommon *precord;
  struct rset *prset;

  dsetLog(3,__FILE__ "[%d] -> %s \n", __LINE__, __func__ );

  callbackGetUser(precord,pcallback);/* Get record attached to callback */
  prset=(struct rset *)(precord->rset);/* get deviceRecord->rset	*/

  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);

  dsetLog(3,__FILE__ "[%d] <- %s \n", __LINE__, __func__ );
  return;
}
Ejemplo n.º 8
0
static void myCallback_devMbboAsyncSerial(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  callbackGetUser(p_record,p_callback);
  dsetLog(3,__FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, p_record->name );

  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);
  dbScanUnlock(p_record);		

  dsetLog(3, __FILE__ "[%d] <- %s\n", __LINE__, __func__);

  return;
} 
Ejemplo n.º 9
0
LOCAL void myCallback(CALLBACK *pCallback)
{
    ab1771IXRecord *precord;
    recordPvt	  *precordPvt;
    int           callLock;

    callbackGetUser(precord,pCallback);
    callLock = interruptAccept;
    if(callLock)dbScanLock((void *)precord);
    precordPvt = precord->dpvt;
    precordPvt->status = (*pabDrv->getStatus)(precordPvt->drvPvt);
    if(precordPvt->status!=abSuccess) {
        switch(precordPvt->msgState) {
	case msgStateWaitInit:
	case msgStateWaitGet:
	    precordPvt->msgState = msgStateInit;
	    break;
        default:
	    errlogPrintf("ILLEGAL myCallback state: record %s\n",precord->name);
	    break;
        }
	issueError(precord,errAb,0);
    } else {
        precordPvt->err = errOK;
        switch(precordPvt->msgState) {
	case msgStateWaitInit:
	    precordPvt->msgState = msgStateGet;
	    break;;
	case msgStateWaitGet:
	    setValMsg(precord,0);
	    msgCompleteGet(precord);
	    issueAsynCallback(precord);
            break;;
        default:
	    errlogPrintf("ILLEGAL myCallback state: record %s\n",precord->name);
	    break;
	}
	if(precordPvt->err == errOK) switch(precordPvt->msgState) {
	    case msgStateInit: msgInit(precord); break;
	    case msgStateGet: msgGet(precord); break;
	    default: break;
	}
    }
    if(precordPvt->err != errOK) issueAsynCallback(precord);
    if(callLock)dbScanUnlock((void *)precord);
}
Ejemplo n.º 10
0
static void myCallback(CALLBACK *pcallback)
{
    ASDBCALLBACK	*pasdbcallback = (ASDBCALLBACK *)pcallback;
    subRecord	*precord;
    struct rset		*prset;

    callbackGetUser(precord,pcallback);
    prset=(struct rset *)(precord->rset);
    precord->val = 0.0;
    if(pasdbcallback->status) {
	recGblSetSevr(precord,READ_ALARM,precord->brsv);
	recGblRecordError(pasdbcallback->status,precord,"asInit Failed");
    }
    dbScanLock((dbCommon *)precord);
    (*prset->process)((dbCommon *)precord);
    dbScanUnlock((dbCommon *)precord);
}
Ejemplo n.º 11
0
static void myCallback(struct callback *pcallback)
{
  struct dbCommon *precord = pcallback->precord;
  struct rset *prset = (struct rset *)(precord->rset);

#ifdef DEBUG1
  printf( __FILE__ "[%d] -> %s\n", __LINE__, __func__ );
#endif

  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);
  
#ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__ );
#endif
}
Ejemplo n.º 12
0
static void controlThreadFunc(void *param)
{

	drvM6802_taskConfig *ptaskConfig = (drvM6802_taskConfig*) param;
	drvM6802_controlThreadConfig *pcontrolThreadConfig;
	controlThreadQueueData		queueData;

	while( !ptaskConfig->pcontrolThreadConfig ) epicsThreadSleep(.1);
	pcontrolThreadConfig = (drvM6802_controlThreadConfig*) ptaskConfig->pcontrolThreadConfig;


	epicsPrintf("task launching: %s thread for %s task\n",pcontrolThreadConfig->threadName, ptaskConfig->taskName);

	while(TRUE) {
		EXECFUNCQUEUE            pFunc;
		execParam                *pexecParam;
		struct dbCommon          *precord;
		struct rset              *prset;

		drvM6802_taskConfig    *ptaskConfig;

		epicsMessageQueueReceive(pcontrolThreadConfig->threadQueueId,
				         (void*) &queueData,
					 sizeof(controlThreadQueueData));

		pFunc      = queueData.pFunc;
	        pexecParam = &queueData.param;	
		precord    = (struct dbCommon*) pexecParam->precord;
		prset      = (struct rset*) precord->rset;
		ptaskConfig = (drvM6802_taskConfig *) pexecParam->ptaskConfig;

		if(!pFunc) continue;
		else pFunc(pexecParam);

		if(!precord) continue;


		dbScanLock(precord);
		(*prset->process)(precord); 
		dbScanUnlock(precord);
	}


	return;
}
Ejemplo n.º 13
0
void prng_cb(CALLBACK* cb)
{
  aiRecord* prec;
  struct prngState* priv;
  struct rset* prset;
  epicsInt32 raw;

  callbackGetUser(prec,cb);
  prset=(struct rset*)prec->rset;
  priv=prec->dpvt;

  raw=rand_r(&priv->seed);

  dbScanLock((dbCommon*)prec);
  prec->rval=raw;
  (*prset->process)(prec);
  dbScanUnlock((dbCommon*)prec);
}
Ejemplo n.º 14
0
/*****************************************************************************
 *
 * Link-group processing function.
 *
 * if the input link is not a constant
 *   call dbGetLink() to get the link value
 * else
 *   get the value from the DOV field
 * call dbPutLink() to forward the value to destination location
 * call processNextLink() to schedule the processing of the next link-group
 *
 * NOTE:
 *   dbScanLock is NOT held for prec when this function is called!!
 *
 ******************************************************************************/
static void processCallback(CALLBACK *arg)
{
  callbackSeq *pcb;
  seqRecord *prec;
  double	myDouble;

  callbackGetUser(pcb,arg);
  prec = pcb->pseqRecord;
  dbScanLock((struct dbCommon *)prec);

  if (seqRecDebug > 5)
    printf("processCallback(%s) processing field index %d\n", prec->name, pcb->index+1);

  /* Save the old value */
  myDouble = pcb->plinks[pcb->index]->dov;

  dbGetLink(&(pcb->plinks[pcb->index]->dol), DBR_DOUBLE,
	&(pcb->plinks[pcb->index]->dov),0,0);

  recGblGetTimeStamp(prec);

  /* Dump the value to the destination field */
  dbPutLink(&(pcb->plinks[pcb->index]->lnk), DBR_DOUBLE,
	&(pcb->plinks[pcb->index]->dov),1);

  if (myDouble != pcb->plinks[pcb->index]->dov)
  {
    if (seqRecDebug > 0)
      printf("link %d changed from %f to %f\n", pcb->index, myDouble, pcb->plinks[pcb->index]->dov);
    db_post_events(prec, &pcb->plinks[pcb->index]->dov, DBE_VALUE|DBE_LOG);
  }
  else
  {
    if (seqRecDebug > 0)
      printf("link %d not changed... %f\n", pcb->index, pcb->plinks[pcb->index]->dov);
  }

  /* Find the 'next' link-seq that is ready for processing. */
  pcb->index++;
  processNextLink(prec);

  dbScanUnlock((struct dbCommon *)prec);
  return;
}
Ejemplo n.º 15
0
static void checkLinksCallback(CALLBACK *pcallback)
{
    acalcoutRecord	*pcalc;
    rpvtStruct		*prpvt;

    callbackGetUser(pcalc, pcallback);
    prpvt = (rpvtStruct *)pcalc->rpvt;
    
	if (!interruptAccept) {
		/* Can't call dbScanLock yet.  Schedule another CALLBACK */
		prpvt->wd_id_1_LOCK = 1;  /* make sure */
		callbackRequestDelayed(&prpvt->checkLinkCb,.5);
	} else {
	    dbScanLock((struct dbCommon *)pcalc);
	    prpvt->wd_id_1_LOCK = 0;
	    checkLinks(pcalc);
	    dbScanUnlock((struct dbCommon *)pcalc);
	}
}
Ejemplo n.º 16
0
long epicsShareAPI dbPutField(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    long	status = 0;
    long	special  = paddr->special;
    dbFldDes	*pfldDes = paddr->pfldDes;
    dbCommon	*precord = paddr->precord;
    short	dbfType  = paddr->field_type;

    if (special == SPC_ATTRIBUTE)
        return S_db_noMod;

    /*check for putField disabled*/
    if (precord->disp &&
        (void *)(&precord->disp) != paddr->pfield)
        return S_db_putDisabled;

    if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK)
        return dbPutFieldLink(paddr, dbrType, pbuffer, nRequest);

    dbScanLock(precord);
    status = dbPut(paddr, dbrType, pbuffer, nRequest);
    if (status == 0) {
        if (paddr->pfield == (void *)&precord->proc ||
            (pfldDes->process_passive &&
             precord->scan == 0 &&
             dbrType < DBR_PUT_ACKT)) {
            if (precord->pact) {
                if (precord->tpro)
                    printf("%s: Active %s\n",
                        epicsThreadGetNameSelf(), precord->name);
                precord->rpro = TRUE;
            } else {
                /* indicate that dbPutField called dbProcess */
                precord->putf = TRUE;
                status = dbProcess(precord);
            }
        }
    }
    dbScanUnlock(precord);
    return status;
}
Ejemplo n.º 17
0
static void devRoboStrParmCallback(asynUser *pasynUser)
{
   dbCommon *pr = (dbCommon *)pasynUser->userPvt;
   devStrParmPvt *pPvt = (devStrParmPvt *)pr->dpvt;
   struct rset *prset = (struct rset *)(pr->rset);

   pPvt->pasynUser->timeout = pPvt->timeout;
   switch(pPvt->opType) {
      case opTypeOutput:
         pPvt->status = pPvt->pasynOctet->write(pPvt->octetPvt, pasynUser, 
                                                pPvt->buffer, strlen(pPvt->buffer), 
                                                &pPvt->nwrite);
         break;
   }
   /* Process the record. This will result in the readXi or writeXi routine
      being called again, but with pact=1 */
   dbScanLock(pr);
   (*prset->process)(pr);
   dbScanUnlock(pr);
}
Ejemplo n.º 18
0
static void myCallbackFunc(CALLBACK *arg)
{
    myCallback *pcallback;
    boRecord *prec;

    callbackGetUser(pcallback,arg);
    prec=(boRecord *)pcallback->precord;
    dbScanLock((struct dbCommon *)prec);
    if(prec->pact) {
	if((prec->val==1) && (prec->high>0)){
	    myCallback *pcallback;
	    pcallback = (myCallback *)(prec->rpvt);
            callbackSetPriority(prec->prio, &pcallback->callback);
            callbackRequestDelayed(&pcallback->callback,(double)prec->high);
	}
    } else {
	prec->val = 0;
	dbProcess((struct dbCommon *)prec);
    }
    dbScanUnlock((struct dbCommon *)prec);
}
Ejemplo n.º 19
0
static void onceTask(void *arg)
{
    taskwdInsert(0, NULL, NULL);
    epicsEventSignal(startStopEvent);

    while (TRUE) {
        void *precord;

        epicsEventMustWait(onceSem);
        while ((precord = epicsRingPointerPop(onceQ))) {
            if (precord == &exitOnce) goto shutdown;
            dbScanLock(precord);
            dbProcess(precord);
            dbScanUnlock(precord);
        }
    }

shutdown:
    taskwdRemove(0);
    epicsEventSignal(startStopEvent);
}
Ejemplo n.º 20
0
/*----------------------------------------------------------------------*/
static void myCallback_devAoAsyncGpib( CALLBACK *pcallback)
{
  struct dbCommon *precord;
  struct rset *prset;

  callbackGetUser(precord,pcallback);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] -> %s(%s)\n", __LINE__ , __func__, precord->name);
  #endif

  prset = (struct rset *)(precord->rset);
  
  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__);
  #endif
}
Ejemplo n.º 21
0
static void myCallback_devAiAsyncSerial(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  #ifdef DEBUG1
  printf(__FILE__ "[%d] -> %s\n", __LINE__, __func__ );
  #endif

  callbackGetUser(p_record,p_callback);
  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);
  dbScanUnlock(p_record);		

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__);
  #endif

  return;

} /* end_of_myCallback */
Ejemplo n.º 22
0
static void devAiHeidND261Callback(asynUser *pasynUser)
{
	dbCommon *pr = (dbCommon *)pasynUser->userPvt;
	aiRecord* pai = (aiRecord*) pr;
	devAiHeidND261Pvt *pPvt = (devAiHeidND261Pvt *)pr->dpvt;
	struct rset *prset = (struct rset *)(pr->rset);
    int eomReason;

	pPvt->pasynUser->timeout = pPvt->timeout;
	pPvt->status = pPvt->pasynOctet->write(pPvt->octetPvt, pasynUser, 
		pPvt->outbuf, 2, &pPvt->nwrite);
	pPvt->pasynOctet->setInputEos(pPvt->octetPvt, pasynUser, pPvt->term, pPvt->termlen);
	pPvt->status = pPvt->pasynOctet->read(pPvt->octetPvt, pasynUser, 
		pPvt->inbuf, pPvt->nchar, &pPvt->nread, &eomReason);


    pai->udf = 0;

	dbScanLock(pr);
	(*prset->process)(pr);
	dbScanUnlock(pr);
}
Ejemplo n.º 23
0
/*
 *  Process a record without printing it.
 */
long epicsShareAPI dbprc(char *record_name)
{
  struct dbAddr addr;
  struct dbCommon *precord;
  long status;

 /*
  *  Convert name to address
  */
  status = dbNameToAddr(record_name, &addr);
  if (status == S_db_notFound)
      printf("   BKPT> Record %s not found\n", record_name);
  if (status != 0) return(status);

  precord = addr.precord;

 /* lock lockset, process record, unlock lockset */
  dbScanLock(precord);
  status = dbProcess(precord);
  dbScanUnlock(precord);

  return(status);
}
Ejemplo n.º 24
0
static void outputCallbackCallback(CALLBACK *pcb)
{
    devPvt *pPvt; 
    static const char *functionName="outputCallbackCallback";

    callbackGetUser(pPvt, pcb);
    {
        dbCommon *pr = pPvt->pr;
        dbScanLock(pr);
        pPvt->newOutputCallbackValue = 1;
        dbProcess(pr);
        if (pPvt->newOutputCallbackValue != 0) {
            /* We called dbProcess but the record did not process, perhaps because PACT was 1 
             * Need to remove ring buffer element */
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, 
                "%s %s::%s warning dbProcess did not process record, PACT=%d\n", 
                pr->name, driverName, functionName,pr->pact);
            getCallbackValue(pPvt);
            pPvt->newOutputCallbackValue = 0;
        }
        dbScanUnlock(pr);
    }
}
Ejemplo n.º 25
0
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsUInt32 value)
{
    devPvt *pPvt = (devPvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    ringBufferElement *rp;
    static const char *functionName="interruptCallbackOutput";

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s %s::%s new value=%u\n",
        pr->name, driverName, functionName, value);
    if (!interruptAccept) return;
    dbScanLock(pr);
    epicsMutexLock(pPvt->ringBufferLock);
    rp = &pPvt->ringBuffer[pPvt->ringHead];
    rp->value = value;
    rp->time = pasynUser->timestamp;
    rp->status = pasynUser->auxStatus;
    rp->alarmStatus = pasynUser->alarmStatus;
    rp->alarmSeverity = pasynUser->alarmSeverity;
    pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1;
    if (pPvt->ringHead == pPvt->ringTail) {
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        pPvt->ringBufferOverflows++;
    } else {
        /* If PACT is true then this callback was received during asynchronous record processing
         * Must defer calling callbackRequest until end of record processing */
        if (pr->pact) {
            pPvt->numDeferredOutputCallbacks++;
        } else { 
            callbackRequest(&pPvt->outputCallback);
        }
    }
    epicsMutexUnlock(pPvt->ringBufferLock);
    dbScanUnlock(pr);
}
Ejemplo n.º 26
0
static void initConversionTask(void* parm)
{
    int qstatus;
    void *sub;
    struct reinitMsg msg;
    struct cvtRecord *pcvt;
    long status;

    while (TRUE) {
        qstatus = epicsMessageQueueReceive(
            initConversionQ, (void*)&msg, REINIT_MSG_SIZE);
        if (qstatus == -1) {
            nerrmsg("", "msgQReceive failed");
            continue;
        }
        pcvt = msg.record;
        status = initConversion(pcvt->name, msg.bdir, msg.tdir, msg.meth, msg.spec, &sub);
        dbScanLock((struct dbCommon *)pcvt);
        if (status && pcvt->ista != menuCvtInitStateAgain) {
            if (pcvt->ista != menuCvtInitStateError) {
                pcvt->ista = menuCvtInitStateError;
                pcvt->drty |= DRTY_ISTA;
            }
        }
        else {
            switch (pcvt->ista) {
            case menuCvtInitStateInProgress:
            case menuCvtInitStateError:
                pcvt->ista = menuCvtInitStateDone;
                pcvt->drty |= DRTY_ISTA;
                /* free old csub if it was a csm_function... */
                if (pcvt->meth == menuCvtMethod1DTable
                    || pcvt->meth == menuCvtMethod1DTableInverted
                    || pcvt->meth == menuCvtMethod2DTable) {
                    csm_function *csub = (csm_function *)pcvt->csub;
                    if (csub) {
                        /* check because it might have never been created */
                        csm_free(csub);
                    }
                }
                /* ...and write the new values back into the record */
                pcvt->meth = msg.meth;
                pcvt->drty |= DRTY_METH;
                strncpy(pcvt->spec, msg.spec, SPEC_SIZE);
                pcvt->drty |= DRTY_SPEC;
                strncpy(pcvt->bdir, msg.bdir, BDIR_SIZE);
                pcvt->drty |= DRTY_BDIR;
                strncpy(pcvt->tdir, msg.tdir, TDIR_SIZE);
                pcvt->drty |= DRTY_TDIR;
                pcvt->csub = sub;
                break;
            case menuCvtInitStateAgain:
                if (!status && sub && (
                    pcvt->meth == menuCvtMethod1DTable
                    || pcvt->meth == menuCvtMethod1DTableInverted
                    || pcvt->meth == menuCvtMethod2DTable)) {
                    csm_free((csm_function *)sub);
                }
                /* even if initConversion(...) above failed, we go here */
                if (reinitConversion(pcvt)) {
                    /* this is fatal */
                    pcvt->ista = menuCvtInitStateError;
                    pcvt->drty |= DRTY_ISTA;
                    pcvt->pact = TRUE;
                    break;
                }
                pcvt->ista = menuCvtInitStateInProgress;
                pcvt->drty |= DRTY_ISTA;
                break;
            case menuCvtInitStateDone:
                errmsg("internal error: unexpected "
                    "value <menuCvtInitStateDone> in field ISTA");
                pcvt->pact = TRUE;
                break;
            default:
                errmsg("internal error: ISTA is not a member of menuCvtMethod");
                pcvt->pact = TRUE;
            }
        }
        checkAlarms(pcvt);
        monitor(pcvt);
        dbScanUnlock((struct dbCommon *)pcvt);
    }
}
Ejemplo n.º 27
0
/*
 *  Remove breakpoint from a record
 *     1. Convert name to address and check breakpoint mask.
 *     2. Lock database and take stack semaphore.
 *     3. Find structure for record's lockset (in stack).
 *     4. Find and delete record from breakpoint list.
 *     5. Turn off break point field.
 *     6. Give up semaphore to "signal" bkptCont task to quit.
 */
long epicsShareAPI dbd(const char *record_name)
{
  struct dbAddr addr;
  struct LS_LIST *pnode;
  struct BP_LIST *pbl;
  struct dbCommon *precord;
  long status;

 /*
  *  Convert name to address
  */
  status = dbNameToAddr(record_name, &addr);
  if (status == S_db_notFound)
      printf("   BKPT> Record %s not found\n", record_name);
  if (status != 0) return(status);

  precord = addr.precord;

  if (! precord->bkpt & BKPT_ON_MASK) {
      printf("   BKPT> No breakpoint set in this record\n");
      return(S_db_bkptNotSet);
  }

  dbScanLock(precord);

  epicsMutexMustLock(bkpt_stack_sem);

  FIND_LOCKSET(precord, pnode);

  if (pnode == NULL) {
     /* not found, error ! */
     printf("   BKPT> Logic Error in dbd()\n");
     precord->bkpt &= BKPT_OFF_MASK;

     epicsMutexUnlock(bkpt_stack_sem);
     dbScanUnlock(precord);
     return(S_db_bkptLogic);
  }

 /*
  *  Remove record from breakpoint list
  */

 /* find record in list */
  pbl = (struct BP_LIST *) ellFirst(&pnode->bp_list);
  while (pbl != NULL) {
     if (pbl->precord == precord) {
         ellDelete(&pnode->bp_list, (ELLNODE *)pbl);
         free(pbl);
         break;
     }
     pbl = (struct BP_LIST *) ellNext((ELLNODE *)pbl);
  }

  if (pbl == NULL) {
     printf("   BKPT> Logic Error in dbd()\n"); 
     precord->bkpt &= BKPT_OFF_MASK;
     epicsMutexUnlock(bkpt_stack_sem);
     dbScanUnlock(precord);
     return(S_db_bkptLogic);
  }

 /*
  *  Turn off breakpoint field in record
  */
  precord->bkpt &= BKPT_OFF_MASK;

 /*
  *  If there are no more breakpoints, give up semaphore
  *    to cause the bkptCont task to quit.
  */
  if (ellCount(&pnode->bp_list) == 0)
     epicsEventSignal(pnode->ex_sem);

  epicsMutexUnlock(bkpt_stack_sem);

  dbScanUnlock(precord);
  return(0);
}
Ejemplo n.º 28
0
/*
 *  Task for continuing record processing
 *     1. Find lockset in stack for precord.
 *       DO 2-3 while breakpoints exist in the lockset.
 *        2. Wait on execution semaphore ...
 *        3. Run through every entrypoint in queue, processing
 *             those that are scheduled.
 *     4. Free resources for lockset, and exit task.
 */
static void dbBkptCont(dbCommon *precord)
{
  struct LS_LIST *pnode;
  struct EP_LIST *pqe = NULL;

 /*
  *  Reset breakpoint, process record, and
  *    reset bkpt field in record
  */
  epicsMutexMustLock(bkpt_stack_sem);

  FIND_LOCKSET(precord, pnode);

  if (pnode == NULL) {
    printf("   BKPT> Logic error in dbBkptCont()\n");
    return;
  }

 /*
  *  For every entrypoint scheduled, process.  Run process
  *    until there are no more breakpoints remaining in a
  *    lock set.
  */
  do {
   /* Give up semaphore before waiting to run ... */
    epicsMutexUnlock(bkpt_stack_sem);

   /* Wait to run */
    epicsEventMustWait(pnode->ex_sem);

   /* Bkpt stack must still be stable ! */
    epicsMutexMustLock(bkpt_stack_sem);

    pqe = (struct EP_LIST *) ellFirst(&pnode->ep_queue);

   /* Run through entrypoint queue */
    while (pqe != NULL) {
        /* check if entrypoint is currently scheduled */
         if (pqe->sched) {
             /* save current entrypoint */
              pnode->current_ep = pqe->entrypoint;

             /* lock the lockset, process record, unlock */
              dbScanLock(precord);
              dbProcess(pqe->entrypoint);
              dbScanUnlock(precord);

             /* reset schedule and stepping flag - Do this AFTER processing */
              pqe->sched = 0;
              pnode->step = 0;
         }
         pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe);
    }

   /* Reset precord. (Since no records are at a breakpoint) */
    pnode->precord = NULL;
  } while (ellCount(&pnode->bp_list) != 0);

 /* remove node from lockset stack */
  ellDelete(&lset_stack, (ELLNODE *)pnode);
  --lset_stack_count;

 /* free entrypoint queue */
  ellFree(&pnode->ep_queue);

 /* remove execution semaphore */
  epicsEventDestroy(pnode->ex_sem);

  printf("\n   BKPT> End debug of lockset %lu\n-> ", pnode->l_num);

 /* free list node */
  free(pnode);

  epicsMutexUnlock(bkpt_stack_sem);
}
Ejemplo n.º 29
0
/*
 * Process breakpoint
 *  Returns a zero if dbProcess() is to execute
 *  record support, a one if dbProcess() is to
 *  skip over record support.  See dbProcess().
 *
 *  1.  See if there is at least a breakpoint set somewhere
 *        in precord's lockset.  If not, return immediately.
 *  2.  Check the disable flag.
 *  3.  Add entry points to the queue for future stepping and
 *        schedule new entrypoints for the continuation task.
 *  4.  Check the pact flag.
 *  5.  Check to see if there is a breakpoint set in a record, and
 *        if so, turn on stepping mode.
 *  6.  If stepping mode is set, stop and report the breakpoint.
 */
int epicsShareAPI dbBkpt(dbCommon *precord)
{
  struct LS_LIST *pnode;
  struct EP_LIST *pqe;

 /*
  *  It is crucial that operations in dbBkpt() execute
  *    in the correct order or certain features in the
  *    breakpoint handler will not work as expected.
  */

 /*
  *  Take and give a semaphore to check for breakpoints
  *	every time a record is processed.  Slow.  Thank
  *	goodness breakpoint checking is turned off during
  *	normal operation.
  */
  epicsMutexMustLock(bkpt_stack_sem);
  FIND_LOCKSET(precord, pnode);
  epicsMutexUnlock(bkpt_stack_sem);

  if (pnode == NULL) {
    /* no breakpoints in precord's lockset */
     return(0);
  }

 /* Check disable flag */
  dbGetLink(&(precord->sdis),DBR_SHORT,&(precord->disa),0,0);
  if (precord->disa == precord->disv) {
     /*
      *  Do not process breakpoints if the record is disabled,
      *    but allow disable alarms.  Alarms will be raised
      *    in dbProcess() because returning 0 allows dbProcess()
      *    to continue.  However processing will be prevented
      *    because disa and disv will be examined again in
      *    dbProcess(). Note that checking for pact will occur
      *    before checking for disa and disv in dbProcess().
      */
      return(0);
  }

 /*
  *  Queue entry points for future stepping.  The taskid comparison
  *    is used to determine if the source of processing is the
  *    continuation task or an external source. If it is an external
  *    source, queue its execution, but dump out of dbProcess without
  *    calling record support. 
  */
  if (pnode->taskid && (epicsThreadGetIdSelf() != pnode->taskid)) {
    /* CONTINUE TASK CANNOT ENTER HERE */

    /*
     *  Add an entry point to queue, if it does
     *    not already exist.
     */
     FIND_QUEUE_ENTRY(&pnode->ep_queue, pqe, precord);
 
     if (pqe == NULL) {

        pqe = (struct EP_LIST *) malloc(sizeof(struct EP_LIST));
        if (pqe == NULL)
             return(1);


        pqe->entrypoint = precord;
        pqe->count = 1;
        epicsTimeGetCurrent(&pqe->time);
        pqe->sched = 0;

#ifdef BKPT_DIAG
        printf("   BKPT> Adding entrypoint %s to queue\n", precord->name);
#endif

       /*
        *  Take semaphore, wait on continuation task
        */
        epicsMutexMustLock(bkpt_stack_sem);

       /* Add entry to queue */
        ellAdd(&pnode->ep_queue, (ELLNODE *)pqe);

        epicsMutexUnlock(bkpt_stack_sem);
     }
     else {
        if (pqe->count < MAX_EP_COUNT)
           pqe->count++;
     }

    /* check pact */
     if (! precord->pact) {
       /* schedule if pact not set */
        pqe->sched = 1;

       /*
        *  Release the semaphore, letting the continuation
        *     task begin execution of the new entrypoint.
        */ 
        epicsEventSignal(pnode->ex_sem);
     }
     return(1);
  }

 /*
  *  Don't mess with breakpoints if pact set!  Skip
  *    over rest of dbProcess() since we don't want
  *    alarms going off.  The pact flag is checked
  *    AFTER entry point queuing so that the record
  *    timing feature will work properly.
  */
  if (precord->pact)
     return(1);

 /* Turn on stepping mode if a breakpoint is found */
  if (precord->bkpt & BKPT_ON_MASK) {
     pnode->step = 1;

#ifdef BKPT_DIAG
     printf("   BKPT> Bkpt detected: %s\n", precord->name);
#endif
  }

 /*
  *  If we are currently stepping through the lockset,
  *    suspend task.
  */
  if (pnode->step) {
      printf("\n   BKPT> Stopped at:  %s  within Entrypoint:  %s\n-> ",
                 precord->name, pnode->current_ep->name);

      pnode->precord = precord;

     /* Move current lockset to top of stack */
      ellDelete(&lset_stack, (ELLNODE *)pnode);
      ellInsert(&lset_stack, NULL, (ELLNODE *)pnode);
     /*
      *  Unlock database while the task suspends itself.  This
      *   is done so that dbb() dbd() dbc() dbs() may be used
      *   when the task is suspended.  Scan tasks that also
      *   use the scan lock feature will not be hung during
      *   a breakpoint, so that records in other locksets will
      *   continue to be processed.  Cross your fingers, this
      *   might actually work !
      */
      epicsMutexUnlock(bkpt_stack_sem);
      dbScanUnlock(precord);
      epicsThreadSuspendSelf();
      dbScanLock(precord);
      epicsMutexMustLock(bkpt_stack_sem);
   }
   return(0);
}
Ejemplo n.º 30
0
static void devVacSenCallback(asynUser *pasynUser)
{
    dbCommon *pr = (dbCommon *)pasynUser->userPvt;
    devVacSenPvt *pPvt = (devVacSenPvt *)pr->dpvt;
    char readBuffer[vacSen_SIZE];
    char responseBuffer[vacSen_BUFFER_SIZE];
    struct rset *prset = (struct rset *)(pr->rset);
    int i, nread;
    char *pstartdata=0;
    char addcmd[3];

    pPvt->pasynUser->timeout = vacSen_TIMEOUT;

/*
*  VacSen on normal cycle should get status from all the values.
*   For commands issued the sendBuf will have a finite value.
*/
    if (pPvt->command) {
        devVacSenWriteRead(pasynUser, pPvt->sendBuf,readBuffer,&nread);
    
        if (nread < 1 ) {
            asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Cmd reply too small=%d\n", 
                  pr->name, nread);
            goto finish;
        }
	/* for GP307 */
	if (pPvt->devType == 0) {	
            if (strcmp(readBuffer,"OK") != 0 ) {
            	asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Cmd reply has error=[%s]\n", 
                  pr->name, readBuffer);
	    	recGblSetSevr(pr, READ_ALARM, INVALID_ALARM);
            	goto finish;
            }
	/* for GP350 */
	} else if (pPvt->devType == 1) {	
            if (readBuffer[0] =='?') {
            	asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Cmd reply has error=[%s]\n", 
                  pr->name, readBuffer);
	    	recGblSetSevr(pr, READ_ALARM, INVALID_ALARM);
            	goto finish;
            }
	} 
    }

/*   Now start the various reads ......
 *   make sure to check the devType and send the correct set of commands
 *   devType ->  0 = GP307, 1=GP350, 2=MM200
 *   GP307 and GP350 have only 6 commands while MM200 has 8 commands
 *   The data will be packed into responseBuf separated by ",".

 *   The locations are as follows for GP307 and GP350
 *   the one character doesnt work. so we use "PCS" for GP307 and "PC S" for GP350
 *	307 = x,x,x,x,x,x<cr><lf>     350=# xxxx     <cr>  where x=1 or 0
 *   responseBuffer[0-14]       = SetPoint Status
 *   responseBuffer[15]      = Degas Status 0 or 1
 *   responseBuffer[20-29]   = IG1 pressure  x.xxE-xx
 *   responseBuffer[30-39]   = IG2 pressure  x.xxE-xx
 *   responseBuffer[40-49]   = CG1 pressure  x.xxE-xx
 *   responseBuffer[50-59]   = CG2 pressure  x.xxE-xx
 
 *   The locations are as follows for MM200
 *   responseBuffer[0-9]    = SetPoint Status in 2 char with 2nd char for low 4
 *   responseBuffer[10-19]  = CC pressure  n=x.xx-(+)eT
 *   responseBuffer[20-29   = CG1 pressure n=x.xx-(+)eT
 *   responseBuffer[30-39]  = CG2 pressure n=x.xx-(+)eT  ( if pressent)
 *   responseBuffer[40-49]  = SP1/2 pressure  x.x-(+)e or x.xx-(+)e
 *   responseBuffer[50-59]  = SP3/4 pressure  x.x-(+)e or x.xx-(+)e
 *   responseBuffer[60-69]  = SP5/6 pressure  x.x-(+)e or x.xx-(+)e
 *   responseBuffer[70-79]  = SP7/8 pressure  x.x-(+)e or x.xx-(+)e
*/ 
    memset(responseBuffer, 0, vacSen_BUFFER_SIZE);

    for (i=0;i<8;i++) {
	/*  check for GP307 and GP350 and exit when commands are done */	
	if (i > 5 && pPvt->devType < 2)  continue;
	/*  check for CV2 nonexistance and skip*/	
	if (pPvt->devType ==2 && i==3 && pPvt->cv2==0) continue;
	/* for MM200 if no of setpoints is only 2 then skip */
	if (pPvt->devType ==2 && pPvt->noSPT==2 && i>5) continue;
	
	strcpy( pPvt->sendBuf,pPvt->cmdPrefix);
	strcat( pPvt->sendBuf,readCmdString[i+(pPvt->devType *10)]);

	/* for MM200 we have to add the station number to command */
  	if (pPvt->devType == 2) {
	    switch (i) {
		case 1:
		    sprintf(addcmd,"%d",pPvt->cc);
		    break;
		case 2:
		    sprintf(addcmd,"%d",pPvt->cv1);
		    break;
		case 3:
		    sprintf(addcmd,"%d",pPvt->cv2);
		    break;
		case 4:
		    sprintf(addcmd,"%dN",pPvt->cv1);
		    break;
		case 5:
		    sprintf(addcmd,"%dN",(2 + pPvt->cv1));
		    break;
		case 6:
		    sprintf(addcmd,"%dN",(4 + pPvt->cv1));
		    break;
		case 7:
		    sprintf(addcmd,"%dN",(6 + pPvt->cv1));
		    break;
		default:
		    strcpy(addcmd,"");
		break;
	    }
 	    strcat(pPvt->sendBuf,addcmd);
	}

	devVacSenWriteRead(pasynUser, pPvt->sendBuf,readBuffer,&nread);
        if (nread < 1) {
            asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Read reply too small=%d\n", 
                  pr->name, nread);
	    pPvt->errCount++;
            goto finish;
        }

/*
*   For Problems:
*     For GP307 series sends out message with the words ERROR at the end
*     For GP350 series all error messages start with ? instead of *
*     Lets look for these and set the alarm on the record if problems.
*     For GP350 lets strip the leading character and the space [*]
*     For MM200 the reply is "x?" where x=ACDLNORS
*/              
	/* for GP307 */	
	if (pPvt->devType ==0) {
	    pstartdata = &readBuffer[nread-5];
            if (strcmp(pstartdata,"ERROR") == 0 ) {
            	asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Read reply has error=[%s]\n", 
                  pr->name, readBuffer);
	    	pPvt->errCount++;
            	goto finish;
            }
            pstartdata = &readBuffer[0];

	/* for GP350 */
	} else if (pPvt->devType == 1) {    
            if (readBuffer[0] =='?') {
            	asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Read reply has error=[%s]\n", 
                  pr->name, readBuffer);
	    	pPvt->errCount++;
            	goto finish;
	    }
	    /* strip off the headers */
            pstartdata = &readBuffer[2]; 

	/* for MM200 */
	} else if (pPvt->devType == 2) {      
            if (readBuffer[1] =='?') {
            	asynPrint(pasynUser, ASYN_TRACE_ERROR,
                  "devVacSen::devVacSenCallback %s Read reply has error=[%s]\n", 
                  pr->name, readBuffer);
	        pPvt->errCount++;
            	goto finish;
	    }
	    /* Figure out how many relays are there based on reply */
	    if(i==0) {
	        if(readBuffer[0] == 'n')
	            pPvt->noSPT = 2;
	    	else 
	            pPvt->noSPT = 4;
	    }
 	    pstartdata = &readBuffer[0];
	}
	/* for Degas alone move the data by 5 to accomadate GP307 PCS */
        if (pPvt->devType < 2 && i==1)
	    strcpy(&responseBuffer[15],pstartdata);
	else
	    strcpy(&responseBuffer[10*i],pstartdata);
	
    }
    /* for successful read set errCount=0 */
    pPvt->errCount=0;    

/* Process the record. This will result in the readWrite_vs routine
*       being called again, but with pact=1 
*/
finish:
    memset(pPvt->recBuf, 0, vacSen_BUFFER_SIZE);
    memcpy(pPvt->recBuf, responseBuffer, vacSen_BUFFER_SIZE);
    dbScanLock(pr);
    (*prset->process)(pr);
    dbScanUnlock(pr);
}