예제 #1
0
void scanShutdown(void)
{
    int i;

    if (scanCtl == ctlExit) return;
    scanCtl = ctlExit;

    interruptAccept = FALSE;

    for (i = 0; i < nPeriodic; i++) {
        papPeriodic[i]->scanCtl = ctlExit;
        epicsEventSignal(papPeriodic[i]->loopEvent);
        epicsEventWait(startStopEvent);
    }

    scanOnce((dbCommon *)&exitOnce);
    epicsEventWait(startStopEvent);

    deletePeriodic();
    ioscanDestroy();

    epicsRingPointerDelete(onceQ);

    epicsEventDestroy(startStopEvent);
    epicsEventDestroy(onceSem);
    onceSem = startStopEvent = NULL;

    free(periodicTaskId);
    papPeriodic = NULL;
    periodicTaskId = NULL;
}
예제 #2
0
void dbProcessNotify(processNotify *ppn)
{
    struct dbChannel *chan = ppn->chan;
    dbCommon *precord = dbChannelRecord(chan);
    short dbfType = dbChannelFieldType(chan);
    notifyPvt *pnotifyPvt;

    /* Must handle DBF_XXXLINKs as special case.
     * Only dbPutField will change link fields.
     * Also the record is not processed as a result
    */
    ppn->status = notifyOK;
    ppn->wasProcessed = 0;
    if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) {
        if (ppn->requestType == putProcessRequest ||
            ppn->requestType == putProcessGetRequest) {
            /* Check if puts disabled */
            if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) {
                ppn->putCallback(ppn, putDisabledType);
            } else {
                ppn->putCallback(ppn, putFieldType);
            }
        }
        if (ppn->requestType == processGetRequest ||
            ppn->requestType == putProcessGetRequest) {
                ppn->getCallback(ppn, getFieldType);
            
        }
        ppn->doneCallback(ppn);
        return;
    }
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (pnotifyPvt && (pnotifyPvt->magic != MAGIC)) {
        printf("dbPutNotify:pnotifyPvt was not initialized\n");
        pnotifyPvt = 0;
    }
    if (pnotifyPvt) {
        assert(pnotifyPvt->state == notifyUserCallbackActive);
        pnotifyPvt->userCallbackWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pnotifyPvt->userCallbackEvent);
        dbScanLock(precord);
        epicsMutexMustLock(pnotifyGlobal->lock);
        notifyCleanup(ppn);
    }
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    assert(!pnotifyPvt);
    notifyInit(ppn);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (!precord->ppnr) {
        /* make sure record has a processNotifyRecord*/
        precord->ppnr = dbCalloc(1, sizeof(processNotifyRecord));
        precord->ppnr->precord = precord;
        ellInit(&precord->ppnr->restartList);
    }
    processNotifyCommon(ppn, precord);
}
예제 #3
0
static asynStatus
asynSetEos(const char *portName, int addr, enum eosType type, const char *eos)
{
    asynUser *pasynUser;
    asynInterface *pasynInterface;
    eosArgs eosargs;

    if (eos == NULL) {
        printf("Missing EOS argument\n");
        return asynError;
    }
    eosargs.eosLen = epicsStrnRawFromEscaped(eosargs.eos, sizeof eosargs.eos, eos, strlen(eos));
    if (eosargs.eosLen >= sizeof eosargs.eos) {
        printf("End of string argument \"%s\" too long.\n", eos);
        return asynError;
    }
    if (findInterface(portName, addr, asynOctetType, setEos,
                                        &pasynUser, &pasynInterface) != asynSuccess)
        return asynError;
    pasynUser->timeout = 2;
    pasynUser->userPvt = &eosargs;
    pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED;
    eosargs.pasynOctet = (asynOctet *)pasynInterface->pinterface;
    eosargs. drvPvt = pasynInterface->drvPvt;
    eosargs.type = type;
    eosargs.done = epicsEventMustCreate(epicsEventEmpty);
    eosargs.status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, 0.0);
    if (eosargs.status == asynSuccess)
        epicsEventWait(eosargs.done);
    epicsEventDestroy(eosargs.done);
    if (eosargs.status != asynSuccess)
        printf("Set EOS failed: %s\n", pasynUser->errorMessage);
    pasynManager->freeAsynUser(pasynUser);
    return eosargs.status;
}
예제 #4
0
epicsShareFunc int
asynShowEos(const char *portName, int addr, enum eosType type)
{
    asynInterface *pasynInterface;
    eosArgs eosargs;
    asynUser *pasynUser;

    if (findInterface(portName, addr, asynOctetType, getEos,
                                        &pasynUser, &pasynInterface) != asynSuccess)
        return asynError;
    pasynUser->timeout = 2;
    pasynUser->userPvt = &eosargs;
    pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED;
    eosargs.pasynOctet = (asynOctet *)pasynInterface->pinterface;
    eosargs. drvPvt = pasynInterface->drvPvt;
    eosargs.type = type;
    eosargs.done = epicsEventMustCreate(epicsEventEmpty);
    eosargs.status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, 0.0);
    if (eosargs.status == asynSuccess)
        epicsEventWait(eosargs.done);
    epicsEventDestroy(eosargs.done);
    if (eosargs.status != asynSuccess)
        printf("Set EOS failed: %s\n", pasynUser->errorMessage);
    pasynManager->freeAsynUser(pasynUser);
    if (eosargs.status == asynSuccess) {
        char cbuf[4*sizeof eosargs.eos + 2];
        epicsStrnEscapedFromRaw(cbuf, sizeof cbuf, eosargs.eos, eosargs.eosLen);
        printf("\"%s\"\n", cbuf);
    }
    return eosargs.status;
}
예제 #5
0
epicsShareFunc int
 asynSetOption(const char *portName, int addr, const char *key, const char *val)
{
    asynUser *pasynUser;
    asynInterface *pasynInterface;
    setOptionArgs optionargs;

    if ((key == NULL) || (val == NULL)) {
        printf("Missing key/value argument\n");
        return asynError;
    }
    if (findInterface(portName, addr, asynOptionType, setOption,
                                    &pasynUser, &pasynInterface) != asynSuccess)
        return asynError;
    pasynUser->timeout = 2;
    pasynUser->userPvt = &optionargs;
    pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED;
    optionargs.pasynOption = (asynOption *)pasynInterface->pinterface;
    optionargs. drvPvt = pasynInterface->drvPvt;
    optionargs.key = key;
    optionargs.val = val;
    optionargs.done = epicsEventMustCreate(epicsEventEmpty);
    if (pasynManager->queueRequest(pasynUser,asynQueuePriorityConnect,0.0) != asynSuccess) {
        printf("queueRequest failed: %s\n", pasynUser->errorMessage);
        epicsEventDestroy(optionargs.done);
        pasynManager->freeAsynUser(pasynUser);
        return asynError;
    }
    epicsEventWait(optionargs.done);
    epicsEventDestroy(optionargs.done);
    pasynManager->freeAsynUser(pasynUser);
    return asynSuccess;
}
예제 #6
0
void threadFunc_RTcore_DivideB(void *param)
{
	ST_RTcore *pRTcore = (ST_RTcore*) param;;
	epicsThreadId pthreadInfo;

#if USE_CPU_AFFINITY_RT	
	pthreadInfo = epicsThreadGetIdSelf();
/*	printf("%s: EPICS ID %p, pthreadID %lu\n", pthreadInfo->name, (void *)pthreadInfo, (unsigned long)pthreadInfo->tid); */
	epicsThreadSetCPUAffinity( pthreadInfo, AFFINITY_RTCORE_DivB);
	epicsThreadSetPosixPriority(pthreadInfo, PRIOTY_RTCORE_DivB, "SCHED_FIFO");
#endif

	epicsThreadSleep(1.0);


	while(TRUE) {
		epicsEventWait( pRTcore->ST_DivThreadB.threadEventId);

#if USE_RTCORE_DivB_HIGH
		WRITE32(pRTcore->base0 + 0x4, 0x1);
#endif
#if USE_RTCORE_DivB_LOW
		WRITE32(pRTcore->base0 + 0x4, 0x0);
#endif

	}
}
예제 #7
0
static void waitTimeout(niport *pniport,double seconds)
{
    epicsEventWaitStatus status;
    transferState_t saveState;

    if(seconds<0.0) {
        status = epicsEventWait(pniport->waitForInterrupt);
    } else {
        status = epicsEventWaitWithTimeout(pniport->waitForInterrupt,seconds);
    }
    if(status==epicsEventWaitOK) return;
    saveState = pniport->transferState;
    pniport->transferState = transferStateIdle;
    switch(saveState) {
    case transferStateRead:
        pniport->status=asynTimeout;
        printStatus(pniport,"waitTimeout transferStateRead\n");
        break;
    case transferStateWrite:
        pniport->status=asynTimeout;
        printStatus(pniport,"waitTimeout transferStateWrite\n");
        break;
    case transferStateCmd:
        pniport->status=asynTimeout;
        printStatus(pniport,"waitTimeout transferStateCmd\n");
        break;
    default:
        pniport->status=asynTimeout;
        printStatus(pniport,"waitTimeout transferState ?\n");
    }
}
예제 #8
0
void dbNotifyCancel(processNotify *ppn)
{
    dbCommon *precord = dbChannelRecord(ppn->chan);
    notifyState state;
    notifyPvt *pnotifyPvt;

    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    ppn->status = notifyCanceled;
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) {
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        return;
    }

    state = pnotifyPvt->state;
    switch (state) {
    case notifyUserCallbackRequested:
    case notifyRestartCallbackRequested:
    case notifyUserCallbackActive:
        /* Callback is scheduled or active, wait for it to complete */
        pnotifyPvt->cancelWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pnotifyPvt->cancelEvent);
        epicsMutexMustLock(pnotifyGlobal->lock);
        notifyCleanup(ppn);
        epicsMutexUnlock(pnotifyGlobal->lock);
        return;
    case notifyNotActive:
    	break;
    case notifyWaitForRestart:
        assert(precord->ppn);
        assert(precord->ppn!=ppn);
        ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode);
        break;
    case notifyRestartInProgress:
    case notifyProcessInProgress:
        { /*Take all records out of wait list */
            processNotifyRecord *ppnrWait;

            while ((ppnrWait = (processNotifyRecord *)
	                       ellFirst(&pnotifyPvt->waitList))) {
                ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode);
                restartCheck(ppnrWait);
            }
        }
        if (precord->ppn == ppn)
            restartCheck(precord->ppnr);
        break;
    default:
        printf("dbNotify: illegal state for notifyCallback\n");
    }
    pnotifyPvt->state = notifyNotActive;
    notifyCleanup(ppn);
    epicsMutexUnlock(pnotifyGlobal->lock);
    dbScanUnlock(precord);
}
예제 #9
0
/** Simulation task that runs as a separate thread.  When the P_Run parameter is set to 1
  * to rub the simulation it computes a 1 kHz sine wave with 1V amplitude and user-controllable
  * noise, and displays it on
  * a simulated scope.  It computes waveforms for the X (time) and Y (volt) axes, and computes
  * statistics about the waveform. */
void testAsynPortDriver::simTask(void)
{
    /* This thread computes the waveform and does callbacks with it */

    double timePerDiv, voltsPerDiv, voltOffset, triggerDelay, noiseAmplitude;
    double updateTime, minValue, maxValue, meanValue;
    double time, timeStep;
    double noise, yScale;
    int run, i, maxPoints;
    double pi=4.0*atan(1.0);
    
    lock();
    /* Loop forever */    
    while (1) {
        getDoubleParam(P_UpdateTime, &updateTime);
        getIntegerParam(P_Run, &run);
        // Release the lock while we wait for a command to start or wait for updateTime
        unlock();
        if (run) epicsEventWaitWithTimeout(eventId_, updateTime);
        else     (void) epicsEventWait(eventId_);
        // Take the lock again
        lock(); 
        /* run could have changed while we were waiting */
        getIntegerParam(P_Run, &run);
        if (!run) continue;
        getIntegerParam(P_MaxPoints,        &maxPoints);
        getDoubleParam (P_TimePerDiv,       &timePerDiv);
        getDoubleParam (P_VoltsPerDiv,      &voltsPerDiv);
        getDoubleParam (P_VoltOffset,       &voltOffset);
        getDoubleParam (P_TriggerDelay,     &triggerDelay);
        getDoubleParam (P_NoiseAmplitude,   &noiseAmplitude);
        time = triggerDelay;
        timeStep = timePerDiv * NUM_DIVISIONS / maxPoints;
        minValue = 1e6;
        maxValue = -1e6;
        meanValue = 0.;
    
        yScale = 1.0 / voltsPerDiv;
        for (i=0; i<maxPoints; i++) {
            noise = noiseAmplitude * (rand()/(double)RAND_MAX - 0.5);
            pData_[i] = AMPLITUDE * (sin(time*FREQUENCY*2*pi)) + noise;
            /* Compute statistics before doing the yOffset and yScale */
            if (pData_[i] < minValue) minValue = pData_[i];
            if (pData_[i] > maxValue) maxValue = pData_[i];
            meanValue += pData_[i];
            pData_[i] = NUM_DIVISIONS/2 + yScale * (voltOffset + pData_[i]);
            time += timeStep;
        }
        updateTimeStamp();
        meanValue = meanValue/maxPoints;
        setDoubleParam(P_MinValue, minValue);
        setDoubleParam(P_MaxValue, maxValue);
        setDoubleParam(P_MeanValue, meanValue);
        callParamCallbacks();
        doCallbacksFloat64Array(pData_, maxPoints, P_Waveform, 0);
    }
}
예제 #10
0
파일: dbNotify.c 프로젝트: ukaea/epics
void epicsShareAPI dbNotifyCancel(putNotify *ppn)
{
    dbCommon	*precord = ppn->paddr->precord;
    putNotifyState state;
    putNotifyPvt *pputNotifyPvt;

    assert(precord);
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt;
    if(!pputNotifyPvt || pputNotifyPvt->state==putNotifyNotActive) {
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        return;
    }
    state = pputNotifyPvt->state;
    /*If callback is scheduled or active wait for it to complete*/
    if(state==putNotifyUserCallbackRequested
    || state==putNotifyRestartCallbackRequested
    || state==putNotifyUserCallbackActive) {
        pputNotifyPvt->cancelWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pputNotifyPvt->cancelEvent);
        epicsMutexMustLock(pnotifyGlobal->lock);
        putNotifyCleanup(ppn);
        epicsMutexUnlock(pnotifyGlobal->lock);
        return;
    }
    switch(state) {
    case putNotifyNotActive: break;
    case putNotifyWaitForRestart:
        assert(precord->ppn);
        assert(precord->ppn!=ppn);
        ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode);
        break;
    case putNotifyRestartInProgress:
    case putNotifyPutInProgress:
        { /*Take all records out of wait list */
            putNotifyRecord *ppnrWait;

            while((ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList))){
                ellSafeDelete(&pputNotifyPvt->waitList,&ppnrWait->waitNode);
                restartCheck(ppnrWait);
            }
        }
        if(precord->ppn==ppn) restartCheck(precord->ppnr);
        break;
    default:
        printf("dbNotify: illegal state for notifyCallback\n");
    }
    pputNotifyPvt->state = putNotifyNotActive;
    putNotifyCleanup(ppn);
    epicsMutexUnlock(pnotifyGlobal->lock);
    dbScanUnlock(precord);
}
예제 #11
0
asynNDArrayDriver::~asynNDArrayDriver()
{ 
    queuedArrayUpdateRun_ = false;
    epicsEventSignal(queuedArrayEvent_);
    epicsEventWait(queuedArrayUpdateDone_);

    delete this->pNDArrayPoolPvt_;
    free(this->pArrays);
    delete this->pAttributeList;
    delete this->queuedArrayCountMutex_;
}    
예제 #12
0
파일: dbNotify.c 프로젝트: ukaea/epics
void epicsShareAPI dbPutNotify(putNotify *ppn)
{
    dbCommon	*precord = ppn->paddr->precord;
    short	dbfType = ppn->paddr->field_type;
    long	status=0;
    putNotifyPvt *pputNotifyPvt;

    assert(precord);
    /*check for putField disabled*/
    if(precord->disp) {
        if((void *)(&precord->disp) != ppn->paddr->pfield) {
           ppn->status = putNotifyPutDisabled;
           (*ppn->userCallback)(ppn);
           return;
        }
    }
    /* Must handle DBF_XXXLINKs as special case.
     * Only dbPutField will change link fields. 
     * Also the record is not processed as a result
    */
    if(dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) {
	status=dbPutField(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest);
        ppn->status = (status==0) ? putNotifyOK : putNotifyError;
        (*ppn->userCallback)(ppn);
        return;
    }
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt;
    if(pputNotifyPvt && (pputNotifyPvt->magic!=MAGIC)) {
        printf("dbPutNotify:pputNotifyPvt was not initialized\n");
        pputNotifyPvt = 0;
    }
    if(pputNotifyPvt) {
        assert(pputNotifyPvt->state==putNotifyUserCallbackActive);
        pputNotifyPvt->userCallbackWait = 1;
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        epicsEventWait(pputNotifyPvt->userCallbackEvent);
        dbScanLock(precord);
        epicsMutexMustLock(pnotifyGlobal->lock);
        putNotifyCleanup(ppn);
    }
    pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt;
    assert(!pputNotifyPvt);
    putNotifyInit(ppn);
    pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt;
    if(!precord->ppnr) {/* make sure record has a putNotifyRecord*/
        precord->ppnr = dbCalloc(1,sizeof(putNotifyRecord));
        precord->ppnr->precord = precord;
        ellInit(&precord->ppnr->restartList);
    }
    putNotifyCommon(ppn,precord);
}
예제 #13
0
static void initOnce(void)
{
    if ((onceQ = epicsRingPointerCreate(onceQueueSize)) == NULL) {
        cantProceed("initOnce: Ring buffer create failed\n");
    }
    onceSem = epicsEventMustCreate(epicsEventEmpty);
    onceTaskId = epicsThreadCreate("scanOnce",
        epicsThreadPriorityScanLow + nPeriodic,
        epicsThreadGetStackSize(epicsThreadStackBig), onceTask, 0);

    epicsEventWait(startStopEvent);
}
예제 #14
0
파일: taskwd.c 프로젝트: ukaea/epics
static void twdShutdown(void *arg)
{
    ELLNODE *cur;
    twdCtl = twdctlExit;
    epicsEventSignal(loopEvent);
    epicsEventWait(exitEvent);
    while ((cur = ellGet(&fList)) != NULL) {
        VALGRIND_MEMPOOL_FREE(&fList, cur);
        free(cur);
    }
    VALGRIND_DESTROY_MEMPOOL(&fList);
}
예제 #15
0
파일: dbNotify.c 프로젝트: ukaea/epics
static void tpnThread(void *pvt)
{
    tpnInfo   *ptpnInfo = (tpnInfo *)pvt;
    putNotify *ppn = (putNotify *)ptpnInfo->ppn;

    dbPutNotify(ppn);
    epicsEventWait(ptpnInfo->callbackDone);
    dbNotifyCancel(ppn);
    epicsEventDestroy(ptpnInfo->callbackDone);
    free((void *)ppn->paddr);
    free(ppn);
    free(ptpnInfo);
}
예제 #16
0
static void tpnThread(void *pvt)
{
    tpnInfo *ptpnInfo = (tpnInfo *) pvt;
    processNotify *ppn = (processNotify *) ptpnInfo->ppn;

    dbProcessNotify(ppn);
    epicsEventWait(ptpnInfo->callbackDone);
    dbNotifyCancel(ppn);
    epicsEventDestroy(ptpnInfo->callbackDone);
    dbChannelDelete(ppn->chan);
    free(ppn);
    free(ptpnInfo);
}
예제 #17
0
static void spawnPeriodic(int ind)
{
    periodic_scan_list *ppsl;
    char taskName[20];

    ppsl = papPeriodic[ind];
    sprintf(taskName, "scan-%g", ppsl->period);
    periodicTaskId[ind] = epicsThreadCreate(
        taskName, epicsThreadPriorityScanLow + ind,
        epicsThreadGetStackSize(epicsThreadStackBig),
        periodicTask, (void *)ppsl);

    epicsEventWait(startStopEvent);
}
예제 #18
0
void asynNDArrayDriver::updateQueuedArrayCount()
{
    while (queuedArrayUpdateRun_) {
        epicsEventWait(queuedArrayEvent_);
        // Exit early
        if (!queuedArrayUpdateRun_)
            break;

        lock();
        setIntegerParam(NDNumQueuedArrays, getQueuedArrayCount());
        callParamCallbacks();
        unlock();
    }
    epicsEventSignal(queuedArrayUpdateDone_);
}
예제 #19
0
파일: callback.c 프로젝트: ukaea/epics
void callbackInit(void)
{
    int i;
    int j;
    char threadName[32];

    if (callbackIsInit) {
        errlogMessage("Warning: callbackInit called again before callbackCleanup\n");
        return;
    }
    callbackIsInit = 1;

    if(!startStopEvent)
        startStopEvent = epicsEventMustCreate(epicsEventEmpty);
    cbCtl = ctlRun;
    timerQueue = epicsTimerQueueAllocate(0, epicsThreadPriorityScanHigh);

    for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) {
        epicsThreadId tid;

        callbackQueue[i].semWakeUp = epicsEventMustCreate(epicsEventEmpty);
        callbackQueue[i].queue = epicsRingPointerLockedCreate(callbackQueueSize);
        if (callbackQueue[i].queue == 0)
            cantProceed("epicsRingPointerLockedCreate failed for %s\n",
                threadNamePrefix[i]);
        callbackQueue[i].queueOverflow = FALSE;
        if (callbackQueue[i].threadsConfigured == 0)
            callbackQueue[i].threadsConfigured = callbackThreadsDefault;

        for (j = 0; j < callbackQueue[i].threadsConfigured; j++) {
            if (callbackQueue[i].threadsConfigured > 1 )
                sprintf(threadName, "%s-%d", threadNamePrefix[i], j);
            else
                strcpy(threadName, threadNamePrefix[i]);
            tid = epicsThreadCreate(threadName, threadPriority[i],
                epicsThreadGetStackSize(epicsThreadStackBig),
                (EPICSTHREADFUNC)callbackTask, &priorityValue[i]);
            if (tid == 0) {
                cantProceed("Failed to spawn callback thread %s\n", threadName);
            } else {
                epicsEventWait(startStopEvent);
                epicsAtomicIncrIntT(&callbackQueue[i].threadsRunning);
            }
        }
    }
}
예제 #20
0
/* Caller must take devLock */
static
void
stopIsrThread(osdISR *isr)
{
    if (isr->waiter_status==osdISRDone)
        return;

    isr->waiter_status = osdISRStopping;

    while (isr->waiter_status!=osdISRDone) {
        epicsMutexUnlock(isr->osd->devLock);

        epicsEventWait(isr->done);

        epicsMutexMustLock(isr->osd->devLock);
    }
}
예제 #21
0
/** Array generation ask that runs as a separate thread.  When the P_RunStop parameter is set to 1
  * it periodically generates a burst of arrays. */
void testArrayRingBuffer::arrayGenTask(void)
{
    double loopDelay;
    int runStop; 
    int i, j;
    int burstLength;
    double burstDelay;
    int maxArrayLength;
    int arrayLength;
    
    lock();
    /* Loop forever */ 
    getIntegerParam(P_MaxArrayLength, &maxArrayLength);   
    while (1) {
        getDoubleParam(P_LoopDelay, &loopDelay);
        getDoubleParam(P_BurstDelay, &burstDelay);
        getIntegerParam(P_RunStop, &runStop);
        // Release the lock while we wait for a command to start or wait for updateTime
        unlock();
        if (runStop) epicsEventWaitWithTimeout(eventId_, loopDelay);
        else         (void)epicsEventWait(eventId_);
        // Take the lock again
        lock(); 
        /* runStop could have changed while we were waiting */
        getIntegerParam(P_RunStop, &runStop);
        if (!runStop) continue;
        getIntegerParam(P_ArrayLength, &arrayLength);
        if (arrayLength > maxArrayLength) {
            arrayLength = maxArrayLength;
            setIntegerParam(P_ArrayLength, arrayLength);
        }
        getIntegerParam(P_BurstLength, &burstLength);
        for (i=0; i<burstLength; i++) {
            for (j=0; j<arrayLength; j++) {
                pData_[j] = i;
            }
            setIntegerParam(P_ScalarData, i);
            callParamCallbacks();
            doCallbacksInt32Array(pData_, arrayLength, P_ArrayData, 0);
            if (burstDelay > 0.0) 
                epicsThreadSleep(burstDelay);
        }
    }
}
예제 #22
0
void verifyTryLock ()
{
    struct verifyTryLock verify;

    verify.mutex = epicsMutexMustCreate ();
    verify.done = epicsEventMustCreate ( epicsEventEmpty );

    testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK);

    epicsThreadCreate ( "verifyTryLockThread", 40, 
        epicsThreadGetStackSize(epicsThreadStackSmall),
        verifyTryLockThread, &verify );

    testOk1(epicsEventWait ( verify.done ) == epicsEventWaitOK);

    epicsMutexUnlock ( verify.mutex );
    epicsMutexDestroy ( verify.mutex );
    epicsEventDestroy ( verify.done );
}
예제 #23
0
static void cpuUsageTask(void *parm)
{
    while(TRUE)
    {
        int	 i;
        epicsTimeStamp tStart, tEnd;

        epicsEventWait(cpuUsage.startSem);
        cpuUsage.nBurnNow=0;
        epicsTimeGetCurrent(&tStart);
        for(i=0; i< cpuUsage.nBurnNoContention; i++)
        {
            cpuBurn();
            epicsTimeGetCurrent(&tEnd);
            cpuUsage.tNow = epicsTimeDiffInSeconds(&tEnd, &tStart);
            ++cpuUsage.nBurnNow;
        }
        cpuUsage.didNotComplete = FALSE;
    }
}
예제 #24
0
void FastCCD::dataStatsTask(void)
{
  unsigned int status = 0;
  double timeout = 0.0;
  static const char *functionName = "dataStatsTask";

  while(1) {

    //Read timeout for polling freq.
    this->lock();
    timeout = dataStatsPollingPeriod;
    this->unlock();

    if (timeout != 0.0) {
      status = epicsEventWaitWithTimeout(dataStatsEvent, timeout);
    } else {
      status = epicsEventWait(dataStatsEvent);
    }              
  
    if (status == epicsEventWaitOK) {
      asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
        "%s:%s: Got status event\n",
        driverName, functionName);
    }

    cin_data_stats_t stats;
    cin_data_compute_stats(&stats);
    setIntegerParam(FastCCDDroppedPck, (int)stats.dropped_packets);
    setIntegerParam(FastCCDBadPck, (int)stats.mallformed_packets);
    setIntegerParam(FastCCDLastFrame, stats.last_frame);
    setIntegerParam(FastCCDPacketBuffer, stats.packet_used);
    setIntegerParam(FastCCDFrameBuffer, stats.frame_used);
    setIntegerParam(FastCCDImageBuffer, stats.image_used);

    //setDoubleParam(FastCCDDataRate, stats.datarate);
    
    this->lock();
    callParamCallbacks();
    this->unlock();
  }
}
예제 #25
0
void Scaler974::eventThread()
{
    int done, presetCount;
    char response[100], statusString[20];
    size_t responseLen, statusLen;
    int counts[MAX_CHANNELS];
    int i;
    asynStatus status;
    static const char *functionName="eventThread";
    
    while(1)
    {
        epicsEventWait(this->eventId);
        while(1)
        {
            status = this->sendCommand("SHOW_COUNTS", statusString, sizeof(statusString), &statusLen,
                                       response, sizeof(response), &responseLen);
            sscanf(response, "%d;%d;%d;%d;", 
                   &counts[0], &counts[1], &counts[2], &counts[3]);
            asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
                "%s:%s status=%d, counts=%d %d %d %d\n",
                driverName, functionName, status, counts[0], counts[1], counts[2], counts[3]);
            this->lock();
            /* Get value of done in case scaler was stopped by scalerArm(0) */
            getIntegerParam(scalerDone, &done);
            getIntegerParam(scalerPreset, &presetCount);
            if (!done && (counts[0] >= presetCount)) done = 1;
            setIntegerParam(scalerDone, done);
            for (i=0; i<MAX_CHANNELS; i++) {
                setIntegerParam(i, scalerReadSingle, counts[i]);
                callParamCallbacks(i, i);
            }
            this->unlock();
            if (done) break; 
            epicsThreadSleep(this->polltime);
        }
    }
}
예제 #26
0
void drvQuadEM::callbackTask()
{
    lock();
    int numAcquire;
    int acquireMode;
    
    while (1) {
        unlock();
        (void)epicsEventWait(ringEvent_);
        lock();
        getIntegerParam(P_AcquireMode, &acquireMode);
        getIntegerParam(P_NumAcquire, &numAcquire);
        doDataCallbacks();
        numAcquired_++;
        setIntegerParam(P_NumAcquired, numAcquired_);
        if ( (acquireMode == QEAcquireModeSingle) ||
            ((acquireMode == QEAcquireModeMultiple) && (numAcquired_ >= numAcquire))) {
            setAcquire(0);
            setIntegerParam(P_Acquire, 0);
        }
        callParamCallbacks();
    }
}
예제 #27
0
void threadFunc_user_DAQ(void *param)
{
	ST_STD_device *pSTDdev = (ST_STD_device*) param;
/*	ST_threadCfg *pDAQST_threadConfig ; */

	if( !pSTDdev ) {
		printf("ERROR! threadFunc_user_DAQ() has null pointer of STD device.\n");
		return;
	}

	while(TRUE) {
/*		sem_wait( &DAQsemaphore ); */
		epicsEventWait( pSTDdev->ST_DAQThread.threadEventId);
#if PRINT_DAQ_DEBUG
		printf(">>> %s: DAQthreadFunc() : Got epics Event and DAQ start\n", pSTDdev->taskName);
#endif
/*		pSTDdev->StatusDev &= ~TASK_DAQ_STOPED; */
		pSTDdev->StatusDev |= TASK_WAIT_FOR_TRIGGER;
		pSTDdev->StatusDev |= DEV_IN_LOOP_HTSTREAM;

		scanIoRequest(pSTDdev->ioScanPvt_status);
// remove TG		acq196_htstream(pSTDdev);
	}
}
예제 #28
0
static void MM4000Poller(MM4000Controller *pController)
{
    /* This is the task that polls the MM4000 */
    double timeout;
    AXIS_HDL pAxis;
    int status;
    int itera, j;
    int axisDone;
    int offset;
    int anyMoving;
    int comStatus;
    int forcedFastPolls=0;
    char *p, *tokSave;
    char statusAllString[BUFFER_SIZE];
    char positionAllString[BUFFER_SIZE];
    char buff[BUFFER_SIZE];

    timeout = pController->idlePollPeriod;
    epicsEventSignal(pController->pollEventId);  /* Force on poll at startup */

    while (1)
    {
        if (timeout != 0.)
            status = epicsEventWaitWithTimeout(pController->pollEventId, timeout);
        else
            status = epicsEventWait(pController->pollEventId);

        if (status == epicsEventWaitOK)
        {
            /* We got an event, rather than a timeout.  This is because other software
             * knows that an axis should have changed state (started moving, etc.).
             * Force a minimum number of fast polls, because the controller status
             * might not have changed the first few polls
             */
            forcedFastPolls = 10;
        }

        anyMoving = 0;

        /* Lock all the controller's axis. */
        for (itera = 0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            epicsMutexLock(pAxis->mutexId);
        }

        comStatus = sendAndReceive(pController, "MS;", statusAllString, sizeof(statusAllString));
        if (comStatus == 0)
            comStatus = sendAndReceive(pController, "TP;", positionAllString, sizeof(positionAllString));

        for (itera=0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            if (comStatus != 0)
            {
                PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: error reading status=%d\n", comStatus);
                motorParam->setInteger(pAxis->params, motorAxisCommError, 1);
            }
            else
            {
                PARAMS params = pAxis->params;
                int intval, axisStatus;

                motorParam->setInteger(params, motorAxisCommError, 0);
                /*
                 * Parse the status string
                 * Status string format: 1MSx,2MSy,3MSz,... where x, y and z are the status
                 * bytes for the motors
                 */
                offset = pAxis->axis*5 + 3;  /* Offset in status string */
                axisStatus = pAxis->axisStatus = statusAllString[offset];
                if (axisStatus & MM4000_MOVING)
                {
                    axisDone = 0;
                    anyMoving = 1;
                }
                else
                    axisDone = 1;
                motorParam->setInteger(params, motorAxisDone, axisDone);

                motorParam->setInteger(params, motorAxisHomeSignal,    (axisStatus & MM4000_HOME));
                motorParam->setInteger(params, motorAxisHighHardLimit, (axisStatus & MM4000_HIGH_LIMIT));
                motorParam->setInteger(params, motorAxisLowHardLimit,  (axisStatus & MM4000_LOW_LIMIT));
                motorParam->setInteger(params, motorAxisDirection,     (axisStatus & MM4000_DIRECTION));
                motorParam->setInteger(params, motorAxisPowerOn,      !(axisStatus & MM4000_POWER_OFF));

                /*
                 * Parse motor position
                 * Position string format: 1TP5.012,2TP1.123,3TP-100.567,...
                 * Skip to substring for this motor, convert to double
                 */

                strcpy(buff, positionAllString);
                tokSave = NULL;
                p = epicsStrtok_r(buff, ",", &tokSave);
                for (j=0; j < pAxis->axis; j++)
                    p = epicsStrtok_r(NULL, ",", &tokSave);
                pAxis->currentPosition = atof(p+3);
                motorParam->setDouble(params, motorAxisPosition,    (pAxis->currentPosition/pAxis->stepSize));
                motorParam->setDouble(params, motorAxisEncoderPosn, (pAxis->currentPosition/pAxis->stepSize));
                PRINT(pAxis->logParam, IODRIVER, "MM4000Poller: axis %d axisStatus=%x, position=%f\n",
                      pAxis->axis, pAxis->axisStatus, pAxis->currentPosition);

                /* We would like a way to query the actual velocity, but this is not possible.  If we could we could
                 * set the direction, and Moving flags */

                /* Check for controller error. */
                comStatus = sendAndReceive(pController, "TE;", buff, sizeof(statusAllString));
                if (buff[2] == '@')
                    intval = 0;
                else
                {
                    intval = 1;
                    PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: controller error %s\n", buff);
                }
                motorParam->setInteger(params, motorAxisProblem, intval);
            }

            motorParam->callCallback(pAxis->params);
        } /* Next axis */

        /* UnLock all the controller's axis. */
        for (itera = 0; itera < pController->numAxes; itera++)
        {
            pAxis = &pController->pAxis[itera];
            if (!pAxis->mutexId)
                break;
            epicsMutexUnlock(pAxis->mutexId);
        }

        if (forcedFastPolls > 0)
        {
            timeout = pController->movingPollPeriod;
            forcedFastPolls--;
        }
        else if (anyMoving)
            timeout = pController->movingPollPeriod;
        else
            timeout = pController->idlePollPeriod;
    } /* End while */
}
예제 #29
0
/** This thread is woken up by an interrupt or a request to read status
  * It loops calling readFIFO until acquiring_ goes to false.
  * readFIFO only reads a limited amount of FIFO data at once in order
  * to avoid blocking the device support threads. */
void drvSIS3801::readFIFOThread()
{
  int count;
  int signal;
  int chan;
  int nChans;
  int status;
  int i;
  bool acquiring;  // We have a separate flag because we need to continue processing one last
                   // time even if acquiring_ goes to false because acquisition was manually stopped
  epicsUInt32 scalerPresets[SIS38XX_MAX_SIGNALS];
  epicsUInt32 *pOut=NULL;
  epicsTimeStamp t1, t2;
  static const char* functionName="readFIFOThread";

  while(true)
  {
    epicsEventWait(readFIFOEventId_);
    // We got an event, which can come from acquisition starting, or FIFO full interrupt
    asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
              "%s:%s: got readFIFOEvent, eventType=%d, interrupt status=0x%8.8x\n",
              driverName, functionName, eventType_, registers_->csr_reg & 0xFFF00000);
    lock();
    acquiring = acquiring_;
    unlock();
    while (acquiring) {
      lock();
      for (i=0; i<maxSignals_; i++) 
        getIntegerParam(i, scalerPresets_, (int *)&scalerPresets[i]);
      getIntegerParam(mcaNumChannels_, &nChans);
      asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                "%s:%s: scaler presets[0]=%d, scalerData[0]=%d\n",
                driverName, functionName, scalerPresets[0], scalerData_[0]);
      signal = nextSignal_;
      chan = nextChan_;
      count = 0;
      // This block of code can be slow and does not require the asynPortDriver lock because we are not
      // accessing object data that could change.  
      // It does require the FIFO lock so no one resets the FIFO while it executes
      epicsMutexLock(fifoLockId_);
      unlock();
      epicsTimeGetCurrent(&t1);

      /* Read out FIFO. It would be more efficient not to check the empty
       * flag on each transfer, using the almost empty flag.  But this has gotten
       * too complex, and is unlikely to save time on new boards with lots of
       * memory.
       */
      if (acquireMode_== ACQUIRE_MODE_MCS) {
        // Copy the data from the FIFO to the mcsBuffer
        pOut = mcsData_ + signal*maxChans_ + chan;
        asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                  "%s:%s: pOut=%p, signal=%d, chan=%d\n",
                  driverName, functionName, pOut, signal, chan);
        while (((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0) && (chan < nChans) && acquiring_) {
          *pOut = registers_->fifo_reg;
          signal++;
          count++;
          if (signal >= maxSignals_) {
            signal = 0;
            chan++;
            pOut = mcsData_ + chan;
          } else {
            pOut += maxChans_;
          }
        }
      } else if (acquireMode_ == ACQUIRE_MODE_SCALER) {
        while ((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0 && acquiring_) {
          scalerData_[signal] += registers_->fifo_reg;
          signal++;
          count++;
          if (signal >= maxSignals_) {
            for (i=0; i<maxSignals_; i++) {
              if ((scalerPresets[i] != 0) && 
                  (scalerData_[i] >= scalerPresets[i]))
                acquiring = false;
            }
            asynPrintIO(pasynUserSelf, ASYN_TRACEIO_DRIVER, 
                      (const char*)scalerData_, maxSignals_*sizeof(epicsUInt32), 
                      "%s:%s:\n",
                      driverName, functionName);
            if (!acquiring) break;
            signal = 0;
          }
        }
      }
      epicsTimeGetCurrent(&t2);

      asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
                "%s:%s: read FIFO (%d) in %fs, acquiring=%d\n",
                driverName, functionName, count, epicsTimeDiffInSeconds(&t2, &t1), acquiring_);
      // Release the FIFO lock, we are done accessing the FIFO
      epicsMutexUnlock(fifoLockId_);
      
      // Take the lock since we are now changing object data
      lock();
      nextChan_ = chan;
      nextSignal_ = signal;
      if (acquireMode_ == ACQUIRE_MODE_MCS) {
        asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                  "%s:%s: pOut=%p,signal=%d, chan=%d\n",
                  driverName, functionName, pOut, signal, chan);
        checkMCSDone();
      } else if (acquireMode_ == ACQUIRE_MODE_SCALER) {
        if (!acquiring) acquiring_ = false;
        if (!acquiring_) {
          asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: scaler done, doing callbacks\n",
                    driverName, functionName);
          stopScaler();
          setIntegerParam(scalerDone_, 1);
          callParamCallbacks();
        }
      }
      /* Reenable interrupts in case we were woken up by an interrupt for FIFO almost full */
      enableInterrupts();
      acquiring = acquiring_;
      // Release the lock
      unlock();
      // If we are still acquiring then sleep for a short time, but wake up if there is an interrupt
      if (acquiring) {
        status = epicsEventWaitWithTimeout(readFIFOEventId_, epicsThreadSleepQuantum());
        if (status == epicsEventWaitOK) 
          asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: got interrupt in epicsEventWaitWithTimeout, eventType=%d\n",
                    driverName, functionName, eventType_);
      }
    }  
  }
}
예제 #30
0
/** Callback task that runs as a separate thread. */
void testErrors::callbackTask(void)
{
    asynStatus currentStatus;
    int itemp;
    epicsInt32 iVal;
    epicsUInt32 uiVal;
    epicsFloat64 dVal;
    int i;
    char octetValue[20];
    
    /* Loop forever */    
    while (1) {
        lock();
        updateTimeStamp();
        getIntegerParam(P_StatusReturn, &itemp); currentStatus = (asynStatus)itemp;

        getIntegerParam(P_Int32Value, &iVal);
        iVal++;
        if (iVal > 64) iVal=0;
        setIntegerParam(P_Int32Value, iVal);
        setParamStatus( P_Int32Value, currentStatus);

        getIntegerParam(P_BinaryInt32Value, &iVal);
        iVal++;
        if (iVal > 1) iVal=0;
        setIntegerParam(P_BinaryInt32Value, iVal);
        setParamStatus( P_BinaryInt32Value, currentStatus);

        getIntegerParam(P_MultibitInt32Value, &iVal);
        iVal++;
        if (iVal > MAX_INT32_ENUMS-1) iVal=0;
        setIntegerParam(P_MultibitInt32Value, iVal);
        setParamStatus( P_MultibitInt32Value, currentStatus);

        getUIntDigitalParam(P_UInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > 64) uiVal=0;
        setUIntDigitalParam(P_UInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_UInt32DigitalValue, currentStatus);

        getUIntDigitalParam(P_BinaryUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > 1) uiVal=0;
        setUIntDigitalParam(P_BinaryUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_BinaryUInt32DigitalValue, currentStatus);

        getUIntDigitalParam(P_MultibitUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK);
        uiVal++;
        if (uiVal > MAX_UINT32_ENUMS-1) uiVal=0;
        setUIntDigitalParam(P_MultibitUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK);
        setParamStatus(     P_MultibitUInt32DigitalValue, currentStatus);

        getDoubleParam(P_Float64Value, &dVal);
        dVal += 0.1;
        setDoubleParam(P_Float64Value, dVal);
        setParamStatus(P_Float64Value, currentStatus);

        sprintf(octetValue, "%.1f", dVal); 
        setStringParam(P_OctetValue, octetValue);
        setParamStatus(P_OctetValue, currentStatus);

        for (i=0; i<MAX_ARRAY_POINTS; i++) {
            int8ArrayValue_[i]    = iVal;
            int16ArrayValue_[i]   = iVal;
            int32ArrayValue_[i]   = iVal;
            float32ArrayValue_[i] = (epicsFloat32)dVal;
            float64ArrayValue_[i] = dVal;
        }
        callParamCallbacks();
        setParamStatus(P_Int8ArrayValue,    currentStatus);
        setParamStatus(P_Int16ArrayValue,   currentStatus);
        setParamStatus(P_Int32ArrayValue,   currentStatus);
        setParamStatus(P_Float32ArrayValue, currentStatus);
        setParamStatus(P_Float64ArrayValue, currentStatus);
        doCallbacksInt8Array(int8ArrayValue_,       MAX_ARRAY_POINTS, P_Int8ArrayValue,    0);
        doCallbacksInt16Array(int16ArrayValue_,     MAX_ARRAY_POINTS, P_Int16ArrayValue,   0);
        doCallbacksInt32Array(int32ArrayValue_,     MAX_ARRAY_POINTS, P_Int32ArrayValue,   0);
        doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0);
        doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0);
        unlock();
        epicsEventWait(eventId_);
    }
}