Esempio n. 1
0
/*
 * start channel access
 */
static int
init_CA_common(int flag)
{
    int stat;
    struct ca_client_context *context;
    stat = ca_context_create(flag?ca_enable_preemptive_callback:ca_disable_preemptive_callback);
    /* ECA_NOTTHREADED indicates that this thread is recognized as
     * part of an existing context, and the application will have to
     * trust the callbacks being made.
     */
    if( stat != ECA_NORMAL && stat != ECA_NOTTHREADED) {
	printf("Can't start channel access (%d)\n", stat);
	return -1;
    }
    if( processFlag == 0)
	    processFlag = epicsMutexCreate();

    context = ca_current_context();
    epicsConnectAddContext( context, flag);
    return 0;
}
Esempio n. 2
0
/*
 * move from 'stop' to 'standby'.
 * return 1 on success, 0 if unable to set up.
 */
int
Standby_mode( acqMaster_t *master)
{
	acqScan_t *sc;
	acqEvent_t *ev;
	char *errMsg;
	int valid = 1;
	int nManualTrigger = 0;

	if( master->GlobalContext == NULL)
	{
		init_CA();
		master->GlobalContext = ca_current_context();
	}
	master->messageAdd(master, "Standby Mode");
	master->putMode( master, AS_STARTUP);
	/*
	 * verify content for all records
	 */
	for( sc = first_acqScan(master); sc ; sc = next_acqScan( sc) )
	{
		if ( ( errMsg = valid_scanRecord_settings(sc) ) != NULL )
		{
			master->messageAdd(master, "Scan %s not valid: %s", sc->scanName, errMsg);
			valid = 0;
		}
		if( sc->useStart)
			nManualTrigger++;
	}

	if( !valid)
	{
		master->putMode( master, AS_OFF);
		return 0;
	}

	if( nManualTrigger == 0)
	{
		master->messageAdd(master, "No Scans set for 'Trigger on Start'");
		return 0;
	}

	for( ev= first_acqEvent(master); ev ; ev = next_acqEvent( ev) )
	{
		if( ( errMsg = valid_eventRecord_settings(ev) ) != NULL )
		{
			master->messageAdd(master, "Event %s not valid: %s", ev->eventName, errMsg);
			valid = 0;
		}
	}

	if( !valid)
	{
		master->putMode(master,  AS_OFF);
		return 0;
	}

	DEBUGM(master,1) printf("Standby mode: building links\n");
	/*
	 * establish all links. on failure, clean up and return
	 */
	for( sc = first_acqScan(master); sc ; sc = next_acqScan(sc) )
	{
		if( build_scanRecord_links(sc) != 1)
		{
			master->messageAdd(master, "Linking for scan '%s' failed", sc->scanName);
			valid = 0;
			break;
		}
	}

	for( ev = first_acqEvent(master); ev ; ev = next_acqEvent(ev) )
	{
		if( build_eventRecord_links( ev) != 1)
		{
			master->messageAdd(master, "Linking for event '%s' failed", ev->eventName);
			valid = 0;
			break;
		}
	}

	if( !valid)
	{
		/* remove the links just created
		 */
		for( sc = first_acqScan(master) ; sc ; sc = next_acqScan(sc) )
			erase_scanRecord_links(sc);
		for( ev = first_acqEvent(master); ev ; ev = next_acqEvent(ev) )
			erase_eventRecord_links(ev);
		master->putMode(master,  AS_OFF);
		return 0;
	}

	master->putMode(master,  AS_STANDBY);
	return 1;
}
Esempio n. 3
0
static void dbCaTask(void *arg)
{
    taskwdInsert(0, NULL, NULL);
    SEVCHK(ca_context_create(ca_enable_preemptive_callback),
        "dbCaTask calling ca_context_create");
    dbCaClientContext = ca_current_context ();
    SEVCHK(ca_add_exception_event(exceptionCallback,NULL),
        "ca_add_exception_event");
    epicsEventSignal(startStopEvent);

    /* channel access event loop */
    while (TRUE){
        do {
            epicsEventMustWait(workListEvent);
        } while (dbCaCtl == ctlPause);
        while (TRUE) { /* process all requests in workList*/
            caLink *pca;
            short  link_action;
            int    status;

            epicsMutexMustLock(workListLock);
            if (!(pca = (caLink *)ellGet(&workList))){  /* Take off list head */
                epicsMutexUnlock(workListLock);
                if (dbCaCtl == ctlExit) goto shutdown;
                break; /* workList is empty */
            }
            link_action = pca->link_action;
            pca->link_action = 0;
            if (link_action & CA_CLEAR_CHANNEL) --removesOutstanding;
            epicsMutexUnlock(workListLock);         /* Give back immediately */
            if (link_action & CA_CLEAR_CHANNEL) {   /* This must be first */
                dbCaLinkFree(pca);
                /* No alarm is raised. Since link is changing so what? */
                continue; /* No other link_action makes sense */
            }
            if (link_action & CA_CONNECT) {
                status = ca_create_channel(
                      pca->pvname,connectionCallback,(void *)pca,
                      CA_PRIORITY_DB_LINKS, &(pca->chid));
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_create_channel %s\n",
                        ca_message(status));
                    printLinks(pca);
                    continue;
                }
                dbca_chan_count++;
                status = ca_replace_access_rights_event(pca->chid,
                    accessRightsCallback);
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask replace_access_rights_event %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
                continue; /*Other options must wait until connect*/
            }
            if (ca_state(pca->chid) != cs_conn) continue;
            if (link_action & CA_WRITE_NATIVE) {
                assert(pca->pputNative);
                if (pca->putType == CA_PUT) {
                    status = ca_array_put(
                        pca->dbrType, pca->nelements,
                        pca->chid, pca->pputNative);
                } else if (pca->putType==CA_PUT_CALLBACK) {
                    status = ca_array_put_callback(
                        pca->dbrType, pca->nelements,
                        pca->chid, pca->pputNative,
                        putCallback, pca);
                } else {
                    status = ECA_PUTFAIL;
                }
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_array_put %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
                epicsMutexMustLock(pca->lock);
                if (status == ECA_NORMAL) pca->newOutNative = FALSE;
                epicsMutexUnlock(pca->lock);
            }
            if (link_action & CA_WRITE_STRING) {
                assert(pca->pputString);
                if (pca->putType == CA_PUT) {
                    status = ca_array_put(
                        DBR_STRING, 1,
                        pca->chid, pca->pputString);
                } else if (pca->putType==CA_PUT_CALLBACK) {
                    status = ca_array_put_callback(
                        DBR_STRING, 1,
                        pca->chid, pca->pputString,
                        putCallback, pca);
                } else {
                    status = ECA_PUTFAIL;
                }
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_array_put %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
                epicsMutexMustLock(pca->lock);
                if (status == ECA_NORMAL) pca->newOutString = FALSE;
                epicsMutexUnlock(pca->lock);
            }
            /*CA_GET_ATTRIBUTES before CA_MONITOR so that attributes available
             * before the first monitor callback                              */
            if (link_action & CA_GET_ATTRIBUTES) {
                status = ca_get_callback(DBR_CTRL_DOUBLE,
                    pca->chid, getAttribEventCallback, pca);
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_get_callback %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
            }
            if (link_action & CA_MONITOR_NATIVE) {
                size_t element_size;
    
                element_size = dbr_value_size[ca_field_type(pca->chid)];
                epicsMutexMustLock(pca->lock);
                pca->pgetNative = dbCalloc(pca->nelements, element_size);
                epicsMutexUnlock(pca->lock);
                status = ca_add_array_event(
                    ca_field_type(pca->chid)+DBR_TIME_STRING,
                    ca_element_count(pca->chid),
                    pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_add_array_event %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
            }
            if (link_action & CA_MONITOR_STRING) {
                epicsMutexMustLock(pca->lock);
                pca->pgetString = dbCalloc(1, MAX_STRING_SIZE);
                epicsMutexUnlock(pca->lock);
                status = ca_add_array_event(DBR_TIME_STRING, 1,
                    pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0);
                if (status != ECA_NORMAL) {
                    errlogPrintf("dbCaTask ca_add_array_event %s\n",
                        ca_message(status));
                    printLinks(pca);
                }
            }
        }
        SEVCHK(ca_flush_io(), "dbCaTask");
    }
shutdown:
    taskwdRemove(0);
    if (dbca_chan_count == 0)
        ca_context_destroy();
    else
        fprintf(stderr, "dbCa: chan_count = %d at shutdown\n", dbca_chan_count);
    epicsEventSignal(startStopEvent);
}