Ejemplo n.º 1
0
static void initAuxmrWait() {
    epicsTimeStamp stime,etime;
    double elapsedTime = 0.0;
    int ntimes = 1;
    static int nloops = 1000000;
    double totalLoops;

    while(elapsedTime<1.0) {
        int i;
        ntimes *= 2;
        epicsTimeGetCurrent(&stime);
        for(i=0; i<ntimes; i++) wasteTime(nloops);
        epicsTimeGetCurrent(&etime);
        elapsedTime = epicsTimeDiffInSeconds(&etime,&stime);
    }
    totalLoops = ((double)ntimes) * ((double)nloops);
    nloopsPerMicrosecond = (totalLoops/elapsedTime)/1e6 + .99;
    if(ni1014Debug) {
        printf("totalLoops %f elapsedTime %f nloopsPerMicrosecond %ld\n",
             totalLoops,elapsedTime,nloopsPerMicrosecond);
        epicsTimeGetCurrent(&stime);
        microSecondDelay(1000000);
        epicsTimeGetCurrent(&etime);
        elapsedTime = epicsTimeDiffInSeconds(&etime,&stime);
        printf("elapsedTime %f\n",elapsedTime);
    }
}
Ejemplo n.º 2
0
static void myCallback(CALLBACK *pCallback)
{
    myPvt *pmyPvt;
    epicsTimeStamp now;
    double delay, error;

    epicsTimeGetCurrent(&now);
    callbackGetUser(pmyPvt, pCallback);

    if (pmyPvt->pass++ == 0) {
        delay = 0.0;
        error = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
        pmyPvt->start = now;
        callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay);
    } else if (pmyPvt->pass == 2) {
        double diff = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
        delay = pmyPvt->delay;
        error = fabs(delay - diff);
    } else {
        testFail("pass = %d for delay = %f", pmyPvt->pass, pmyPvt->delay);
        return;
    }
    testOk(error < 0.05, "delay %f seconds, callback time error %f",
        delay, error);
}
Ejemplo n.º 3
0
void motorSimController::motorSimTask()
{
  epicsTimeStamp now;
  double delta;
  int axis;
  motorSimAxis *pAxis;

  while ( 1 )
  {
    /* Get a new timestamp */
    epicsTimeGetCurrent( &now );
    delta = epicsTimeDiffInSeconds( &now, &(prevTime_) );
    prevTime_ = now;

    if ( delta > (DELTA/4.0) && delta <= (4.0*DELTA) )
    {
      /* A reasonable time has elapsed, it's not a time step in the clock */
      for (axis=0; axis<numAxes_; axis++) 
      {     
        this->lock();
        pAxis = getAxis(axis);
        pAxis->process(delta );
        this->unlock();
      }
    }
    epicsThreadSleep( DELTA );
  }
}
Ejemplo n.º 4
0
static void harnessExit(void *dummy) {
    epicsTimeStamp ended;
    int Faulty;

    if (!Harness) return;

    epicsTimeGetCurrent(&ended);

    printf("\n\n    EPICS Test Harness Results"
             "\n    ==========================\n\n");

    Faulty = ellCount(&faults);
    if (!Faulty)
        printf("All tests successful.\n");
    else {
        int Failures = 0;
        testFailure *f;

        printf("Failing Program           Tests  Faults\n"
               "---------------------------------------\n");
        while ((f = (testFailure *)ellGet(&faults))) {
            Failures += f->failures;
            printf("%-25s %5d   %5d\n", f->name, f->tests, f->failures);
            if (f->skips)
                printf("%d subtests skipped\n", f->skips);
            free(f);
        }
        printf("\nFailed %d/%d test programs. %d/%d subtests failed.\n",
               Faulty, Programs, Failures, Tests);
    }

    printf("Programs=%d, Tests=%d, %.0f wallclock secs\n\n",
           Programs, Tests, epicsTimeDiffInSeconds(&ended, &started));
}
Ejemplo n.º 5
0
void Sim::run()
{
    Guard G(lock);
    while(!stop) {
        if(!doSim) {
            UnGuard U(G);
            event.wait();
            continue;
        }

        doSim = false;

        epicsTimeStamp start;
        epicsTimeGetCurrent(&start);

        try {
            std::auto_ptr<StateBase> state(machine->allocState());

            machine->propagate(state.get());

            valid = true;
        }catch(std::exception& e){
            last_msg = e.what();
            valid = false;
        }

        epicsTimeGetCurrent(&last_run);
        last_duration = epicsTimeDiffInSeconds(&last_run, &start);

        scanIoRequest(aftersim);
    }
}
Ejemplo n.º 6
0
void drvFastSweep::nextPoint(epicsInt32 *newData)
{
    int i;
    int offset;
    epicsTimeStamp now;

    if (!acquiring_) return;

    offset = numAcquired_;
    for (i = 0; i < maxSignals_; i++) {
        pData_[offset] = newData[i];
        offset += maxPoints_;
    }
    numAcquired_++;
    if (numAcquired_ >= numPoints_) {
       stopAcquire();
    }
    epicsTimeGetCurrent(&now);
    elapsedTime_ = epicsTimeDiffInSeconds(&now, &startTime_);
    if ((realTime_ > 0) && (elapsedTime_ >= realTime_)) {
        stopAcquire();
    }
    setIntegerParam(fastSweepCurrentChannel_, numAcquired_);
    setDoubleParam(mcaElapsedRealTime_, elapsedTime_);
    callParamCallbacks();
}
Ejemplo n.º 7
0
void epicsSpinPerformance ()
{
    static const unsigned N = 10000;
    unsigned i;
    epicsSpinId spin;
    epicsTimeStamp begin;
    epicsTimeStamp end;
    double delay;

    /* Initialize spinlock */
    spin = epicsSpinCreate();
    if (!spin)
        testAbort("epicsSpinCreate() returned NULL");

    /* test a single lock pair */
    epicsTimeGetCurrent(&begin);
    for ( i = 0; i < N; i++ ) {
        tenLockPairsSquared(spin);
    }
    epicsTimeGetCurrent(&end);

    delay = epicsTimeDiffInSeconds(&end, &begin);
    delay /= N * 100u;  /* convert to delay per lock pair */
    delay *= 1e6;       /* convert to micro seconds */
    testDiag("lock()*1/unlock()*1 takes %f microseconds", delay);
    epicsSpinDestroy(spin);
}
Ejemplo n.º 8
0
static void motorProcTask( motorSim_t *pDrv)
{
  epicsTimeStamp now;
  double delta;
  AXIS_HDL pAxis;

  /* Get a new timestamp */
  epicsTimeGetCurrent( &now );
  delta = epicsTimeDiffInSeconds( &now, &(pDrv->now) );
  pDrv->now = now;

  if ( delta > (DELTA/4.0) && delta <= (4.0*DELTA) )
  {
    /* A reasonable time has elapsed, it's not a time step in the clock */

    for (pAxis = pDrv->pFirst; pAxis != NULL; pAxis = pAxis->pNext )
    {
      if (epicsMutexLock( pAxis->axisMutex ) == epicsMutexLockOK)
      {
        motorSimProcess( pAxis, delta );
        motorParam->callCallback( pAxis->params );
        epicsMutexUnlock( pAxis->axisMutex );
      }
    }
  }
}
Ejemplo n.º 9
0
int main(int argc, char **argv)
{
    int i, j, loop;
    int ignore=0;
    epicsTimeStamp tStart, tEnd;
    int status;

    printf("Initializing ...\n");
    xiaSetLogLevel(2);
    xiaInit("test4.ini");
    xiaStartSystem();
    for (i=0; i<NUM_SCAS; i++) {
        sca_lo[i] = calloc(1, SCA_NAME_LEN);
        sprintf(sca_lo[i], "sca%d_lo", i);
        sca_hi[i] = calloc(1, SCA_NAME_LEN);
        sprintf(sca_hi[i], "sca%d_hi", i);
    }
    for (loop=0; loop<NUM_LOOPS; loop++) {
        printf("Loop = %d/%d\n", loop+1, NUM_LOOPS);
        epicsTimeGetCurrent(&tStart);
        for (i=0; i<NUM_CHANNELS; i++) {
            printf("  channel=%d\n", i);
            for (j=0; j<NUM_SCAS; j++) {
                setSCAs(i);
            }
        }
        status = xiaBoardOperation(0, "apply", &ignore);
        CHECK_STATUS(status);
        epicsTimeGetCurrent(&tEnd);
        printf("Time = %f\n", epicsTimeDiffInSeconds(&tEnd, &tStart));
    } 
    return(0);
}
Ejemplo n.º 10
0
static long read_delta(aiRecord* prec)
{
    epicsMutexMustLock(ntpShm.ntplock);
    double val = 0.0;
    if(ntpShm.lastValid)
        val = epicsTimeDiffInSeconds(&ntpShm.lastStamp, &ntpShm.lastRx);
    else
        recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
    if(prec->tse==epicsTimeEventDeviceTime) {
        prec->time = ntpShm.lastStamp;
    }
    epicsMutexUnlock(ntpShm.ntplock);

    if(prec->linr==menuConvertLINEAR){
        val-=prec->eoff;
        if(prec->eslo!=0)
            val/=prec->eslo;
    }
    val-=prec->aoff;
    if(prec->aslo!=0)
        val/=prec->aslo;
    prec->val = val;
    prec->udf = !isfinite(val);

    return 2;
}
Ejemplo n.º 11
0
/* print list of stopped records, and breakpoints set in locksets */
long epicsShareAPI dbstat(void)
{
  struct LS_LIST *pnode;
  struct BP_LIST *pbl;
  struct EP_LIST *pqe;
  epicsTimeStamp time;

  epicsMutexMustLock(bkpt_stack_sem);

  epicsTimeGetCurrent(&time);

 /*
  *  Traverse list, reporting stopped records
  */
  pnode = (struct LS_LIST *) ellFirst(&lset_stack);
  while (pnode != NULL) {
    if (pnode->precord != NULL) {

       printf("LSet: %lu  Stopped at: %-28.28s  #B: %5.5d  T: %p\n",
             pnode->l_num, pnode->precord->name, ellCount(&pnode->bp_list), pnode->taskid);

      /* for each entrypoint detected, print out entrypoint statistics */
       pqe = (struct EP_LIST *) ellFirst(&pnode->ep_queue); 
       while (pqe != NULL) {
          double diff = epicsTimeDiffInSeconds(&time,&pqe->time);
          if (diff) {
             printf("             Entrypoint: %-28.28s  #C: %5.5lu  C/S: %7.1f\n",
                 pqe->entrypoint->name, pqe->count,diff);
          }
          pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe);
       }
    }
    else {
       printf("LSet: %lu                                            #B: %5.5d  T: %p\n",
         pnode->l_num, ellCount(&pnode->bp_list), pnode->taskid);
    }

   /*
    *  Print out breakpoints set in the lock set
    */
    pbl = (struct BP_LIST *) ellFirst(&pnode->bp_list);
    while (pbl != NULL) {
        printf("             Breakpoint: %-28.28s", pbl->precord->name);

       /* display auto print flag */
        if (pbl->precord->bkpt & BKPT_PRINT_MASK)
           printf(" (ap)\n");
        else
           printf("\n");

        pbl = (struct BP_LIST *) ellNext((ELLNODE *)pbl);
    }

    pnode = (struct LS_LIST *) ellNext((ELLNODE *)pnode);
  }

  epicsMutexUnlock(bkpt_stack_sem);
  return(0);
}
Ejemplo n.º 12
0
int devIocStatsInitCpuUsage(void)
{
    int    nBurnNoContention = 0;
    double tToWait = SECONDS_TO_BURN;
    epicsTimeStamp tStart, tEnd;
    
    if (cpuUsage.startSem) return 0;
    /* Initialize only if OS wants to spin */
    if (tToWait > 0) {
        /*wait for a tick*/
        epicsTimeGetCurrent(&tStart);
        do {
            epicsTimeGetCurrent(&tEnd);
        } while ( epicsTimeDiffInSeconds(&tEnd, &tStart) <= 0.0 );
        epicsTimeGetCurrent(&tStart);
        while(TRUE)
        {
            cpuBurn();
            epicsTimeGetCurrent(&tEnd);
            cpuUsage.tNow = epicsTimeDiffInSeconds(&tEnd, &tStart);
            if (cpuUsage.tNow >= tToWait ) break;
            nBurnNoContention++;
        }
        cpuUsage.nBurnNoContention = nBurnNoContention;
        cpuUsage.nBurnNow          = nBurnNoContention;
        cpuUsage.startSem = epicsEventMustCreate(epicsEventFull);
        cpuUsage.tNoContention = cpuUsage.tNow;
  /*
        * FIXME: epicsThreadPriorityMin is not really the lowest
        *        priority. We could use a native call to
        *        lower our priority further but OTOH there is not
        *        much going on at these low levels...
  */
        epicsThreadCreate("cpuUsageTask",
                          epicsThreadPriorityMin,
                          epicsThreadGetStackSize(epicsThreadStackMedium),
                                  (EPICSTHREADFUNC)cpuUsageTask,
                                   0);
    } else {
        cpuUsage.startSem = 0;
    }
    return 0;
}
Ejemplo n.º 13
0
/*
 * clean_addrq
 */
static void clean_addrq(void)
{
    struct channel_in_use * pciu;
    struct channel_in_use * pnextciu;
    epicsTimeStamp current;
    double delay;
    double maxdelay = 0;
    unsigned ndelete=0;
    double timeout = TIMEOUT;
    int s;

    epicsTimeGetCurrent ( &current );

    epicsMutexMustLock ( prsrv_cast_client->chanListLock );
    pnextciu = (struct channel_in_use *) 
            prsrv_cast_client->chanList.node.next;

    while( (pciu = pnextciu) ) {
        pnextciu = (struct channel_in_use *)pciu->node.next;

        delay = epicsTimeDiffInSeconds(&current,&pciu->time_at_creation);
        if (delay > timeout) {

            ellDelete(&prsrv_cast_client->chanList, &pciu->node);
            LOCK_CLIENTQ;
            s = bucketRemoveItemUnsignedId (
                pCaBucket,
                &pciu->sid);
            if(s){
                errMessage (s, "Bad id at close");
            }
            else {
                rsrvChannelCount--;
            }
            UNLOCK_CLIENTQ;
            if ( ! s ) {
                freeListFree(rsrvChanFreeList, pciu);
                ndelete++;
            }
            if(delay>maxdelay) maxdelay = delay;
        }
    }
    epicsMutexUnlock ( prsrv_cast_client->chanListLock );

#   ifdef DEBUG
    if(ndelete){
        epicsPrintf ("CAS: %d CA channels have expired after %f sec\n",
            ndelete, maxdelay);
    }
#   endif

}
Ejemplo n.º 14
0
static double cpuBurn(void)
{
    epicsTimeStamp then, now;
    double         diff;

    /* poll the clock for 500us */
    epicsTimeGetCurrent(&then);
    do {
        epicsTimeGetCurrent(&now);
        diff = epicsTimeDiffInSeconds(&now,&then);
    } while ( diff < 0.0005 );
    return diff;
}
Ejemplo n.º 15
0
void
vxStats_busyloop(unsigned busyperc)
{
    epicsTimeStamp then, now;
    double         fac = vxStats_busyloop_period/(double)100.0;

    if ( busyperc > 100 )
        busyperc = 100;

    while ( vxStats_busyloop_run ) {
        epicsTimeGetCurrent(&then);
        do {
            epicsTimeGetCurrent(&now);
        } while ( epicsTimeDiffInSeconds(&now,&then) < (double)busyperc*fac );

        epicsThreadSleep((double)(100-busyperc)*fac);
    }
}
Ejemplo n.º 16
0
int Eiger::waitFile (const char *filename, double timeout)
{
    const char *functionName = "waitFile";

    epicsTimeStamp start, now;

    request_t request;
    char requestBuf[MAX_MESSAGE_SIZE];
    request.data      = requestBuf;
    request.dataLen   = sizeof(requestBuf);
    request.actualLen = epicsSnprintf(request.data, request.dataLen,
            REQUEST_HEAD, sysStr[SSData], filename);

    response_t response;
    char responseBuf[MAX_MESSAGE_SIZE];
    response.data    = responseBuf;
    response.dataLen = sizeof(responseBuf);

    epicsTimeGetCurrent(&start);

    do
    {
        if(doRequest(&request, &response))
        {
            ERR_ARGS("[file=%s] HEAD request failed", filename);
            return EXIT_FAILURE;
        }

        if(response.code == 200)
            return EXIT_SUCCESS;

        if(response.code != 404)
        {
            ERR_ARGS("[file=%s] server returned error code %d", filename,
                    response.code);
            return EXIT_FAILURE;
        }

        epicsTimeGetCurrent(&now);
    }while(epicsTimeDiffInSeconds(&now, &start) < timeout);

    //ERR_ARGS("timeout waiting for file %s", filename);
    return EXIT_FAILURE;
}
Ejemplo n.º 17
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;
    }
}
Ejemplo n.º 18
0
int Eiger::trigger (int timeout, double exposure)
{
    // Trigger for INTS mode
    if(!exposure)
        return put(SSCommand, "trigger", "", 0, NULL, timeout);

    // Tigger for INTE mode
    // putDouble should block for the whole exposure duration, but it doesn't
    // (Eiger's fault)

    epicsTimeStamp start, end;

    epicsTimeGetCurrent(&start);
    if(putDouble(SSCommand, "trigger", exposure, NULL, timeout))
        return EXIT_FAILURE;
    epicsTimeGetCurrent(&end);

    double diff = epicsTimeDiffInSeconds(&end, &start);
    if(diff < exposure)
        epicsThreadSleep(exposure - diff);

    return EXIT_SUCCESS;
}
Ejemplo n.º 19
0
asynStatus mar345::waitForCompletion(const char *doneString, double timeout)
{
    char response[MAX_MESSAGE_SIZE];
    asynStatus status;
    double elapsedTime;
    epicsTimeStamp start, now;
    const char *functionName = "waitForCompletion";
 
    epicsTimeGetCurrent(&start);
    while (1) {
        status = readServer(response, sizeof(response), MAR345_POLL_DELAY);
        if (status == asynSuccess) {
            if (strstr(response, doneString)) return(asynSuccess);
        }
        epicsTimeGetCurrent(&now);
        elapsedTime = epicsTimeDiffInSeconds(&now, &start);
        if (elapsedTime > timeout) {
            asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
                "%s:%s: error waiting for response from marServer\n",
                driverName, functionName);
            return(asynError);
        }
    }
}
Ejemplo n.º 20
0
/*
 * Write to the TCP port
 */
static asynStatus writeIt(void *drvPvt, asynUser *pasynUser,
                          const char *data, size_t numchars,size_t *nbytesTransfered)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisWrite;
    asynStatus status = asynSuccess;
    int writePollmsec;
    int epicsTimeStatus;
    epicsTimeStamp startTime;
    epicsTimeStamp endTime;
    int haveStartTime;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "%s write.\n", tty->IPDeviceName);
    asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
                "%s write %lu\n", tty->IPDeviceName, (unsigned long)numchars);
    *nbytesTransfered = 0;
    if (tty->fd == INVALID_SOCKET) {
        if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) {
            if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess)
                return status;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s disconnected:", tty->IPDeviceName);
            return asynError;
        }
    }
    if (numchars == 0)
        return asynSuccess;
    writePollmsec = (int) (pasynUser->timeout * 1000.0);
    if (writePollmsec == 0) writePollmsec = 1;
    if (writePollmsec < 0) writePollmsec = -1;
#ifdef USE_SOCKTIMEOUT
    {
        struct timeval tv;
        tv.tv_sec = writePollmsec / 1000;
        tv.tv_usec = (writePollmsec % 1000) * 1000;
        if (setsockopt(tty->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv) < 0) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "Can't set %s socket send timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            return asynError;
        }
    }
#endif
    haveStartTime = 0;
    for (;;) {
#ifdef USE_POLL
        struct pollfd pollfd;
        pollfd.fd = tty->fd;
        pollfd.events = POLLOUT;
        epicsTimeGetCurrent(&startTime);
        while (poll(&pollfd, 1, writePollmsec) < 0) {
            if (errno != EINTR) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Poll() failed: %s", strerror(errno));
                return asynError;
            }
            epicsTimeGetCurrent(&endTime);
            if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000 > writePollmsec) break;
        }
#endif
        for (;;) {
            if (tty->socketType == SOCK_DGRAM) {
                thisWrite = sendto(tty->fd, (char *)data, (int)numchars, 0, &tty->farAddr.oa.sa, (int)tty->farAddrSize);
            } else {
                thisWrite = send(tty->fd, (char *)data, (int)numchars, 0);
            }
            if (thisWrite >= 0) break;
            if (SOCKERRNO == SOCK_EWOULDBLOCK || SOCKERRNO == SOCK_EINTR) {
                if (!haveStartTime) {
                    epicsTimeStatus = epicsTimeGetCurrent(&startTime);
                    assert(epicsTimeStatus == epicsTimeOK);
                    haveStartTime = 1;
                } else if (pasynUser->timeout >= 0) {
                    epicsTimeStatus = epicsTimeGetCurrent(&endTime);
                    assert(epicsTimeStatus == epicsTimeOK);
                    if (epicsTimeDiffInSeconds(&endTime, &startTime) >
                            pasynUser->timeout) {
                        thisWrite = 0;
                        break;
                    }
                }
                epicsThreadSleep(SEND_RETRY_DELAY);
            } else break;
        }
        if (thisWrite > 0) {
            tty->nWritten += (unsigned long)thisWrite;
            *nbytesTransfered += thisWrite;
            numchars -= thisWrite;
            if (numchars == 0)
                break;
            data += thisWrite;
        }
        else if (thisWrite == 0) {
            status = asynTimeout;
            break;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
                          "%s write error: %s", tty->IPDeviceName,
                          strerror(SOCKERRNO));
            closeConnection(pasynUser,tty,"Write error");
            status = asynError;
            break;
        }
    }
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "wrote %lu to %s, return %s.\n", (unsigned long)*nbytesTransfered,
              tty->IPDeviceName,
              pasynManager->strStatus(status));
    return status;
}
Ejemplo n.º 21
0
static asynStatus AIMWrite(void *drvPvt, asynUser *pasynUser,
                           epicsInt32 ivalue, epicsFloat64 dvalue)
{
    mcaAIMPvt *pPvt = (mcaAIMPvt *)drvPvt;
    mcaCommand command=pasynUser->reason;
    asynStatus status=asynSuccess;
    int len;
    int address, seq;
    int signal;
    epicsTimeStamp now;

    pasynManager->getAddr(pasynUser, &signal);

    asynPrint(pasynUser, ASYN_TRACE_FLOW, 
             "mcaAIMAsynDriver::AIMWrite entry, command=%d, signal=%d, "
             "ivalue=%d, dvalue=%f\n", command, signal, ivalue, dvalue);
    switch (command) {
        case mcaStartAcquire:
            /* Start acquisition. */
            status = nmc_acqu_setstate(pPvt->module, pPvt->adc, 1);
            break;
        case mcaStopAcquire:
            /* stop data acquisition */
            status = nmc_acqu_setstate(pPvt->module, pPvt->adc, 0);
            break;
        case mcaErase:
            /* Erase. If this is signal 0 then erase memory for all signals.
             * Databases take advantage of this for performance with
             * multielement detectors with multiplexors */
            if (signal == 0)
                len = pPvt->maxChans*pPvt->maxSignals*4;
            else
                len = pPvt->nchans*4;
            /* If AIM is acquiring, turn if off */
            if (pPvt->acquiring)
            status = nmc_acqu_setstate(pPvt->module, pPvt->adc, 0);
            address = pPvt->seq_address + pPvt->maxChans*signal*4;
            status = nmc_acqu_erase(pPvt->module, address, len);
            asynPrint(pasynUser, ASYN_TRACE_FLOW,
                    "(mcaAIMAsynDriver::command [%s signal=%d]):"
                    " erased %d chans, status=%d\n",
                    pPvt->portName, signal, len, status);
            /* Set the elapsed live and real time back to zero. */
            status = nmc_acqu_setelapsed(pPvt->module, pPvt->adc, 0, 0);
            /* If AIM was acquiring, turn it back on */
            if (pPvt->acquiring)
                status = nmc_acqu_setstate(pPvt->module, pPvt->adc, 1);
                break;
        case mcaReadStatus:
            /* The status will be the same for each signal on a port.
             * We optimize by not reading the status if this is not
             * signal 0 and if the cached status is relatively recent
             * Read the current status of the device if signal 0 or
             * if the existing status info is too old */
            epicsTimeGetCurrent(&now);
            if ((signal == 0) || 
                    (epicsTimeDiffInSeconds(&now, &pPvt->statusTime)
                    > pPvt->maxStatusTime)) {
                status = nmc_acqu_statusupdate(pPvt->module, pPvt->adc, 0, 0, 0,
                                              &pPvt->elive, &pPvt->ereal, 
                                              &pPvt->etotals, &pPvt->acquiring);
                asynPrint(pasynUser, ASYN_TRACE_FLOW,
                          "(mcaAIMAsynDriver [%s signal=%d]): get_acq_status=%d\n",
                          pPvt->portName, signal, status);
                epicsTimeGetCurrent(&pPvt->statusTime);
            }
        case mcaChannelAdvanceSource:
            /* set channel advance source */
            /* This is a NOOP for current MCS hardware - done manually */
            break;
        case mcaNumChannels:
            /* set number of channels */
            pPvt->nchans = ivalue;
            if (pPvt->nchans > pPvt->maxChans) {
                asynPrint(pasynUser, ASYN_TRACE_ERROR, 
                          "mcaAIMServer Illegal nuse field");
                pPvt->nchans = pPvt->maxChans;
            }
            status = sendAIMSetup(pPvt);
            break;
        case mcaAcquireMode:
            if (ivalue == mcaAcquireMode_PHA)  pPvt->acqmod = 1;
            if (ivalue == mcaAcquireMode_MCS)  pPvt->acqmod = 1;
            if (ivalue == mcaAcquireMode_List) pPvt->acqmod = 3;
            status = sendAIMSetup(pPvt);
            break;
        case mcaSequence:
            /* set sequence number */
            seq = ivalue;
            if (seq > pPvt->maxSequences) {
                asynPrint(pasynUser, ASYN_TRACE_ERROR, 
                          "mcaAIMAsynDriver::command: Illegal seq field\n");
                seq = pPvt->maxSequences;
            }
            pPvt->seq_address = pPvt->base_address + 
                                      pPvt->maxChans * pPvt->maxSignals * seq * 4;
            status = sendAIMSetup(pPvt);
            break;
        case mcaPrescale:
            /* No-op for AIM */
            break;
        case mcaPresetSweeps:
            /* set number of sweeps (for MCS mode) */
            /* This is a NOOP on current version of MCS */
            break;
        case mcaPresetLowChannel:
            /* set lower side of region integrated for preset counts */
            /* The preset total start channel is in bytes from start of
               AIM memory */
            pPvt->ptschan = pPvt->seq_address + 
                                  pPvt->maxChans*signal*4 + ivalue*4;
            status = sendAIMSetup(pPvt);
            break;
        case mcaPresetHighChannel:
            /* set high side of region integrated for preset counts */
            /* The preset total end channel is in bytes from start of
               AIM memory */
            pPvt->ptechan = pPvt->seq_address + 
                                  pPvt->maxChans*signal*4 + ivalue*4;
            status = sendAIMSetup(pPvt);
            break;
        case mcaDwellTime:
            /* set dwell time */
            /* This is a NOOP for current MCS hardware - done manually */
            break;
        case mcaPresetRealTime:
            /* set preset real time. Convert to centiseconds */
            pPvt->preal = (int) (100. * dvalue);
            status = sendAIMSetup(pPvt);
            break;
        case mcaPresetLiveTime:
            /* set preset live time. Convert to centiseconds */
            pPvt->plive = (int) (100. * dvalue);
            status = sendAIMSetup(pPvt);
            break;
        case mcaPresetCounts:
            /* set preset counts */
            pPvt->ptotal = dvalue;
            status = sendAIMSetup(pPvt);
            break;
        default:
            asynPrint(pasynUser, ASYN_TRACE_ERROR, 
                      "mcaAIMAsynDriver::command port %s got illegal command %d\n",
                      pPvt->portName, command);
            break;
    }
    return(asynSuccess);
}
Ejemplo n.º 22
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_);
      }
    }  
  }
}
Ejemplo n.º 23
0
/*
 * logClientDestroy
 */
static void logClientDestroy (logClientId id)
{
    enum epicsSocketSystemCallInterruptMechanismQueryInfo interruptInfo;
    logClient *pClient = (logClient *) id;
    epicsTimeStamp begin, current;
    double diff;

    /* command log client thread to shutdown - taking mutex here */
    /* forces cache flush on SMP machines */
    epicsMutexMustLock ( pClient->mutex );
    pClient->shutdown = 1u;
    epicsMutexUnlock ( pClient->mutex );

    /* unblock log client thread blocking in send() or connect() */
    interruptInfo =
        epicsSocketSystemCallInterruptMechanismQuery ();
    switch ( interruptInfo ) {
    case esscimqi_socketCloseRequired:
        logClientClose ( pClient );
        break;
    case esscimqi_socketBothShutdownRequired:
        shutdown ( pClient->sock, SHUT_WR );
        break;
    case esscimqi_socketSigAlarmRequired:
        epicsSignalRaiseSigAlarm ( pClient->restartThreadId );
        break;
    default:
        break;
    };

    /* wait for confirmation that the thread exited - taking */
    /* mutex here forces cache update on SMP machines */
    epicsTimeGetCurrent ( & begin );
    epicsMutexMustLock ( pClient->mutex );
    do {
        epicsMutexUnlock ( pClient->mutex );
        epicsEventWaitWithTimeout ( 
            pClient->stateChangeNotify, 
            LOG_SERVER_SHUTDOWN_TIMEOUT / 10.0 ); 
        epicsTimeGetCurrent ( & current );
        diff = epicsTimeDiffInSeconds ( & current, & begin );
        epicsMutexMustLock ( pClient->mutex );
    }
    while ( ! pClient->shutdownConfirm && diff < LOG_SERVER_SHUTDOWN_TIMEOUT );
    epicsMutexUnlock ( pClient->mutex );

    if ( ! pClient->shutdownConfirm ) {
        fprintf ( stderr, "log client shutdown: timed out stopping"
            " reconnect thread for \"%s\" after %.1f seconds - cleanup aborted\n",
            pClient->name, LOG_SERVER_SHUTDOWN_TIMEOUT );
        return;
    }

    logClientClose ( pClient );

    epicsMutexDestroy ( pClient->mutex );
   
    epicsEventDestroy ( pClient->stateChangeNotify );

    free ( pClient );
}
Ejemplo n.º 24
0
/*
 *  log_one_client ()
 */
static void log_one_client (struct client *client, unsigned level)
{
    char                    *pproto;
    double                  send_delay;
    double                  recv_delay;
    char                    *state[] = {"up", "down"};
    epicsTimeStamp          current;
    char                    clientHostName[256];

    ipAddrToDottedIP (&client->addr, clientHostName, sizeof(clientHostName));

    if(client->proto == IPPROTO_UDP){
        pproto = "UDP";
    }
    else if(client->proto == IPPROTO_TCP){
        pproto = "TCP";
    }
    else{
        pproto = "UKN";
    }

    epicsTimeGetCurrent(&current);
    send_delay = epicsTimeDiffInSeconds(&current,&client->time_at_last_send);
    recv_delay = epicsTimeDiffInSeconds(&current,&client->time_at_last_recv);

    printf ( "%s %s(%s): User=\"%s\", V%u.%u, %d Channels, Priority=%u\n", 
        pproto,
        clientHostName,
        client->pHostName ? client->pHostName : "",
        client->pUserName ? client->pUserName : "",
        CA_MAJOR_PROTOCOL_REVISION,
        client->minor_version_number,
        ellCount(&client->chanList) + 
            ellCount(&client->chanPendingUpdateARList),
        client->priority );
    if ( level >= 1 ) {
        printf ("\tTask Id=%p, Socket FD=%d\n", 
            (void *) client->tid, client->sock); 
        printf( 
        "\tSecs since last send %6.2f, Secs since last receive %6.2f\n", 
            send_delay, recv_delay);
        printf( 
        "\tUnprocessed request bytes=%u, Undelivered response bytes=%u\n", 
            client->recv.cnt - client->recv.stk,
            client->send.stk ); 
        printf( 
        "\tState=%s%s%s\n", 
            state[client->disconnect?1:0],
            client->send.type == mbtLargeTCP ? " jumbo-send-buf" : "",
            client->recv.type == mbtLargeTCP ? " jumbo-recv-buf" : "");
    }

    if ( level >= 2u ) {
        unsigned bytes_reserved = 0;
        bytes_reserved += sizeof(struct client);
        bytes_reserved += countChanListBytes ( 
                            client, & client->chanList );
        bytes_reserved += countChanListBytes ( 
                        client, & client->chanPendingUpdateARList );
        printf( "\t%d bytes allocated\n", bytes_reserved);
        showChanList ( client, & client->chanList );
        showChanList ( client, & client->chanPendingUpdateARList );
        printf("\n");
    }

    if ( level >= 3u ) {
        printf( "\tSend Lock\n");
        epicsMutexShow(client->lock,1);
        printf( "\tPut Notify Lock\n");
        epicsMutexShow (client->putNotifyLock,1);
        printf( "\tAddress Queue Lock\n");
        epicsMutexShow (client->chanListLock,1);
        printf( "\tEvent Queue Lock\n");
        epicsMutexShow (client->eventqLock,1);
        printf( "\tBlock Semaphore\n");
        epicsEventShow (client->blockSem,1);
    }
}
Ejemplo n.º 25
0
static long histScalerDma_do(aSubRecord *pasub) {
	int j;
	epicsUInt32 *data;
	epicsTimeStamp  timeStart, timeEnd;
	double dmaTime;
	struct dma_proxy_channel_interface *hs_rx_proxy_interface_p;
	int hs_rx_proxy_fd;
	int dummy = 0;
	int timeout_msecs = 10;
	int dma_bytes; /* in bytes32-byte events */
	int dma_words;

	int *clear = (int *)pasub->d;
	epicsUInt32 *counts1 = (epicsUInt32 *)pasub->vala;

	int i;
	int *debug = (int *)pasub->h;

	if (*debug>1) {
		printf("histScalerDma_do: entry\n");
	}

	if (*clear) {
		/* erase pixel maps */
		for (i=0; i<pasub->nova; i++) {
			counts1[i] = 0;
		}
		*histClear = 0x20;
		*histClear = 0;
		*clear = 0;
	}

	/* cause HistScal component to dump its data to the FIFO */
	*histRead = 0x20;
	*histRead = 0;

	dma_words = *histScalerDmaWords;
	dma_bytes = dma_words*4;

	if (*hs_fifoCountAddr < dma_words) {
		if (*debug>1) {
			printf("histScalerDma_do: avail words (%d) < dma_words (%d)\n",
				*hs_fifoCountAddr, dma_words);
		}
		return(0);
	}

	/* do DMA */
	hs_rx_proxy_fd = open("/dev/dma_proxy_rx", O_RDWR);
	if (hs_rx_proxy_fd < 1) {
		printf("histScalerDmaRoutine: Unable to open DMA proxy device file for RX\n");
		return(0);
	}
	hs_rx_proxy_interface_p = (struct dma_proxy_channel_interface *)mmap(NULL, sizeof(struct dma_proxy_channel_interface),
			PROT_READ | PROT_WRITE, MAP_SHARED, hs_rx_proxy_fd, 0);

    if (hs_rx_proxy_interface_p == MAP_FAILED) {
       	printf("histScalerDmaRoutine: Failed to mmap for RX\n");
       	return(0);
    }

	hs_rx_proxy_interface_p->length = dma_bytes;
	hs_rx_proxy_interface_p->timeout_msecs = timeout_msecs;

	dmaTime = 0;

	/* Perform the DMA transfer and after it finishes check the status */
	epicsTimeGetCurrent(&timeStart);
	ioctl(hs_rx_proxy_fd, 0, &dummy);
	if (*debug && (hs_rx_proxy_interface_p->status != PROXY_NO_ERROR)) {
		printf("histScalerDmaRoutine: Proxy rx transfer error\n");
		munmap(hs_rx_proxy_interface_p, sizeof(struct dma_proxy_channel_interface));
		close(hs_rx_proxy_fd);
		return(0);
	}
	data = (epicsUInt32 *)(hs_rx_proxy_interface_p->buffer);
	epicsTimeGetCurrent(&timeEnd);
	dmaTime += epicsTimeDiffInSeconds(&timeEnd, &timeStart);

	/*** collect data ***/
	for (j=0; j<dma_words; j++) {
		counts1[j] = data[j] & 0x7fffffff;
		if (*debug > 10) printf("histScalerDmaRoutine: counts1[%d]=%d, first==%d\n", j, counts1[j], (data[j] & 0x80000000)!=0);
		*clear = 0;
	}
	/* If there's enough data in the FIFO, do another DMA transaction. */
	if (*debug > 1) printf("histScalerDmaRoutine: *hs_fifoCountAddr=%d\n", *hs_fifoCountAddr);

	if (*debug) printf("histScalerDmaRoutine: DMA time=%f\n", dmaTime);
	if (*debug>=10) printf("histScalerDmaRoutine: done binning this buffer.\n");
	/* For now, just open and close every time */
	munmap(hs_rx_proxy_interface_p, sizeof(struct dma_proxy_channel_interface));
	close(hs_rx_proxy_fd);

	return(0);
}
Ejemplo n.º 26
0
static void NTPTimeSync(void *dummy)
{
    taskwdInsert(0, NULL, NULL);

    for (epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval);
         NTPTimePvt.synchronize;
         epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval)) {
        int             status;
        struct timespec timespecNow;
        epicsTimeStamp  timeNow;
        epicsUInt32     tickNow;
        double          diff;
        double          ntpDelta;

        status = osdNTPGet(&timespecNow);
        tickNow = osdTickGet();

        if (status) {
            if (++NTPTimePvt.syncsFailed > NTPTimeSyncRetries &&
                NTPTimePvt.synchronized) {
                errlogPrintf("NTPTimeSync: NTP requests failing - %s\n",
                    strerror(errno));
                NTPTimePvt.synchronized = 0;
            }
            continue;
        }

        if (timespecNow.tv_sec <= POSIX_TIME_AT_EPICS_EPOCH ||
            epicsTimeFromTimespec(&timeNow, &timespecNow) == epicsTimeERROR) {
            errlogPrintf("NTPTimeSync: Bad time received from NTP server\n");
            NTPTimePvt.synchronized = 0;
            continue;
        }

        ntpDelta = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.syncTime);
        if (ntpDelta <= 0.0 && NTPTimePvt.synchronized) {
            errlogPrintf("NTPTimeSync: NTP time not increasing, delta = %g\n",
                ntpDelta);
            NTPTimePvt.synchronized = 0;
            continue;
        }

        NTPTimePvt.syncsFailed = 0;
        if (!NTPTimePvt.synchronized) {
            errlogPrintf("NTPTimeSync: Sync recovered.\n");
        }

        epicsMutexMustLock(NTPTimePvt.lock);
        diff = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.clockTime);
        if (diff >= 0.0) {
            NTPTimePvt.ticksToSkip = 0;
        } else { /* dont go back in time */
            NTPTimePvt.ticksToSkip = -diff * osdTickRateGet();
        }
        NTPTimePvt.clockTick = tickNow;
        NTPTimePvt.clockTime = timeNow;
        NTPTimePvt.synchronized = 1;
        epicsMutexUnlock(NTPTimePvt.lock);

        NTPTimePvt.tickRate = (tickNow - NTPTimePvt.syncTick) / ntpDelta;
        NTPTimePvt.syncTick = tickNow;
        NTPTimePvt.syncTime = timeNow;
    }

    NTPTimePvt.synchronized = 0;
    taskwdRemove(0);
}
Ejemplo n.º 27
0
/*
 * Read from the TCP port
 */
static asynStatus readIt(void *drvPvt, asynUser *pasynUser,
                         char *data, size_t maxchars,size_t *nbytesTransfered,int *gotEom)
{
    ttyController_t *tty = (ttyController_t *)drvPvt;
    int thisRead;
    int readPollmsec;
    int reason = 0;
    epicsTimeStamp startTime;
    epicsTimeStamp endTime;
    asynStatus status = asynSuccess;

    assert(tty);
    asynPrint(pasynUser, ASYN_TRACE_FLOW,
              "%s read.\n", tty->IPDeviceName);
    if (tty->fd == INVALID_SOCKET) {
        if (tty->flags & FLAG_CONNECT_PER_TRANSACTION) {
            if ((status = connectIt(drvPvt, pasynUser)) != asynSuccess)
                return status;
        }
        else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s disconnected:", tty->IPDeviceName);
            return asynError;
        }
    }
    if (maxchars <= 0) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                      "%s maxchars %d. Why <=0?",tty->IPDeviceName,(int)maxchars);
        return asynError;
    }
    readPollmsec = (int) (pasynUser->timeout * 1000.0);
    if (readPollmsec == 0) readPollmsec = 1;
    if (readPollmsec < 0) readPollmsec = -1;
#ifdef USE_SOCKTIMEOUT
    {
        struct timeval tv;
        tv.tv_sec = readPollmsec / 1000;
        tv.tv_usec = (readPollmsec % 1000) * 1000;
        if (setsockopt(tty->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) < 0) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "Can't set %s socket receive timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            status = asynError;
        }
    }
#endif
    if (gotEom) *gotEom = 0;
#ifdef USE_POLL
    {
        struct pollfd pollfd;
        pollfd.fd = tty->fd;
        pollfd.events = POLLIN;
        epicsTimeGetCurrent(&startTime);
        while (poll(&pollfd, 1, readPollmsec) < 0) {
            if (errno != EINTR) {
                epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                              "Poll() failed: %s", strerror(errno));
                return asynError;
            }
            epicsTimeGetCurrent(&endTime);
            if (epicsTimeDiffInSeconds(&endTime, &startTime)*1000. > readPollmsec) break;
        }
    }
#endif
    if (tty->socketType == SOCK_DGRAM) {
        /* We use recvfrom() for SOCK_DRAM so we can print the source address with ASYN_TRACEIO_DRIVER */
        osiSockAddr oa;
        unsigned int addrlen = sizeof(oa.ia);
        thisRead = recvfrom(tty->fd, data, (int)maxchars, 0, &oa.sa, &addrlen);
        if (thisRead > 0) {
            if (pasynTrace->getTraceMask(pasynUser) & ASYN_TRACEIO_DRIVER) {
                char inetBuff[32];
                ipAddrToDottedIP(&oa.ia, inetBuff, sizeof(inetBuff));
                asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                            "%s (from %s) read %d\n",
                            tty->IPDeviceName, inetBuff, thisRead);
            }
            tty->nRead += (unsigned long)thisRead;
        }
    } else {
        thisRead = recv(tty->fd, data, (int)maxchars, 0);
        if (thisRead > 0) {
            asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, thisRead,
                        "%s read %d\n", tty->IPDeviceName, thisRead);
            tty->nRead += (unsigned long)thisRead;
        }
    }
    if (thisRead < 0) {
        int should_close = (tty->userFlags & USERFLAG_CLOSE_ON_READ_TIMEOUT) ||
                           ((SOCKERRNO != SOCK_EWOULDBLOCK) && (SOCKERRNO != SOCK_EINTR));
        if (should_close) {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s read error: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            closeConnection(pasynUser,tty,"Read error");
            status = asynError;
        } else {
            epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                          "%s timeout: %s",
                          tty->IPDeviceName, strerror(SOCKERRNO));
            status = asynTimeout;
        }
    }
    /* If recv() returns 0 on a SOCK_STREAM (TCP) socket, the connection has closed */
    if ((thisRead == 0) && (tty->socketType == SOCK_STREAM)) {
        epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
                      "%s connection closed",
                      tty->IPDeviceName);
        closeConnection(pasynUser,tty,"Read from broken connection");
        reason |= ASYN_EOM_END;
    }
    if (thisRead < 0)
        thisRead = 0;
    *nbytesTransfered = thisRead;
    /* If there is room add a null byte */
    if (thisRead < (int) maxchars)
        data[thisRead] = 0;
    else
        reason |= ASYN_EOM_CNT;
    if (gotEom) *gotEom = reason;
    return status;
}
Ejemplo n.º 28
0
/** This thread controls acquisition, reads image files to get the image data,
  * and does the callbacks to send it to higher layers */
void hdf5Driver::hdf5Task (void)
{
    const char *functionName = "hdf5Task";
    int status = asynSuccess;
    epicsTimeStamp startTime, endTime;
    int imageMode, currentFrame, colorMode;
    double acquirePeriod, elapsedTime, delay;

    this->lock();

    for(;;)
    {
        int acquire;
        getIntegerParam(ADAcquire, &acquire);

        if (!acquire)
        {
            this->unlock(); // Wait for semaphore unlocked

            asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: waiting for acquire to start\n",
                    driverName, functionName);

            status = epicsEventWait(this->mStartEventId);

            this->lock();

            acquire = 1;
            setStringParam(ADStatusMessage, "Acquiring data");
            setIntegerParam(ADNumImagesCounter, 0);
        }

        // Are there datasets loaded?
        if(!mDatasetsCount)
        {
            setStringParam(ADStatusMessage, "No datasets loaded");
            goto error;
        }

        // Get acquisition parameters
        epicsTimeGetCurrent(&startTime);
        getIntegerParam(ADImageMode, &imageMode);
        getDoubleParam(ADAcquirePeriod, &acquirePeriod);
        getIntegerParam(HDF5CurrentFrame, &currentFrame);
        setIntegerParam(ADStatus, ADStatusAcquire);
        callParamCallbacks();

        // Get information to allocate NDArray
        size_t dims[2];
        NDDataType_t dataType;
        if(getFrameInfo(currentFrame, dims, &dataType))
        {
            setStringParam(ADStatusMessage, "Failed to get frame info");
            goto error;
        }

        // Allocate NDArray
        NDArray *pImage;
        if(!(pImage = pNDArrayPool->alloc(2, dims, dataType, 0, NULL)))
        {
            setStringParam(ADStatusMessage, "Failed to allocate frame");
            goto error;
        }

        // Copy data into NDArray
        if(getFrameData(currentFrame, pImage->pData))
        {
            setStringParam(ADStatusMessage, "Failed to read frame data");
            goto error;
        }

        // Set ColorMode
        colorMode = NDColorModeMono;
        pImage->pAttributeList->add("ColorMode", "Color mode", NDAttrInt32,
                &colorMode);

        // Call plugins callbacks
        int arrayCallbacks;
        getIntegerParam(NDArrayCallbacks, &arrayCallbacks);
        if (arrayCallbacks)
        {
          this->unlock();
          asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
                    "%s:%s: calling imageData callback\n",
                    driverName, functionName);
          doCallbacksGenericPointer(pImage, NDArrayData, 0);
          this->lock();
        }
        pImage->release();

        // Get the current parameters
        int lastFrame, imageCounter, numImages, numImagesCounter;
        getIntegerParam(HDF5LastFrame,      &lastFrame);
        getIntegerParam(NDArrayCounter,     &imageCounter);
        getIntegerParam(ADNumImages,        &numImages);
        getIntegerParam(ADNumImagesCounter, &numImagesCounter);

        setIntegerParam(NDArrayCounter,     ++imageCounter);
        setIntegerParam(ADNumImagesCounter, ++numImagesCounter);
        setIntegerParam(HDF5CurrentFrame,   ++currentFrame);

        // Put the frame number and time stamp into the buffer
        pImage->uniqueId = imageCounter;
        pImage->timeStamp = startTime.secPastEpoch + startTime.nsec / 1.e9;
        updateTimeStamp(&pImage->epicsTS);

        // Prepare loop if necessary
        int loop;
        getIntegerParam(HDF5Loop, &loop);

        if (loop && currentFrame > lastFrame)
        {
            getIntegerParam(HDF5FirstFrame,   &currentFrame);
            setIntegerParam(HDF5CurrentFrame, currentFrame);
        }

        // See if acquisition is done
        if (imageMode == ADImageSingle || currentFrame > lastFrame ||
            (imageMode == ADImageMultiple && numImagesCounter >= numImages))
        {
          // First do callback on ADStatus
          setStringParam(ADStatusMessage, "Waiting for acquisition");
          setIntegerParam(ADStatus, ADStatusIdle);

          acquire = 0;
          setIntegerParam(ADAcquire, acquire);

          asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
                  "%s:%s: acquisition completed\n",
                  driverName, functionName);
        }

        callParamCallbacks();

        // Delay next acquisition and check if received STOP signal
        if(acquire)
        {
            epicsTimeGetCurrent(&endTime);
            elapsedTime = epicsTimeDiffInSeconds(&endTime, &startTime);
            delay = acquirePeriod - elapsedTime;
            asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
                      "%s:%s: delay=%f\n",
                      driverName, functionName, delay);
            if(delay > 0.0)
            {
                // Set the status to waiting to indicate we are in the delay
                setIntegerParam(ADStatus, ADStatusWaiting);
                callParamCallbacks();
                this->unlock();
                status = epicsEventWaitWithTimeout(mStopEventId, delay);
                this->lock();

                if (status == epicsEventWaitOK)
                {
                    acquire = 0;
                    if (imageMode == ADImageContinuous)
                        setIntegerParam(ADStatus, ADStatusIdle);
                    else
                        setIntegerParam(ADStatus, ADStatusAborted);

                  callParamCallbacks();
                }
            }
        }
        continue;

error:
        setIntegerParam(ADAcquire, 0);
        setIntegerParam(ADStatus, ADStatusError);
        callParamCallbacks();
        continue;
    }
}
Ejemplo n.º 29
0
/** This thread controls handling of slow events - erase, acquire, change mode */
void mar345::mar345Task()
{
    int status = asynSuccess;
    int numImages, numImagesCounter;
    int imageMode;
    int acquire;
    double acquirePeriod;
    double elapsedTime, delayTime;
    const char *functionName = "mar345Task";

    this->lock();

    /* Loop forever */
    while (1) {
        setStringParam(ADStatusMessage, "Waiting for event");
        callParamCallbacks();
        /* Release the lock while we wait for an event that says acquire has started, then lock again */
        this->unlock();
        asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: waiting for start event\n", driverName, functionName);
        status = epicsEventWait(this->startEventId);
        this->lock();

        switch(this->mode) {
            case mar345ModeErase:
                this->erase();
                this->mode = mar345ModeIdle;
                break;

            case mar345ModeAcquire:
                getIntegerParam(ADImageMode, &imageMode);
                getIntegerParam(ADNumImages, &numImages);
                if (numImages < 1) numImages = 1;
                if (imageMode == ADImageSingle) numImages=1;
                for (numImagesCounter=0;
                        numImagesCounter<numImages || (imageMode == ADImageContinuous); 
                        numImagesCounter++) {
                    if (epicsEventTryWait(this->abortEventId) == epicsEventWaitOK) break;
                    setIntegerParam(ADNumImagesCounter, numImagesCounter);
                    callParamCallbacks();
                    status = acquireFrame();
                    if (status) break;
                    /* We get out of the loop in single shot mode or if acquire was set to 0 by client */
                    if (imageMode == ADImageSingle) setIntegerParam(ADAcquire, 0);
                    getIntegerParam(ADAcquire, &acquire);
                    if (!acquire) break;
                    /* We are in continuous or multiple mode.
                     * Sleep until the acquire period expires or acquire is set to stop */
                    epicsTimeGetCurrent(&this->acqEndTime);
                    elapsedTime = epicsTimeDiffInSeconds(&this->acqEndTime, &this->acqStartTime);
                    getDoubleParam(ADAcquirePeriod, &acquirePeriod);
                    delayTime = acquirePeriod - elapsedTime;
                    if (delayTime > 0.) {
                        setIntegerParam(ADStatus, mar345StatusWaiting);
                        callParamCallbacks();
                        this->unlock();
                        status = epicsEventWaitWithTimeout(this->abortEventId, delayTime);
                        this->lock();
                        if (status == epicsEventWaitOK) break;
                    }
                }
                this->mode = mar345ModeIdle;
                setIntegerParam(ADAcquire, 0);
                setIntegerParam(ADStatus, mar345StatusIdle);
                break;

            case mar345ModeChange:
                this->changeMode();
                this->mode = mar345ModeIdle;
                break;
                
            default:
                break;
        }

        /* Call the callbacks to update any changes */
        callParamCallbacks();
    }
}
Ejemplo n.º 30
0
asynStatus mar345::acquireFrame()
{
    asynStatus status=asynSuccess;
    epicsTimeStamp startTime, currentTime;
    int eraseMode;
    epicsEventWaitStatus waitStatus;
    int imageCounter;
    int arrayCallbacks;
    double acquireTime;
    double timeRemaining;
    int size, res;
    int shutterMode, useShutter;
    char tempFileName[MAX_FILENAME_LEN];
    char fullFileName[MAX_FILENAME_LEN];
    //const char *functionName = "acquireframe";

    /* Get current values of some parameters */
    getDoubleParam(ADAcquireTime, &acquireTime);
    getIntegerParam(ADShutterMode, &shutterMode);
    getIntegerParam(mar345Size, &size);
    getIntegerParam(mar345Res, &res);
    getIntegerParam(NDArrayCallbacks, &arrayCallbacks);
    getIntegerParam(mar345EraseMode, &eraseMode);
    if (shutterMode == ADShutterModeNone) useShutter=0; else useShutter=1;

    epicsTimeGetCurrent(&this->acqStartTime);

    createFileName(MAX_FILENAME_LEN, tempFileName);
    /* We need to append the extension */
    epicsSnprintf(fullFileName, sizeof(fullFileName), "%s.mar%d", tempFileName, imageSizes[res][size]);

    /* Erase before exposure if set */
    if (eraseMode == mar345EraseBefore) {
        status = this->erase();
        if (status) return(status);
    }
    
    /* Set the the start time for the TimeRemaining counter */
    epicsTimeGetCurrent(&startTime);
    timeRemaining = acquireTime;
    if (useShutter) setShutter(1);

    /* Wait for the exposure time using epicsEventWaitWithTimeout, 
     * so we can abort */
    epicsTimerStartDelay(this->timerId, acquireTime);
    setIntegerParam(ADStatus, mar345StatusExpose);
    callParamCallbacks();
    while(1) {
        if (epicsEventTryWait(this->abortEventId) == epicsEventWaitOK) {
            status = asynError;
            break;
        }
        this->unlock();
        waitStatus = epicsEventWaitWithTimeout(this->stopEventId, MAR345_POLL_DELAY);
        this->lock();
        if (waitStatus == epicsEventWaitOK) {
            /* The acquisition was stopped before the time was complete */
            epicsTimerCancel(this->timerId);
            break;
        }
        epicsTimeGetCurrent(&currentTime);
        timeRemaining = acquireTime - 
            epicsTimeDiffInSeconds(&currentTime, &startTime);
        if (timeRemaining < 0.) timeRemaining = 0.;
        setDoubleParam(ADTimeRemaining, timeRemaining);
        callParamCallbacks();
    }
    setDoubleParam(ADTimeRemaining, 0.0);
    if (useShutter) setShutter(0);
    setIntegerParam(ADStatus, mar345StatusIdle);
    callParamCallbacks();
    // If the exposure was aborted return error
    if (status) return asynError;
    setIntegerParam(ADStatus, mar345StatusScan);
    callParamCallbacks();
    epicsSnprintf(this->toServer, sizeof(this->toServer), "COMMAND SCAN %s", fullFileName);
    setStringParam(NDFullFileName, fullFileName);
    callParamCallbacks();
    writeServer(this->toServer);
    status = waitForCompletion("SCAN_DATA    Ended o.k.", MAR345_COMMAND_TIMEOUT);
    if (status) {
        return asynError;
    }
    getIntegerParam(NDArrayCounter, &imageCounter);
    imageCounter++;
    setIntegerParam(NDArrayCounter, imageCounter);
    /* Call the callbacks to update any changes */
    callParamCallbacks();

    /* If arrayCallbacks is set then read the file back in */
    if (arrayCallbacks) {
        getImageData();
    }

    /* Erase after scanning if set */
    if (eraseMode == mar345EraseAfter) status = this->erase();

    return status;
}