int simRegDevAsynTransfer( regDevice *device, unsigned int dlen, size_t nelem, void* src, void* dest, void* pmask, int prio, regDevTransferComplete callback, const char* user, int isOutput) { simRegDevMessage* msg; if (simRegDevDebug & (isOutput ? DBG_OUT : DBG_IN)) printf ("simRegDevAsynTransfer %s %s: copy %s %u bytes * %"Z"u elements\n", user, device->name, isOutput ? "out" : "in", dlen, nelem); epicsMutexLock(device->lock); if (device->msgFreelist[prio] == NULL) { msg = calloc(sizeof(simRegDevMessage),1); if (msg) msg->timer = epicsTimerQueueCreateTimer(device->queue[prio], simRegDevCallback, msg); if (msg == NULL || msg->timer == NULL) { errlogSevPrintf(errlogMajor, "simRegDevAllocMessage %s %s: out of memory\n", user, device->name); if (msg) free(msg); epicsMutexUnlock(device->lock); return S_dev_noMemory; } } else { msg = device->msgFreelist[prio]; device->msgFreelist[prio] = device->msgFreelist[prio]->next; } msg->next = NULL; msg->device = device; msg->dlen = dlen; msg->nelem = nelem; msg->src = src; msg->dest = dest; msg->pmask = pmask; msg->prio = prio; msg->callback = callback; msg->user = user; msg->isOutput = isOutput; epicsMutexUnlock(device->lock); if (simRegDevDebug & (isOutput ? DBG_OUT : DBG_IN)) printf ("simRegDevAsynTransfer %s %s: starting timer %g seconds\n", user, device->name, nelem*0.01); epicsTimerStartDelay(msg->timer, nelem*0.01); return ASYNC_COMPLETION; }
void callbackRequestDelayed(CALLBACK *pcallback, double seconds) { epicsTimerId timer = (epicsTimerId)pcallback->timer; if (timer == 0) { timer = epicsTimerQueueCreateTimer(timerQueue, notify, pcallback); pcallback->timer = timer; } epicsTimerStartDelay(timer, seconds); }
static epicsTimerId wdogCreate(void (*fn)(int), long arg) { static epicsThreadOnceId inited = EPICS_THREAD_ONCE_INIT; /* lazy init of timer queue */ if ( EPICS_THREAD_ONCE_INIT == inited ) epicsThreadOnce( &inited, timerQCreate, 0); return epicsTimerQueueCreateTimer(timerQ, (void (*)(void*))fn, (void*)arg); }
/* * Configure and register a generic serial device */ epicsShareFunc int drvAsynSerialPortConfigure(char *portName, char *ttyName, unsigned int priority, int noAutoConnect, int noProcessEos) { ttyController_t *tty; asynStatus status; /* * Check arguments */ if (portName == NULL) { printf("Port name missing.\n"); return -1; } if (ttyName == NULL) { printf("TTY name missing.\n"); return -1; } if(!pserialBase) serialBaseInit(); /* * Create a driver */ tty = (ttyController_t *)callocMustSucceed(1, sizeof(*tty), "drvAsynSerialPortConfigure()"); /* * Create timeout mechanism */ tty->timer = epicsTimerQueueCreateTimer( pserialBase->timerQueue, timeoutHandler, tty); if(!tty->timer) { printf("drvAsynSerialPortConfigure: Can't create timer.\n"); return -1; } tty->fd = -1; tty->serialDeviceName = epicsStrDup(ttyName); tty->portName = epicsStrDup(portName); /* * Set defaults */ tty->termios.c_cflag = CS8 | CLOCAL | CREAD; tty->baud = 9600; #ifndef vxWorks tty->termios.c_iflag = IGNBRK | IGNPAR; tty->termios.c_oflag = 0; tty->termios.c_lflag = 0; tty->termios.c_cc[VMIN] = 0; tty->termios.c_cc[VTIME] = 0; tty->termios.c_cc[VSTOP] = 0x13; /* ^S */ tty->termios.c_cc[VSTART] = 0x11; /* ^Q */ cfsetispeed(&tty->termios, B9600); cfsetospeed(&tty->termios, B9600); #endif /* * Link with higher level routines */ tty->common.interfaceType = asynCommonType; tty->common.pinterface = (void *)&asynCommonMethods; tty->common.drvPvt = tty; tty->option.interfaceType = asynOptionType; tty->option.pinterface = (void *)&asynOptionMethods; tty->option.drvPvt = tty; if (pasynManager->registerPort(tty->portName, ASYN_CANBLOCK, !noAutoConnect, priority, 0) != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register myself.\n"); ttyCleanup(tty); return -1; } status = pasynManager->registerInterface(tty->portName,&tty->common); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register common.\n"); ttyCleanup(tty); return -1; } status = pasynManager->registerInterface(tty->portName,&tty->option); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register option.\n"); ttyCleanup(tty); return -1; } tty->octet.interfaceType = asynOctetType; tty->octet.pinterface = &asynOctetMethods; tty->octet.drvPvt = tty; status = pasynOctetBase->initialize(tty->portName,&tty->octet, (noProcessEos ? 0 : 1),(noProcessEos ? 0 : 1),1); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register octet.\n"); ttyCleanup(tty); return -1; } tty->pasynUser = pasynManager->createAsynUser(0,0); status = pasynManager->connectDevice(tty->pasynUser,tty->portName,-1); if(status != asynSuccess) { printf("connectDevice failed %s\n",tty->pasynUser->errorMessage); ttyCleanup(tty); return -1; } return 0; }
/* * Configure and register a generic serial device */ epicsShareFunc int drvAsynSerialPortConfigure(char *portName, char *ttyName, unsigned int priority, int noAutoConnect, int noProcessEos) { ttyController_t *tty; asynStatus status; /* * Check arguments */ if (portName == NULL) { printf("Port name missing.\n"); return -1; } if (ttyName == NULL) { printf("TTY name missing.\n"); return -1; } if(!pserialBase) serialBaseInit(); /* * Create a driver */ tty = (ttyController_t *)callocMustSucceed(1, sizeof(*tty), "drvAsynSerialPortConfigure()"); /* * Create timeout mechanism */ tty->timer = epicsTimerQueueCreateTimer( pserialBase->timerQueue, timeoutHandler, tty); if(!tty->timer) { printf("drvAsynSerialPortConfigure: Can't create timer.\n"); return -1; } tty->commHandle = INVALID_HANDLE_VALUE; tty->serialDeviceName = epicsStrDup(ttyName); tty->portName = epicsStrDup(portName); /* * Link with higher level routines */ tty->common.interfaceType = asynCommonType; tty->common.pinterface = (void *)&asynCommonMethods; tty->common.drvPvt = tty; tty->option.interfaceType = asynOptionType; tty->option.pinterface = (void *)&asynOptionMethods; tty->option.drvPvt = tty; if (pasynManager->registerPort(tty->portName, ASYN_CANBLOCK, !noAutoConnect, priority, 0) != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register myself.\n"); ttyCleanup(tty); return -1; } status = pasynManager->registerInterface(tty->portName,&tty->common); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register common.\n"); ttyCleanup(tty); return -1; } status = pasynManager->registerInterface(tty->portName,&tty->option); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register option.\n"); ttyCleanup(tty); return -1; } tty->octet.interfaceType = asynOctetType; tty->octet.pinterface = &asynOctetMethods; tty->octet.drvPvt = tty; status = pasynOctetBase->initialize(tty->portName,&tty->octet, (noProcessEos ? 0 : 1),(noProcessEos ? 0 : 1),1); if(status != asynSuccess) { printf("drvAsynSerialPortConfigure: Can't register octet.\n"); ttyCleanup(tty); return -1; } tty->pasynUser = pasynManager->createAsynUser(0,0); status = pasynManager->connectDevice(tty->pasynUser,tty->portName,-1); if(status != asynSuccess) { printf("connectDevice failed %s\n",tty->pasynUser->errorMessage); ttyCleanup(tty); return -1; } return 0; }
/** Constructor for mar345 driver; most parameters are simply passed to ADDriver::ADDriver. * After calling the base class constructor this method creates a thread to collect the detector data, * and sets reasonable default values for the parameters defined in this class and ADDriver. * \param[in] portName The name of the asyn port driver to be created. * \param[in] serverPort The name of the asyn port driver previously created with drvAsynIPPortConfigure * connected to the mar345dtb program. * \param[in] maxBuffers The maximum number of NDArray buffers that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited number of buffers. * \param[in] maxMemory The maximum amount of memory that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited amount of memory. * \param[in] priority The thread priority for the asyn port driver thread. * \param[in] stackSize The stack size for the asyn port driver thread. */ mar345::mar345(const char *portName, const char *serverPort, int maxBuffers, size_t maxMemory, int priority, int stackSize) : ADDriver(portName, 1, NUM_MAR345_PARAMS, maxBuffers, maxMemory, 0, 0, /* No interfaces beyond those set in ADDriver.cpp */ ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=1, ASYN_MULTIDEVICE=0, autoConnect=1 */ priority, stackSize), pData(NULL) { int status = asynSuccess; epicsTimerQueueId timerQ; const char *functionName = "mar345"; size_t dims[2]; createParam(mar345EraseString, asynParamInt32, &mar345Erase); createParam(mar345EraseModeString, asynParamInt32, &mar345EraseMode); createParam(mar345NumEraseString, asynParamInt32, &mar345NumErase); createParam(mar345NumErasedString, asynParamInt32, &mar345NumErased); createParam(mar345ChangeModeString,asynParamInt32, &mar345ChangeMode); createParam(mar345SizeString, asynParamInt32, &mar345Size); createParam(mar345ResString, asynParamInt32, &mar345Res); createParam(mar345AbortString, asynParamInt32, &mar345Abort); this->mode = mar345ModeIdle; /* Create the epicsEvents for signaling to the mar345 task when acquisition starts and stops */ this->startEventId = epicsEventCreate(epicsEventEmpty); if (!this->startEventId) { printf("%s:%s epicsEventCreate failure for start event\n", driverName, functionName); return; } this->stopEventId = epicsEventCreate(epicsEventEmpty); if (!this->stopEventId) { printf("%s:%s epicsEventCreate failure for stop event\n", driverName, functionName); return; } this->abortEventId = epicsEventCreate(epicsEventEmpty); if (!this->abortEventId) { printf("%s:%s epicsEventCreate failure for abort event\n", driverName, functionName); return; } /* Create the epicsTimerQueue for exposure time handling */ timerQ = epicsTimerQueueAllocate(1, epicsThreadPriorityScanHigh); this->timerId = epicsTimerQueueCreateTimer(timerQ, timerCallbackC, this); /* Connect to server */ status = pasynOctetSyncIO->connect(serverPort, 0, &this->pasynUserServer, NULL); dims[0] = 3450; dims[1] = 3450; /* Allocate the raw buffer we use to files. Only do this once */ setIntegerParam(ADMaxSizeX, (int)dims[0]); setIntegerParam(ADMaxSizeY, (int)dims[1]); this->pData = this->pNDArrayPool->alloc(2, dims, NDInt16, 0, NULL); /* Set some default values for parameters */ status = setStringParam (ADManufacturer, "MAR"); status |= setStringParam (ADModel, "345"); status |= setIntegerParam(NDDataType, NDInt16); status |= setIntegerParam(ADImageMode, ADImageSingle); status |= setIntegerParam(ADTriggerMode, TMInternal); status |= setDoubleParam (ADAcquireTime, 1.); status |= setDoubleParam (ADAcquirePeriod, 0.); status |= setIntegerParam(ADNumImages, 1); status |= setIntegerParam(mar345EraseMode, mar345EraseAfter); status |= setIntegerParam(mar345Size, mar345Size345); status |= setIntegerParam(mar345Res, mar345Res100); status |= setIntegerParam(mar345NumErase, 1); status |= setIntegerParam(mar345NumErased , 0); status |= setIntegerParam(mar345Erase, 0); status |= setIntegerParam(mar345Res, mar345Res100); if (status) { printf("%s: unable to set camera parameters\n", functionName); return; } /* Create the thread that collects the data */ status = (epicsThreadCreate("mar345Task", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)mar345TaskC, this) == NULL); if (status) { printf("%s:%s epicsThreadCreate failure for data collection task\n", driverName, functionName); return; } }
/** Constructor for BIS driver; most parameters are simply passed to ADDriver::ADDriver. * After calling the base class constructor this method creates a thread to collect the detector data, * and sets reasonable default values for the parameters defined in this class, asynNDArrayDriver, and ADDriver. * \param[in] portName The name of the asyn port driver to be created. * \param[in] commandPort The name of the asyn port previously created with drvAsynIPPortConfigure to * send commands to BIS. * \param[in] statusPort The name of the asyn port previously created with drvAsynIPPortConfigure to * receive status information from BIS. * \param[in] maxBuffers The maximum number of NDArray buffers that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited number of buffers. * \param[in] maxMemory The maximum amount of memory that the NDArrayPool for this driver is * allowed to allocate. Set this to -1 to allow an unlimited amount of memory. * \param[in] priority The thread priority for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags. * \param[in] stackSize The stack size for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags. */ BISDetector::BISDetector(const char *portName, const char *commandPort, const char *statusPort, int maxBuffers, size_t maxMemory, int priority, int stackSize) : ADDriver(portName, 1, NUM_BIS_PARAMS, maxBuffers, maxMemory, 0, 0, /* No interfaces beyond those set in ADDriver.cpp */ ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=1, ASYN_MULTIDEVICE=0, autoConnect=1 */ priority, stackSize) { int status = asynSuccess; epicsTimerQueueId timerQ; const char *functionName = "BISDetector"; createParam(BISSFRMTimeoutString, asynParamFloat64, &BISSFRMTimeout); createParam(BISNumDarksString, asynParamInt32, &BISNumDarks); createParam(BISStatusString, asynParamOctet, &BISStatus); /* Create the epicsEvents for signaling to the BIS task when acquisition starts and stops */ this->startEventId = epicsEventMustCreate(epicsEventEmpty); this->stopEventId = epicsEventMustCreate(epicsEventEmpty); this->readoutEventId = epicsEventMustCreate(epicsEventEmpty); /* Create the epicsTimerQueue for exposure time handling */ timerQ = epicsTimerQueueAllocate(1, epicsThreadPriorityScanHigh); this->timerId = epicsTimerQueueCreateTimer(timerQ, timerCallbackC, this); /* Connect to BIS */ status = pasynOctetSyncIO->connect(commandPort, 0, &this->pasynUserCommand, NULL); status = pasynOctetSyncIO->connect(statusPort, 0, &this->pasynUserStatus, NULL); /* Set some default values for parameters */ status = setStringParam (ADManufacturer, "Bruker"); status |= setStringParam (ADModel, "BIS"); status |= setIntegerParam(ADMaxSizeX, 4096); status |= setIntegerParam(ADMaxSizeY, 4096); status |= setIntegerParam(ADSizeX, 0); status |= setIntegerParam(ADSizeY, 0); status |= setIntegerParam(NDArraySizeX, 0); status |= setIntegerParam(NDArraySizeY, 0); status |= setIntegerParam(NDArraySize, 0); status |= setIntegerParam(NDDataType, NDUInt32); status |= setIntegerParam(ADImageMode, ADImageContinuous); if (status) { printf("%s: unable to set camera parameters\n", functionName); return; } /* Create the thread that updates the images */ status = (epicsThreadCreate("BISDetTask", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)BISTaskC, this) == NULL); if (status) { printf("%s:%s epicsThreadCreate failure for image task\n", driverName, functionName); return; } /* Create the thread that reads the status socket */ status = (epicsThreadCreate("BISStatusTask", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)statusTaskC, this) == NULL); if (status) { printf("%s:%s epicsThreadCreate failure for status task\n", driverName, functionName); return; } }