예제 #1
0
int simRegDevSetStatus(
    const char* name,
    int connected)
{
    regDevice* device;

    if (!name)
    {
        printf ("usage: simRegDevSetStatus name, 0|1\n");
        return S_dev_badArgument;
    }
    device = regDevFind(name);
    if (!device)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetStatus: %s not found\n",
            name);
        return S_dev_noDevice;
    }
    if (device->magic != MAGIC)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetStatus: %s is not a simRegDev\n",
            name);
        return S_dev_wrongDevice;
    }
    device->connected = connected;
    if (simRegDevDebug >= 1)
        printf ("simRegDevSetStatus %s: trigger input records\n", device->name);
    scanIoRequest(device->ioscanpvt);
    return S_dev_success;
}
예제 #2
0
/*
 * Return whether the last get completed. In safe mode, as a
 * side effect, copy value from shared buffer to state set local buffer.
 */
epicsShareFunc boolean epicsShareAPI seq_pvGetComplete(SS_ID ss, VAR_ID varId)
{
	epicsEventId	getSem = ss->getSemId[varId];
	SPROG		*sp = ss->sprog;
	CHAN		*ch = sp->chan + varId;
	pvStat		status;

	if (!ch->dbch)
	{
		/* Anonymous PVs always complete immediately */
		if (!(sp->options & OPT_SAFE))
			errlogSevPrintf(errlogMajor,
				"pvGetComplete(%s): user error (variable not assigned)\n",
				ch->varName);
		return TRUE;
	}

	if (!ss->getReq[varId])
	{
		errlogSevPrintf(errlogMinor,
			"pvGetComplete(%s): no pending get request for this variable\n",
			ch->varName);
		return TRUE;
	}

	switch (epicsEventTryWait(getSem))
	{
	case epicsEventWaitOK:
		ss->getReq[varId] = NULL;
		epicsEventSignal(getSem);
		status = check_connected(ch->dbch, metaPtr(ch,ss));
		/* TODO: returning either TRUE or FALSE here seems wrong. We return TRUE,
		   so that state sets don't hang. Still means that user code has to check
		   status by calling pvStatus and/or pvMessage. */
		if (status) return TRUE;
		/* In safe mode, copy value and meta data from shared buffer
		   to ss local buffer. */
		if (sp->options & OPT_SAFE)
			/* Copy regardless of whether dirty flag is set or not */
			ss_read_buffer(ss, ch, FALSE);
		return TRUE;
	case epicsEventWaitTimeout:
		return FALSE;
	case epicsEventWaitError:
		ss->getReq[varId] = NULL;
		epicsEventSignal(getSem);
		errlogSevPrintf(errlogFatal, "pvGetComplete: "
		  "epicsEventTryWait(getSemId[%d]) failure\n", varId);
	default: /* pacify gcc which does not understand the we checked all possibilities */
		return FALSE;
	}
}
예제 #3
0
int simRegDevRead(
    regDevice *device,
    size_t offset,
    unsigned int dlen,
    size_t nelem,
    void* pdata,
    int prio,
    regDevTransferComplete callback,
    const char* user)
{
    if (!device || device->magic != MAGIC)
    {
        errlogSevPrintf(errlogMajor,
            "simRegDevRead %s: illegal device handle\n", user);
        return S_dev_wrongDevice;
    }
    if (device->connected == 0)
    {
        return S_dev_noDevice;
    }
    if (simRegDevDebug & DBG_IN)
        printf ("simRegDevRead %s %s:%"Z"u: %u bytes * %"Z"u elements, prio=%d\n",
        user, device->name, offset, dlen, nelem, prio);

    if (nelem > 1 && device->lock)
        return simRegDevAsynTransfer(device, dlen, nelem,
            device->buffer+offset, pdata, NULL, prio, callback, user, FALSE);

    regDevCopy(dlen, nelem, device->buffer+offset, pdata, NULL, device->swap);
    return S_dev_success;
}
예제 #4
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Get value from a queued PV.
 */
epicsShareFunc boolean seq_pvGetQ(SS_ID ss, CH_ID chId)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;
	void	*var = valPtr(ch,ss);
	EF_ID	ev_flag = ch->syncedTo;
	PVMETA	*meta = metaPtr(ch,ss);
	boolean	was_empty;
	struct getq_cp_arg arg = {ch, var, meta};

	if (!ch->queue)
	{
		errlogSevPrintf(errlogMajor,
			"pvGetQ(%s): user error (not queued)\n",
			ch->varName
		);
		return FALSE;
	}

	was_empty = seqQueueGetF(ch->queue, getq_cp, &arg);

	if (ev_flag)
	{
		epicsMutexMustLock(sp->lock);
		/* If queue is now empty, clear the event flag */
		if (seqQueueIsEmpty(ch->queue))
		{
			bitClear(sp->evFlags, ev_flag);
		}
		epicsMutexUnlock(sp->lock);
	}

	return (!was_empty);
}
예제 #5
0
파일: seq_if.c 프로젝트: ukaea/epics
static pvStat wait_complete(
	pvEventType evtype,
	SS_ID ss,
	PVREQ **req,
	DBCHAN *dbch,
	PVMETA *meta,
	double tmo)
{
	const char *call = evtype == pvEventGet ? "pvGet" : "pvPut";
	while (*req)
	{
		switch (epicsEventWaitWithTimeout(ss->syncSem, tmo))
		{
		case epicsEventWaitOK:
			break;
		case epicsEventWaitTimeout:
			*req = NULL;			/* cancel the request */
			completion_timeout(evtype, meta);
			return meta->status;
		case epicsEventWaitError:
			errlogSevPrintf(errlogFatal,
				"%s: epicsEventWaitWithTimeout() failure\n", call);
			*req = NULL;			/* cancel the request */
			completion_failure(evtype, meta);
			return meta->status;
		}
	}
	return check_connected(dbch, meta);
}
예제 #6
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Return whether the last get completed. In safe mode, as a
 * side effect, copy value from shared buffer to state set local buffer.
 */
epicsShareFunc boolean seq_pvGetComplete(
	SS_ID	ss,
	CH_ID	chId)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;

	if (!ch->dbch)
	{
		/* Anonymous PVs always complete immediately */
		if (!optTest(sp, OPT_SAFE))
			errlogSevPrintf(errlogMajor,
				"pvGetComplete(%s): user error (not assigned to a PV)\n",
				ch->varName);
		return TRUE;
	}
	else if (!ss->getReq[chId])
	{
		pvStat status = check_connected(ch->dbch, metaPtr(ch,ss));
		if (status == pvStatOK && optTest(sp, OPT_SAFE))
		{
			/* In safe mode, copy value and meta data from shared buffer
			   to ss local buffer. */
			/* Copy regardless of whether dirty flag is set or not */
			ss_read_buffer(ss, ch, FALSE);
		}
		return TRUE;
	}
	return FALSE;
}
예제 #7
0
파일: seq_if.c 프로젝트: ukaea/epics
static pvStat seq_pvSingleMonitor(SS_ID ss, CH_ID chId, boolean turn_on, const char *what)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;
	DBCHAN	*dbch = ch->dbch;
	pvStat	status;

	if (!dbch)
	{
		if (optTest(sp, OPT_SAFE))
		{
			ch->monitored = TRUE;
			return pvStatOK;
		}
		else
		{
			errlogSevPrintf(errlogMajor,
				"%s(%s): user error (not assigned to a PV)\n",
				what, ch->varName
			);
			return pvStatERROR;
		}
	}
	ch->monitored = turn_on;
	status = seq_camonitor(ch, turn_on);
	if (status != pvStatOK)
	{
		pv_call_failure(dbch, metaPtr(ch,ss), status);
	}
	return status;
}
예제 #8
0
void seqCreatePvSys(SPROG *sp)
{
	int debug = sp->debug;
	pvStat status = pvSysCreate(sp->pvSysName,
		max(0, debug-1), &sp->pvSys);
	if (status != pvStatOK)
		errlogSevPrintf(errlogFatal, "pvSysCreate(\"%s\") failure\n", sp->pvSysName);
}
예제 #9
0
void mk3Driver::checkErrorCode(int code)
{
    // 0 = no error
    if (code != 0)
    {
        char answer[50];
        m_interface->checkErrorCode(code, answer, 50);
        errlogSevPrintf(errlogMajor, "%s", answer);
        
        // If .net timeout try to re-intialise
        if (code == -3)
        {
            errlogSevPrintf(errlogMajor, "%s","Trying to re-establish .NET connection");
            m_interface->initialise();
        }
    }
}
예제 #10
0
int simRegDevWrite(
    regDevice *device,
    size_t offset,
    unsigned int dlen,
    size_t nelem,
    void* pdata,
    void* pmask,
    int prio,
    regDevTransferComplete callback,
    const char* user)
{
    if (!device || device->magic != MAGIC)
    {
        errlogSevPrintf(errlogMajor,
            "simRegDevWrite: illegal device handle\n");
        return S_dev_wrongDevice;
    }
    if (device->connected == 0)
    {
        return S_dev_noDevice;
    }
    if (simRegDevDebug & DBG_OUT)
    {
        size_t n;
        printf ("simRegDevWrite %s %s:%"Z"u: %u bytes * %"Z"u elements, prio=%d\n",
        user, device->name, offset, dlen, nelem, prio);
        for (n=0; n<nelem && n<10; n++)
        {
            switch (dlen)
            {
                case 1:
                    printf (" %02x",((epicsUInt8*)pdata)[n*dlen]);
                    break;
                case 2:
                    printf (" %04x",((epicsUInt16*)pdata)[n*dlen]);
                    break;
                case 4:
                    printf (" %08x",((epicsUInt32*)pdata)[n*dlen]);
                    break;
                case 8:
                    printf (" %08llx",((unsigned long long*)pdata)[n*dlen]);
                    break;
            }
        }
        printf ("\n");
    }

    if (nelem > 1 && device->lock)
        return simRegDevAsynTransfer(device, dlen, nelem, pdata,
            device->buffer+offset, pmask, prio, callback, user, TRUE);

    regDevCopy(dlen, nelem, pdata, device->buffer+offset, pmask, device->swap);
    /* We got new data: trigger all interested input records */
    if (simRegDevDebug & DBG_OUT)
        printf ("simRegDevWrite %s: trigger input records\n", device->name);
    scanIoRequest(device->ioscanpvt);
    return S_dev_success;
}
예제 #11
0
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;
}
예제 #12
0
int caPutLogAsInit()
{
    if (!asActive) {
        errlogSevPrintf(errlogFatal, "caPutLog: access security is disabled\n");
        return caPutLogError;
    }

    /* Initialize the free list of log elements */
    if (!logDataFreeList) {
        freeListInitPvt(&logDataFreeList, sizeof(LOGDATA), FREE_LIST_SIZE);
    }

    /* Initialize the Trap Write Listener */
    listenerId = asTrapWriteRegisterListener(caPutLogAs);
    if (!listenerId) {
        errlogSevPrintf(errlogFatal, "caPutLog: asTrapWriteRegisterListener failed\n");
        return caPutLogError;
    }
    return caPutLogSuccess;
}
예제 #13
0
int simRegDevSetData(
    const char* name,
    size_t offset,
    int value)
{
    regDevice* device;

    if (!name)
    {
        printf ("usage: simRegDevSetData name, offset, value\n");
        return S_dev_badArgument;
    }
    device = regDevFind(name);
    if (!device)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetData: %s not found\n",
            name);
        return S_dev_noDevice;
    }
    if (device->magic != MAGIC)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetData: %s is not a simRegDev\n",
            name);
        return S_dev_wrongDevice;
    }
    if (offset > device->size)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetData: %s offset %"Z"d out of range (0-%"Z"d)\n",
            name, offset, device->size);
        return S_dev_badSignalNumber;
    }
    
    device->buffer[offset] = value;
    if (simRegDevDebug >= 1)
        printf ("simRegDevSetData %s: trigger input records\n", device->name);
    scanIoRequest(device->ioscanpvt);
    return S_dev_success;
}
/// EPICS iocsh callable function to call constructor of lvDCOMInterface().
/// \param[in] portName @copydoc initArg0
/// \param[in] configSection @copydoc initArg1
/// \param[in] configFile @copydoc initArg2
/// \param[in] host @copydoc initArg3
/// \param[in] options @copydoc initArg4
/// \param[in] progid @copydoc initArg5
/// \param[in] username @copydoc initArg6
/// \param[in] password @copydoc initArg7
int isisdaeConfigure(const char *portName, int options, const char *host, const char* username, const char* password)
{
	try
	{
		isisdaeInterface* iface = new isisdaeInterface(host, options, username, password);
		if (iface != NULL)
		{
			isisdaeDriver* driver = new isisdaeDriver(iface, portName);
			if (driver != NULL)
			{
				if (epicsThreadCreate("daeCAS",
                          epicsThreadPriorityMedium,
                          epicsThreadGetStackSize(epicsThreadStackMedium),
                          (EPICSTHREADFUNC)daeCASThread, iface) == 0)
				{
					printf("epicsThreadCreate failure\n");
					return(asynError);
				}
			}
			else
			{
			    errlogSevPrintf(errlogMajor, "isisdaeConfigure failed (NULL)\n");
				return(asynError);
			}
			return(asynSuccess);
		}
		else
		{
			errlogSevPrintf(errlogMajor, "isisdaeConfigure failed (NULL)\n");
			return(asynError);
		}
			
	}
	catch(const std::exception& ex)
	{
		errlogSevPrintf(errlogMajor, "isisdaeConfigure failed: %s\n", ex.what());
		return(asynError);
	}
}
void isisdaeDriver::reportErrors(const char* exc_text)
{
		std::string msgs = m_iface->getAllMessages();
        setStringParam(P_AllMsgs, msgs.c_str());
        setStringParam(P_ErrMsgs, exc_text);
		std::string mess_ts;
		isisdaeInterface::stripTimeStamp(exc_text, mess_ts);
//		std::cerr << mess_ts << std::endl;		  
		errlogSevPrintf(errlogMajor, "%s", mess_ts.c_str());
// getAsynMessages will pick these up and report to screen
//		errlogSevPrintf(errlogInfo, "%s", msgs.c_str());
		m_iface->resetMessages();
}
예제 #16
0
int simRegDevGetData(
    const char* name,
    size_t offset,
    int *value)
{
    regDevice* device;

    if (!name)
    {
        printf ("usage: simRegDevGetData name, offset, &value\n");
        return S_dev_badArgument;
    }
    device = regDevFind(name);
    if (!device)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevGetData: %s not found\n",
            name);
        return S_dev_noDevice;
    }
    if (device->magic != MAGIC)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevGetData: %s is not a simRegDev\n",
            name);
        return S_dev_wrongDevice;
    }
    if (offset > device->size)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevGetData: %s offset %"Z"d out of range (0-%"Z"d)\n",
            name, offset, device->size);
        return S_dev_badSignalNumber;
    }
    
    *value = device->buffer[offset];
    return S_dev_success;
}
예제 #17
0
IOSCANPVT simRegDevGetInScanPvt(
    regDevice *device,
    size_t offset,
    int ivec,
    const char* name)
{
    if (!device || device->magic != MAGIC)
    {
        errlogSevPrintf(errlogMajor,
            "simRegDevGetInScanPvt %s: illegal device handle\n", name);
        return NULL;
    }
    return device->ioscanpvt;
}
	/// EPICS iocsh callable function to call constructor of NetShrVarInterface().
	/// The function is registered via NetShrVarRegister().
	///
	/// @param[in] portName @copydoc initArg0
	/// @param[in] configSection @copydoc initArg1
	/// @param[in] configFile @copydoc initArg2
	/// @param[in] pollPeriod @copydoc initArg3
	/// @param[in] options @copydoc initArg4
	int NetShrVarConfigure(const char *portName, const char* configSection, const char *configFile, int pollPeriod, int options)
	{
		try
		{
			NetShrVarInterface* netvarint = new NetShrVarInterface(configSection, configFile, options);
			if (netvarint != NULL)
			{
				new NetShrVarDriver(netvarint, pollPeriod, portName);
				return(asynSuccess);
			}
			else
			{
				errlogSevPrintf(errlogFatal, "NetShrVarConfigure failed (NULL)\n");
				return(asynError);
			}

		}
		catch(const std::exception& ex)
		{
			errlogSevPrintf(errlogFatal, "NetShrVarConfigure failed: %s\n", ex.what());
			return(asynError);
		}
	}
void NetShrVarInterface::createParams(asynPortDriver* driver)
{
    static const char* functionName = "createParams";
    m_driver = driver;
	getParams();
	for(params_t::iterator it=m_params.begin(); it != m_params.end(); ++it)
	{
		NvItem* item = it->second;
		if (item->type == "float64")
		{
			m_driver->createParam(it->first.c_str(), asynParamFloat64, &(item->id));
		}
		else if (item->type == "int32" || item->type == "boolean")
		{
			m_driver->createParam(it->first.c_str(), asynParamInt32, &(item->id));
		}
		else if (item->type == "string")
		{
			m_driver->createParam(it->first.c_str(), asynParamOctet, &(item->id));
		}
		else if (item->type == "float64array")
		{
			m_driver->createParam(it->first.c_str(), asynParamFloat64Array, &(item->id));
		}
		else if (item->type == "float32array")
		{
			m_driver->createParam(it->first.c_str(), asynParamFloat32Array, &(item->id));
		}
		else if (item->type == "int32array")
		{
			m_driver->createParam(it->first.c_str(), asynParamInt32Array, &(item->id));
		}
		else if (item->type == "int16array")
		{
			m_driver->createParam(it->first.c_str(), asynParamInt16Array, &(item->id));
		}
		else if (item->type == "int8array")
		{
			m_driver->createParam(it->first.c_str(), asynParamInt8Array, &(item->id));
		}
		else
		{
			errlogSevPrintf(errlogMajor, "%s:%s: unknown type %s for parameter %s\n", driverName, 
			                functionName, item->type.c_str(), it->first.c_str());
		}
	}
	connectVars();
}
예제 #20
0
static long initRecord (dbCommon *record)
{
    static const int typesize[] = {MAX_STRING_SIZE,1,1,2,2,4,4,4,8,2};
    aaoRecord *aao = (aaoRecord *) record;

    aao->bptr = calloc(aao->nelm, typesize[aao->ftvl]);
    if (aao->bptr == NULL)
    {
        errlogSevPrintf (errlogFatal,
            "initRecord %s: can't allocate memory for data array\n",
            record->name);
        return ERROR;
    }
    return streamInitRecord (record, &aao->out, readData, writeData) == ERROR ?
        ERROR : OK;
}
예제 #21
0
파일: seq_if.c 프로젝트: ukaea/epics
static void anonymous_put(SS_ID ss, CHAN *ch)
{
	char *var = valPtr(ch,ss);

	if (ch->queue)
	{
		QUEUE queue = ch->queue;
		pvType type = ch->type->getType; /*BUG? should that be putType?*/
		size_t size = ch->type->size;
		boolean full;
		struct putq_cp_arg arg = {ch, var};

		DEBUG("anonymous_put: type=%d, size=%d, count=%d, buf_size=%d, q=%p\n",
			type, size, ch->count, pv_size_n(type, ch->count), queue);
		print_channel_value(DEBUG, ch, var);

		/* Note: Must lock here because multiple state sets can issue
		   pvPut calls concurrently. OTOH, no need to lock against CA
		   callbacks, because anonymous and named PVs are disjoint. */
		epicsMutexMustLock(ch->varLock);

		full = seqQueuePutF(queue, putq_cp, &arg);
		if (full)
		{
			errlogSevPrintf(errlogMinor,
			  "pvPut on queued channel '%s' (anonymous): "
			  "last queue element overwritten (queue is full)\n",
			  ch->varName
			);
		}

		epicsMutexUnlock(ch->varLock);
	}
	else
	{
		/* Set dirty flag only if monitored */
		ss_write_buffer(ch, var, 0, ch->monitored);
	}
	/* If there's an event flag associated with this channel, set it */
	if (ch->syncedTo)
		seq_efSet(ss, ch->syncedTo);
	/* Wake up each state set that uses this channel in an event */
	ss_wakeup(ss->prog, ch->eventNum);
}
예제 #22
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Cancel the last asynchronous put request.
 */
epicsShareFunc void seq_pvPutCancel(
	SS_ID	ss,
	CH_ID	chId)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;

	if (!ch->dbch)
	{
		if (!optTest(sp, OPT_SAFE))
			errlogSevPrintf(errlogMinor,
				"pvPutCancel(%s): user error (not assigned to a PV)\n",
				ch->varName);
	}
	else
	{
		ss->putReq[chId] = NULL;	/* cancel the request */
	}
}
예제 #23
0
int simRegDevConfigure(
    const char* name,
    size_t size,
    int swapEndianFlag,
    int async)
{
    regDevice* device;

    if (name == NULL)
    {
        printf("usage: simRegDevConfigure(\"name\", size, swapEndianFlag)\n");
        printf("maps allocated memory block to device \"name\"");
        printf("\"name\" must be a unique string on this IOC\n");
        return S_dev_success;
    }
    device = (regDevice*)calloc(sizeof(regDevice)+size-1,1);
    if (device == NULL)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevConfigure %s: out of memory\n",
            name);
        return errno;
    }
    device->magic = MAGIC;
    device->name = strdup(name);
    device->size = size;
    device->connected = 1;
    device->swap = swapEndianFlag;
    if (async)
    {
        int i;
        device->lock = epicsMutexCreate();
        for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++)
        {
            const unsigned int prio [3] =
                {epicsThreadPriorityLow, epicsThreadPriorityMedium, epicsThreadPriorityHigh};
            device->queue[i] = epicsTimerQueueAllocate(FALSE, prio[i]);
        }
    }
    regDevRegisterDevice(name, &simRegDevSupport, device, size);
    scanIoInit(&device->ioscanpvt);
    return S_dev_success;
}
static void daeCASThread(void* arg)
{
    exServer    *pCAS;
    unsigned    debugLevel = 0u;
    double      executionTime = 0.0;
    double      asyncDelay = 0.1;
    const char*        pvPrefix;
    unsigned    aliasCount = 1u;
    unsigned    scanOn = true;
    unsigned    syncScan = true;
    unsigned    maxSimultAsyncIO = 1000u;
	isisdaeInterface* iface = static_cast<isisdaeInterface*>(arg);
    printf("starting cas server\n");
	pvPrefix = macEnvExpand("$(MYPVPREFIX)DAE:");
    try {
        pCAS = new exServer ( pvPrefix, aliasCount, 
            scanOn != 0, syncScan == 0, asyncDelay,
            maxSimultAsyncIO, iface );
    }
    catch ( ... ) {
        errlogSevPrintf (errlogMajor, "Server initialization error\n" );
        errlogFlush ();
        return;
    }
    
    pCAS->setDebugLevel(debugLevel);
    try
    {
        while (true) 
        {
            fileDescriptorManager.process(1000.0);
        }
    }
    catch(const std::exception& ex)
    {
        std::cerr << ex.what() << std::endl;
    }
    //pCAS->show(2u);
    delete pCAS;
    errlogFlush ();
}
예제 #25
0
/*
 * Cancel a monitor.
 */
epicsShareFunc pvStat epicsShareAPI seq_pvStopMonitor(SS_ID ss, VAR_ID varId)
{
	SPROG	*sp = ss->sprog;
	CHAN	*ch = sp->chan + varId;
	DBCHAN	*dbch = ch->dbch;

	if (!dbch && (sp->options & OPT_SAFE))
	{
		ch->monitored = FALSE;
		return pvStatOK;
	}
	if (!dbch)
	{
		errlogSevPrintf(errlogMajor,
			"pvStopMonitor(%s): user error (variable not assigned)\n",
			ch->varName
		);
		return pvStatERROR;
	}
	ch->monitored = FALSE;
	return seq_monitor(ch, FALSE);
}
예제 #26
0
epicsShareFunc QUEUE seqQueueCreate(size_t numElems, size_t elemSize)
{
    QUEUE q = new(struct seqQueue);

    if (!q) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: out of memory\n");
        return 0;
    }
    /* check arguments to establish invariants */
    if (numElems == 0) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: numElems must be positive\n");
        free(q);
        return 0;
    }
    if (elemSize == 0) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: elemSize must be positive\n");
        free(q);
        return 0;
    }
    if (numElems > seqQueueMaxNumElems) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: numElems too large\n");
        free(q);
        return 0;
    }
    DEBUG("%s:%d:calloc(%u,%u)\n",__FILE__,__LINE__,numElems, elemSize);
    q->buffer = (char *)calloc(numElems, elemSize);
    if (!q->buffer) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: out of memory\n");
        free(q);
        return 0;
    }
    q->mutex = epicsMutexCreate();
    if (!q->mutex) {
        errlogSevPrintf(errlogFatal, "seqQueueCreate: out of memory\n");
        free(q->buffer);
        free(q);
        return 0;
    }
    q->elemSize = elemSize;
    q->numElems = numElems;
    q->overflow = FALSE;
    q->rd = q->wr = 0;
    return q;
}
예제 #27
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Return whether the last put completed.
 */
static boolean seq_pvSinglePutComplete(
	SS_ID	ss,
	CH_ID	chId)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;

	if (!ch->dbch)
	{
		/* Anonymous PVs always complete immediately */
		if (!(sp->options & OPT_SAFE))
			errlogSevPrintf(errlogMajor,
				"pvPutComplete(%s): user error (not assigned to a PV)\n",
				ch->varName);
		return TRUE;
	}
	else if (!ss->putReq[chId])
	{
		check_connected(ch->dbch, metaPtr(ch,ss));
		return TRUE;
	}

	return FALSE;
}
예제 #28
0
파일: seq_if.c 프로젝트: ukaea/epics
static pvStat check_pending(
	pvEventType evtype,
	SS_ID ss,
	PVREQ **req,
	const char *varName,
	DBCHAN *dbch,
	PVMETA *meta,
	enum compType compType,
	double tmo)
{
	const char *call = evtype == pvEventGet ? "pvGet" : "pvPut";

	assert(evtype != pvEventMonitor);
	if (compType == SYNC)
	{
		if (tmo <= 0.0)
		{
			errlogSevPrintf(errlogMajor,
				"%s(%s,SYNC,%f): user error (timeout must be positive)\n",
				call, varName, tmo);
			return pvStatERROR;
		}
		while (*req)
		{
			/* a request is already pending (must be an async request) */
			double before, after;
			pvStat status;

			pvTimeGetCurrentDouble(&before);
			switch (epicsEventWaitWithTimeout(ss->syncSem, tmo))
			{
			case epicsEventWaitOK:
				status = check_connected(dbch, meta);
				if (status != pvStatOK)
					return status;
				pvTimeGetCurrentDouble(&after);
				tmo -= (after - before);
				if (tmo > 0.0)
					break;
				/* else: fall through to timeout */
			case epicsEventWaitTimeout:
				errlogSevPrintf(errlogMajor,
					"%s(ss %s, var %s, pv %s): failed (timeout "
					"waiting for other %s requests to finish)\n",
					call, ss->ssName, varName, dbch->dbName, call
				);
				completion_timeout(evtype, meta);
				return meta->status;
			case epicsEventWaitError:
				errlogSevPrintf(errlogFatal,
					"%s: epicsEventWaitWithTimeout() failure\n", call);
				completion_failure(evtype, meta);
				return meta->status;
			}
		}
	}
	else if (compType == ASYNC)
	{
		if (*req) {
			errlogSevPrintf(errlogMajor,
				"%s(ss %s, var %s, pv %s): user error "
				"(there is already a %s pending for this channel/"
				"state set combination)\n",
				call, ss->ssName, varName, dbch->dbName, call
			);
			return pvStatERROR;
		}
	}
	return pvStatOK;
}
예제 #29
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Assign/Connect to a channel.
 * Assign to a zero-length string ("") disconnects/de-assigns,
 * in safe mode, creates an anonymous PV.
 */
epicsShareFunc pvStat seq_pvAssign(SS_ID ss, CH_ID chId, const char *pvName)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;
	pvStat	status = pvStatOK;
	DBCHAN	*dbch;

	if (!pvName) pvName = "";

	DEBUG("Assign %s to \"%s\"\n", ch->varName, pvName);

	epicsMutexMustLock(sp->lock);

	dbch = ch->dbch;

	if (dbch)	/* was assigned to a named PV */
	{
		ch->dbch = 0;

		epicsMutexUnlock(sp->lock);

		status = pvVarDestroy(&dbch->pvid);

		epicsMutexMustLock(sp->lock);

		sp->assignCount--;

		if (dbch->connected)	/* see connection handler */
		{
			dbch->connected = FALSE;
			sp->connectCount--;

			/* Must not call seq_camonitor(ch, FALSE), it would give an
			error because channel is already dead. pvVarDestroy takes
                        care that the monid inside the pvid gets invalidated. */

			/* Note ch->monitored remains on because it is a configuration
			value that belongs to the variable and newly created channels
			for the same variable should inherit this configuration. */
		}

		if (status != pvStatOK)
		{
			errlogSevPrintf(errlogFatal, "pvAssign(var %s, pv %s): pvVarDestroy() failure: "
				"%s\n", ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
		}

		free(dbch->dbName);
	}

	if (pvName[0] == 0)	/* new name is empty -> free resources */
	{
		if (dbch) {
			free(dbch);
		}
	}
	else		/* new name is non-empty -> create resources */
	{
		if (!dbch)
		{
			dbch = new(DBCHAN);
			if (!dbch)
			{
				errlogSevPrintf(errlogFatal, "pvAssign: calloc failed\n");
				epicsMutexUnlock(sp->lock);
				return pvStatERROR;
			}
		}
		dbch->dbName = epicsStrDup(pvName);
		if (!dbch->dbName)
		{
			errlogSevPrintf(errlogFatal, "pvAssign: epicsStrDup failed\n");
			free(dbch);
			epicsMutexUnlock(sp->lock);
			return pvStatERROR;
		}
		ch->dbch = dbch;

		status = pvVarCreate(
			sp->pvSys,		/* PV system context */
			dbch->dbName,		/* DB channel name */
			seq_conn_handler,	/* connection handler routine */
			seq_event_handler,	/* event handler routine */
			ch,			/* user ptr is CHAN structure */
			&dbch->pvid);		/* ptr to pvid */
		if (status != pvStatOK)
		{
			errlogSevPrintf(errlogFatal, "pvAssign(var %s, pv %s): pvVarCreate() failure: "
				"%s\n", ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
			free(ch->dbch->dbName);
			free(ch->dbch);
		}
		else
		{
			sp->assignCount++;
		}
	}

	epicsMutexUnlock(sp->lock);

	return status;
}
예제 #30
0
파일: seq_if.c 프로젝트: ukaea/epics
/*
 * Put a variable's value to a PV, with timeout.
 */
epicsShareFunc pvStat seq_pvPutTmo(SS_ID ss, CH_ID chId, enum compType compType, double tmo)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;
	pvStat	status;
	unsigned count;
	char	*var = valPtr(ch,ss);	/* ptr to value */
	PVREQ	*req;
	DBCHAN	*dbch = ch->dbch;
	PVMETA	*meta = metaPtr(ch,ss);

	DEBUG("pvPut: pv name=%s, var=%p\n", dbch ? dbch->dbName : "<anonymous>", var);

	/* First handle anonymous PV (safe mode only) */
	if (optTest(sp, OPT_SAFE) && !dbch)
	{
		anonymous_put(ss, ch);
		return pvStatOK;
	}
	if (!dbch)
	{
		errlogSevPrintf(errlogMajor,
			"pvPut(%s): user error (not assigned to a PV)\n",
			ch->varName
		);
		return pvStatERROR;
	}

	/* Check for channel connected */
	status = check_connected(dbch, meta);
	if (status != pvStatOK) return status;

	/* Determine whether to perform synchronous, asynchronous, or
	   plain put ((+a) option was never honored for put, so DEFAULT
	   means fire-and-forget) */
	status = check_pending(pvEventPut, ss, ss->putReq + chId, ch->varName,
		dbch, meta, compType, tmo);
	if (status != pvStatOK)
		return status;

	/* Determine number of elements to put (don't try to put more
	   than db count) */
	count = dbch->dbCount;

	/* Perform the PV put operation (either non-blocking or with a
	   callback routine specified) */
	if (compType == DEFAULT)
	{
		status = pvVarPutNoBlock(
				&dbch->pvid,		/* PV id */
				ch->type->putType,	/* data type */
				count,			/* element count */
				(pvValue *)var);	/* data value */
		if (status != pvStatOK)
		{
			pv_call_failure(dbch, meta, status);
			errlogSevPrintf(errlogFatal, "pvPut(var %s, pv %s): pvVarPutNoBlock() failure: %s\n",
				ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
			return status;
		}
	}
	else
	{
		/* Allocate and initialize a pv request */
		req = (PVREQ *)freeListMalloc(sp->pvReqPool);
		req->ss = ss;
		req->ch = ch;

		assert(ss->putReq[chId] == NULL);
		ss->putReq[chId] = req;

		status = pvVarPutCallback(
				&dbch->pvid,		/* PV id */
				ch->type->putType,	/* data type */
				count,			/* element count */
				(pvValue *)var,		/* data value */
				req);			/* user arg */
		if (status != pvStatOK)
		{
			pv_call_failure(dbch, meta, status);
			errlogSevPrintf(errlogFatal, "pvPut(var %s, pv %s): pvVarPutCallback() failure: %s\n",
				ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
			ss->putReq[chId] = NULL;	/* cancel the request */
			freeListFree(sp->pvReqPool, req);
			check_connected(dbch, meta);
			return status;
		}

		if (compType == SYNC)			/* wait for completion */
		{
			pvSysFlush(sp->pvSys);
			status = wait_complete(pvEventPut, ss, ss->putReq + chId, dbch, meta, tmo);
			if (status != pvStatOK)
				return status;
		}
	}
	return pvStatOK;
}