示例#1
0
文件: dbNotify.c 项目: ukaea/epics
void epicsShareAPI dbNotifyCompletion(dbCommon *precord)
{
    putNotify	*ppn = precord->ppn;
    putNotifyPvt *pputNotifyPvt;

    epicsMutexMustLock(pnotifyGlobal->lock);
    assert(ppn);
    assert(precord->ppnr);
    pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt;
    if(pputNotifyPvt->state!=putNotifyRestartInProgress
    && pputNotifyPvt->state!=putNotifyPutInProgress) {
        epicsMutexUnlock(pnotifyGlobal->lock);
        return;
    }
    ellSafeDelete(&pputNotifyPvt->waitList,&precord->ppnr->waitNode);
    if((ellCount(&pputNotifyPvt->waitList)!=0)) {
        restartCheck(precord->ppnr);
    } else if(pputNotifyPvt->state == putNotifyPutInProgress) {
        pputNotifyPvt->state = putNotifyUserCallbackRequested;
        restartCheck(precord->ppnr);
        callbackRequest(&pputNotifyPvt->callback);
    } else if(pputNotifyPvt->state == putNotifyRestartInProgress) {
        pputNotifyPvt->state = putNotifyRestartCallbackRequested;
        callbackRequest(&pputNotifyPvt->callback);
    } else {
        cantProceed("dbNotifyCompletion illegal state");
    }
    epicsMutexUnlock(pnotifyGlobal->lock);
}
示例#2
0
void
evgSoftSeq::abort(bool callBack) {
    if(!isLoaded() && !isEnabled())
        return;

    // Prevent re-trigger
    m_seqRam->setRunMode(Single);
    m_seqRam->setTrigSrc(None);

    m_seqRam->reset();
    m_isEnabled = false;
    if(mrmEVGSeqDebug)
        fprintf(stderr, "SS%u: Abort!\n",m_id);
    scanIoRequest(ioscanpvt);

    if(callBack) {
        /*
             * Satisfy any callback request pending on irqStop0 or irqStop1
             * recList. As no 'End of sequence' Intrrupt will be generated. 
             */
        if(m_seqRam->getId() == 0)
            callbackRequest(&m_owner->irqStop0_cb);
        else
            callbackRequest(&m_owner->irqStop1_cb);
    }
}
示例#3
0
static long processLo(longoutRecord *pr)
{
    devPvt *pPvt = (devPvt *)pr->dpvt;
    asynStatus status;

    if(pPvt->newOutputCallbackValue && getCallbackValue(pPvt)) {
        /* We got a callback from the driver */
        if (pPvt->result.status == asynSuccess) {
            pr->val = pPvt->result.value & pPvt->mask;
            pr->udf = 0;
        }
    } else if(pr->pact == 0) {
        pPvt->result.value = pr->val & pPvt->mask;
        if(pPvt->canBlock) pr->pact = 1;
        status = pasynManager->queueRequest(pPvt->pasynUser, 0, 0);
        if((status==asynSuccess) && pPvt->canBlock) return 0;
        if(pPvt->canBlock) pr->pact = 0;
        reportQueueRequestStatus(pPvt, status);
    }
    pasynEpicsUtils->asynStatusToEpicsAlarm(pPvt->result.status, 
                                            WRITE_ALARM, &pPvt->result.alarmStatus,
                                            INVALID_ALARM, &pPvt->result.alarmSeverity);
    recGblSetSevr(pr, pPvt->result.alarmStatus, pPvt->result.alarmSeverity);
    if (pPvt->numDeferredOutputCallbacks > 0) {
        callbackRequest(&pPvt->outputCallback);
        pPvt->numDeferredOutputCallbacks--;
    }
    pPvt->newOutputCallbackValue = 0;
    if(pPvt->result.status == asynSuccess) {
        return 0;
    }
    else {
        return -1;
    }
}
示例#4
0
文件: seqRecord.c 项目: ukaea/epics
/*****************************************************************************
 *
 * Find the next link-group that needs processing.
 *
 * If there are no link-groups left to process
 *   call bdProcess() to complete the async record processing.
 * else
 *   if the delay is > 0 seconds
 *     schedule the watch dog task to wake us up later
 *   else
 *     invoke the watch-dog wakeup routine now
 *
 *
 * NOTE:
 *   dbScanLock is already held for prec before this function is called.
 *
 ******************************************************************************/
static int processNextLink(seqRecord *prec)
{
  callbackSeq   *pcb = (callbackSeq *) (prec->dpvt);

  if (seqRecDebug > 5)
    printf("processNextLink(%s) looking for work to do, index = %d\n", prec->name, pcb->index);

  if (pcb->plinks[pcb->index] == NULL)
  {
    /* None left, finish up. */
    (*(struct rset *)(prec->rset)).process(prec);
  }
  else
  {
    if (pcb->plinks[pcb->index]->dly > 0.0)
    {
      callbackRequestDelayed( &pcb->callback,pcb->plinks[pcb->index]->dly);
    }
    else
    {
      /* No delay, do it now.  Avoid recursion by using the callback task */
      callbackRequest(&pcb->callback);
    }
  }
  return(0);
}
示例#5
0
void
bufRxManager::receive(epicsUInt8* raw,unsigned int usedlen)
{
    /* CONTAINER doesn't work when the member is a pointer
     * because the GNU version's check isn't correct
    buffer *buf=CONTAINER(raw, buffer, data);
     */
    buffer *buf=(buffer*)((char*)(raw) - offsetof(buffer, data));

    if (usedlen>bsize())
        throw std::out_of_range("User admitted overflowing Rx buffer");
    buf->used=usedlen;

    if (usedlen==0) {
        // buffer returned w/o being used
        {
            SCOPED_LOCK(guard);
            ellAdd(&freebufs, &buf->node);
        }
        return;
    }

    {
        SCOPED_LOCK(guard);
        ellAdd(&usedbufs, &buf->node);
    }

    callbackRequest(&received_cb);
}
示例#6
0
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsFloat64 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=%f\n",
        pr->name, driverName, functionName,value);
    if (!interruptAccept) return;
    epicsMutexLock(pPvt->devPvtLock);
    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 this callback was received during asynchronous record processing
         * we must defer calling callbackRequest until end of record processing */
        if (pPvt->asyncProcessingActive) {
            pPvt->numDeferredOutputCallbacks++;
        } else { 
            callbackRequest(&pPvt->outputCallback);
        }
    }
    epicsMutexUnlock(pPvt->devPvtLock);
}
示例#7
0
static
void xycom566isr(void *arg)
{
  xy566 *card=arg;
  epicsUInt16 csr;
  csr=READ16(card->base, XY566_CSR);
  if(!(csr&XY566_CSR_PND))
    return; /* not ours */

  if(card->use_seq_clk)
    WRITE8(card->base, XY566_STC, 0xC2); /* Disarm Seq. trig clock */
  
  /* Disable sequence controller, acknowledge
   * interrupts, and schedule further processing
   * out of interrupt context
   */

  csr&=~XY566_CSR_SEQ; /* disable seq. cont. */

  /* writing back what was read will clear any pending
   * interrupts
   */

  WRITE16(card->base, XY566_CSR, csr);

  callbackRequest(&card->cb_irq);

  return;
}
示例#8
0
/**************************************************
* scalerISR()
***************************************************/
STATIC void scalerISR(int card)
{
	volatile char *addr;
	uint16 value;	

	Debug(5, "%s", "scalerISR: entry\n");
	if ((card+1) > scaler_total_cards) return;

	addr = scaler_state[card]->localAddr;
	/* disable interrupts during processing */
	value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) & 0x7f;
	writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value);

	/* clear interrupt */
	writeReg16(addr,IRQ_RESET_OFFSET, 0);

	/* tell record support the hardware is done counting */
	scaler_state[card]->done = 1;

	/* get the record processed */
	callbackRequest(scaler_state[card]->pcallback);

	/* enable interrupts */
	value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) | 0x80;
	writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value);

	return;
}
示例#9
0
void
evgMrm::isr(void* arg) {
    evgMrm *evg = (evgMrm*)(arg);

    epicsUInt32 flags = READ32(evg->m_pReg, IrqFlag);
    epicsUInt32 enable = READ32(evg->m_pReg, IrqEnable);
    epicsUInt32 active = flags & enable;
    
    if(!active)
        return;
    
    if(active & EVG_IRQ_STOP_RAM(0)) {
        if(evg->irqStop0_queued==0) {
            callbackRequest(&evg->irqStop0_cb);
            evg->irqStop0_queued=1;
        } else if(evg->irqStop0_queued==1) {
            WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_STOP_RAM(0));
            evg->irqStop0_queued=2;
        }
    }

    if(active & EVG_IRQ_STOP_RAM(1)) {
        if(evg->irqStop1_queued==0) {
            callbackRequest(&evg->irqStop1_cb);
            evg->irqStop1_queued=1;
        } else if(evg->irqStop1_queued==1) {
            WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_STOP_RAM(1));
            evg->irqStop1_queued=2;
        }
    }

    if(active & EVG_IRQ_EXT_INP) {
        if(evg->irqExtInp_queued==0) {
            callbackRequest(&evg->irqExtInp_cb);
            evg->irqExtInp_queued=1;
        } else if(evg->irqExtInp_queued==1) {
            WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_EXT_INP);
            evg->irqExtInp_queued=2;
        }
    }

    WRITE32(evg->m_pReg, IrqFlag, flags);  // Clear the interrupt causes
    READ32(evg->m_pReg, IrqFlag);          // Make sure the clear completes before returning
    return;
}
示例#10
0
/*CODE that interacts with drvAb*/
LOCAL void drvCallback(void *drvPvt)
{
    ab1771IXRecord *precord;
    recordPvt	 *precordPvt;

    /*run myCallback under general purpose callback task*/
    precord = (*pabDrv->getUserPvt)(drvPvt);
    precordPvt = precord->dpvt;
    callbackSetPriority(precord->prio,&precordPvt->callback);
    callbackRequest(&precordPvt->callback);
}
示例#11
0
void postEvent(event_list *pel)
{
    int prio;

    if (scanCtl != ctlRun) return;
    if (!pel) return;
    for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
        if (ellCount(&pel->scan_list[prio].list) >0)
            callbackRequest(&pel->callback[prio]);
    }
}
示例#12
0
static void asInitTask(ASDBCALLBACK *pcallback)
{
    long status;

    taskwdInsert(epicsThreadGetIdSelf(), wdCallback, (void *)pcallback);
    status = asInitCommon();
    taskwdRemove(epicsThreadGetIdSelf());
    asInitTheadId = 0;
    if(pcallback) {
	pcallback->status = status;
	callbackRequest(&pcallback->callback);
    }
}
示例#13
0
/**************************************************
* scalerISR()
***************************************************/
STATIC void scalerISR()
{
	Debug(5, "%s", "scalerISR: entry\n");
	int card = 0;
	
	/* tell record support the hardware is done counting */
	scaler_state[card]->done = 1;

	/* get the record processed */
	callbackRequest(scaler_state[card]->pcallback);

	return;
}
示例#14
0
/* Callback routine gets called when acquisition completes */
static void interruptCallback(void *drvPvt,  asynUser *pasynUser, epicsInt32 value)
{
    scalerAsynPvt *pPvt = (scalerAsynPvt *)drvPvt;
    scalerRecord *psr = pPvt->psr;

    /* Ignore callbacks when done value is 0 */
    if (value == 0) return;
    pPvt->done = 1;
    asynPrint(pPvt->pasynUser[0], ASYN_TRACEIO_DEVICE,
        "%s devScalerAsyn::interruptCallback new value=%d\n",
        psr->name, value);
    callbackRequest(pPvt->pcallback);
}
示例#15
0
static long processAo(aoRecord *pr)
{
    devPvt *pPvt = (devPvt *)pr->dpvt;
    asynStatus status;

    epicsMutexLock(pPvt->devPvtLock);
    if (pPvt->newOutputCallbackValue && getCallbackValue(pPvt)) {
        if (pPvt->result.status == asynSuccess) {
            epicsFloat64 val64 = pPvt->result.value;
            /* ASLO/AOFF conversion */
            if (pr->aslo != 0.0) val64 *= pr->aslo;
            val64 += pr->aoff;
            pr->val = val64;
            pr->udf = 0;
        }
    } else if(pr->pact == 0) {
        /* ASLO/AOFF conversion */
        epicsFloat64 val64 = pr->oval - pr->aoff;
        if (pr->aslo != 0.0) val64 /= pr->aslo;
        pPvt->result.value = val64;
        if(pPvt->canBlock) {
            pr->pact = 1;
            pPvt->asyncProcessingActive = 1;
        }
        epicsMutexUnlock(pPvt->devPvtLock);
        status = pasynManager->queueRequest(pPvt->pasynUser, 0, 0);
        if((status==asynSuccess) && pPvt->canBlock) return 0;
        if(pPvt->canBlock) pr->pact = 0;
        epicsMutexLock(pPvt->devPvtLock);
        reportQueueRequestStatus(pPvt, status);
    }
    pasynEpicsUtils->asynStatusToEpicsAlarm(pPvt->result.status,
                                            WRITE_ALARM, &pPvt->result.alarmStatus, 
                                            INVALID_ALARM, &pPvt->result.alarmSeverity);
    recGblSetSevr(pr, pPvt->result.alarmStatus, pPvt->result.alarmSeverity);
    if (pPvt->numDeferredOutputCallbacks > 0) {
        callbackRequest(&pPvt->outputCallback);
        pPvt->numDeferredOutputCallbacks--;
    }
    pPvt->newOutputCallbackValue = 0;
    pPvt->asyncProcessingActive = 0;
    epicsMutexUnlock(pPvt->devPvtLock);
    if(pPvt->result.status == asynSuccess) {
        return 0;
    }
    else {
        pPvt->result.status = asynSuccess;
        return -1;
    }
}
示例#16
0
static void ntpshmhooks(initHookState state)
{
    if(state!=initHookAfterIocRunning)
        return;

    epicsThreadOnce(&ntponce, &ntpshminit, 0);

    epicsMutexMustLock(ntpShm.ntplock);
    if(ntpShm.evr) {
        callbackRequest(&ntpShm.ntpcb);
        fprintf(stderr, "Starting NTP SHM writer for segment %d\n", ntpShm.segid);
    }
    epicsMutexUnlock(ntpShm.ntplock);
}
示例#17
0
/**************************************************
* scalerEndOfGateISR()
***************************************************/
STATIC void scalerEndOfGateISR(int card)
{
#ifdef vxWorks
	Debug(5, "%s", "scalerEndOfGateISR: entry\n");
#endif
	if (card >= scalerVS_total_cards) {
		return;
	} else {
		/* tell record support the hardware is done counting */
		scalerVS_state[card]->done = 1;

		/* get the record processed */
		callbackRequest(scalerVS_state[card]->pcallback);
	}
}
示例#18
0
/* Return a bit mask indicating each priority level
 * in which a callback request was successfully queued.
 */
unsigned int scanIoRequest(IOSCANPVT piosh)
{
    int prio;
    unsigned int queued = 0;

    if (scanCtl != ctlRun)
        return 0;

    for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) {
        io_scan_list *piosl = &piosh->iosl[prio];

        if (ellCount(&piosl->scan_list.list) > 0)
            if (!callbackRequest(&piosl->callback))
                queued |= 1 << prio;
    }

    return queued;
}
示例#19
0
static void restartCheck(processNotifyRecord *ppnr)
{
    dbCommon *precord = ppnr->precord;
    processNotify *pfirst;
    notifyPvt *pnotifyPvt;
    
    assert(precord->ppn);
    pfirst = (processNotify *) ellFirst(&ppnr->restartList);
    if (!pfirst) {
        precord->ppn = 0;
        return;
    }
    pnotifyPvt = (notifyPvt *) pfirst->pnotifyPvt;
    assert(pnotifyPvt->state == notifyWaitForRestart);
    /* remove pfirst from restartList */
    ellSafeDelete(&ppnr->restartList, &pfirst->restartNode);
    /*make pfirst owner of the record*/
    precord->ppn = pfirst;
    /* request callback for pfirst */
    pnotifyPvt->state = notifyRestartCallbackRequested;
    callbackRequest(&pnotifyPvt->callback);
}
示例#20
0
文件: callback.c 项目: ukaea/epics
static void notify(void *pPrivate)
{
    CALLBACK *pcallback = (CALLBACK *)pPrivate;
    callbackRequest(pcallback);
}
示例#21
0
文件: callback.c 项目: ukaea/epics
int  callbackRequestProcessCallback(CALLBACK *pcallback,
    int Priority, void *pRec)
{
    callbackSetProcess(pcallback, Priority, pRec);
    return callbackRequest(pcallback);
}
示例#22
0
static void wdCallback(void *arg)
{
    ASDBCALLBACK *pcallback = (ASDBCALLBACK *)arg;
    pcallback->status = S_asLib_InitFailed;
    callbackRequest(&pcallback->callback);
}
示例#23
0
void ni1014(void *pvt)
{
    niport          *pniport = (niport *)pvt;
    transferState_t state = pniport->transferState;
    epicsUInt8      isr1,isr2,octet;
    char            message[80];

    pniport->isr2 = isr2 = readRegister(pniport,ISR2);
    pniport->isr1 = isr1 = readRegister(pniport,ISR1);
    writeRegister(pniport,CSR1,2); /*acknowledge interrupt*/
    if(isr2&SRQI) callbackRequest(&pniport->callback);
    if(isr1&ERR) {
        if(state!=transferStateIdle) {
            sprintf(pniport->errorMessage,"\n%s interruptHandler ERR state %d\n",
                pniport->portName,state);
            pniport->status = asynError;
            epicsEventSignal(pniport->waitForInterrupt);
        }
        goto exit;
    }
    switch(state) {
    case transferStateCmd:
        if(!isr2&CO)
	    goto exit;
        if(pniport->bytesRemainingCmd == 0) {
            pniport->transferState = pniport->nextTransferState;
            if(pniport->transferState==transferStateIdle) {
                epicsEventSignal(pniport->waitForInterrupt);
            } else {
                writeRegister(pniport,AUXMR,AUXGTS);
            }
            break ;
        }
        octet = *pniport->nextByteCmd;
        writeRegister(pniport,CDOR,(epicsUInt8)octet);
        --(pniport->bytesRemainingCmd); ++(pniport->nextByteCmd);
        break;
    case transferStateWrite:
        if(!isr1&DO)
	    goto exit;
        if(pniport->bytesRemainingWrite == 0) {
            pniport->transferState = transferStateIdle;
            writeRegister(pniport,AUXMR,AUXTCA);
            epicsEventSignal(pniport->waitForInterrupt);
            break ;
        }
        if(pniport->bytesRemainingWrite==1) writeRegister(pniport,AUXMR,AUXEOI);
        octet = *pniport->nextByteWrite;
        writeRegister(pniport,CDOR,(epicsUInt8)octet);
        --(pniport->bytesRemainingWrite); ++(pniport->nextByteWrite);
        break;
    case transferStateRead:
        if(!isr1&DI) break;
        octet = readRegister(pniport,DIR);
        *pniport->nextByteRead = octet;
        --(pniport->bytesRemainingRead); ++(pniport->nextByteRead);
        if((pniport->eos != -1 ) && (octet == pniport->eos))
            pniport->eomReason |= ASYN_EOM_EOS;
        if(ENDRX&isr1) pniport->eomReason |= ASYN_EOM_END;
        if(pniport->bytesRemainingRead == 0) pniport->eomReason |= ASYN_EOM_CNT;
        if(pniport->eomReason) {
            pniport->transferState = transferStateIdle;
            writeRegister(pniport,AUXMR,AUXTCS);
            epicsEventSignal(pniport->waitForInterrupt);
            break;
        }
        writeRegister(pniport,AUXMR,AUXFH);
        break;
    case transferStateIdle:
        if(!isr1&DI)
	    goto exit;
        octet = readRegister(pniport,DIR);
        sprintf(message,"%s ni1014IH transferStateIdle received %2.2x\n",
             pniport->portName,octet);
        epicsInterruptContextMessage(message);
    }

exit:
    /* Force synchronization of VMEbus writes on PPC CPU boards. */
    readRegister(pniport,ADSR);
}