Ejemplo n.º 1
0
int
channel_get(Channel *chan)
{
    DEBUGP printf("channel_get %s %s\n", chan->chan_name, chan->valid?"valid":"invalid");
    if(! chan->valid)
	return -1;
    
    ca_array_get(chan->chan_type, chan->maxelement, chan->chan_id, chan->dataval);
    ca_flush_io( );
    return 0;
}
Ejemplo n.º 2
0
int
channel_put_ackt(Channel *chan, int acknowledge)
{
	short s_acknowledge = acknowledge;
	int status;

	if(! chan->valid)
		return -1;
	status = ca_array_put( DBR_PUT_ACKT, 1, chan->chan_id, &s_acknowledge);
	SEVCHK(status, "channel_put : ca_array_put ACKT failed");
	ca_flush_io();
	return 0;
}
Ejemplo n.º 3
0
int
channel_put_acks(Channel *chan, int severity)
{
	short s_severity = severity;
	int status;

	if(! chan->valid)
		return -1;
	status = ca_array_put( DBR_PUT_ACKS, 1, chan->chan_id, &s_severity);
	SEVCHK(status, "channel_put : ca_array_put ACKS failed");
	ca_flush_io();
	return 0;
}
Ejemplo n.º 4
0
void medmSendString(Record *pr, char *data)
{
    int status;

    Channel *pCh = &((caTask.pages[pr->caId/CA_PAGE_SIZE])
      [pr->caId % CA_PAGE_SIZE]);
    status = ca_put(DBR_STRING,pCh->chid,data);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"medmSendString: ca_put failed: %s\n",
	  ca_message(status));
    }
    ca_flush_io();
}
Ejemplo n.º 5
0
void medmSendCharacterArray(Record *pr, char *data, unsigned long size)
{
    int status;

    Channel *pCh = &((caTask.pages[pr->caId/CA_PAGE_SIZE])
      [pr->caId % CA_PAGE_SIZE]);
    status = ca_array_put(DBR_CHAR,size,pCh->chid,data);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"medmSendCharacterArray: ca_put failed: %s\n",
	  ca_message(status));
    }
    ca_flush_io();
}
Ejemplo n.º 6
0
int
channel_put(Channel *chan, int count)
{
    int status;
    
    DEBUGP printf("channel_put %s %d %s\n", chan->chan_name, count, chan->valid?"valid":"invalid");
    if(! chan->valid)
	return -1;
    if( count > chan->maxelement)
	count = chan->maxelement;
    status = ca_array_put(chan->chan_type, count, chan->chan_id, chan->dataval);
    SEVCHK(status, "channel_put : ca_array_put failed");
    ca_flush_io();
    return 0;
}
Ejemplo n.º 7
0
int
channel_put_callback( Channel *chan, int count, CHANNEL_USERFUNC func, void *arg)
{
    int status;
    
    DEBUGP printf("channel_put_callback %s %d %s\n", chan->chan_name, count, chan->valid?"valid":"invalid");
    if( !chan->valid)
	return -1;
    if( count > chan->maxelement)
	count = chan->maxelement;
    chan->outstanding = 1;
    status = ca_array_put_callback( chan->chan_type, count, chan->chan_id, chan->dataval, func, arg);
    SEVCHK(status, "channel_put_callback : ca_array_put_callback failed");
    ca_flush_io();
    return 0;
}
Ejemplo n.º 8
0
void medmSendDouble(Record *pr, double data)
{
    int status;

    Channel *pCh = &((caTask.pages[pr->caId/CA_PAGE_SIZE])
      [pr->caId % CA_PAGE_SIZE]);
    status = ca_put(DBR_DOUBLE,pCh->chid,&data);
#if DEBUG_SLIDER
    if(data > 150.0 || data < -150.0) {
	print("medmSendDouble: %g\n",data);
    }
#endif
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"medmSendDouble: ca_put failed: %s\n",
	  ca_message(status));
    }
    ca_flush_io();
}
Ejemplo n.º 9
0
/*
 * create a channel entry, and lookup all details
 */
Channel *
build_PV(char * name)
{
	Channel *chan;
	int st;

	chan = (Channel *) calloc( 1, sizeof *chan);
	if( !chan)
		return 0;
	chan->chan_name = strdup(name);
	chan->initData = 1;
	chan->createData = 1;
	chan->monitor = 1;
	chan->outstanding = 1;
	st = ca_search_and_connect(name, &(chan->chan_id), connect_callback, chan);
	DEBUGP printf("ca_search_and_connect = %d\n", st);
	ca_flush_io();
	return chan;
}
Ejemplo n.º 10
0
Channel *
init_PV(char *name, chtype chan_type, void *dataptr, int size)
{
    Channel *chan;
    int st;
    
    DEBUGP printf("init_PV(%s, ...)\n", name);
    chan = (Channel *) calloc( 1, sizeof (Channel));
    if( !chan)
	return 0;
    DEBUGP printf("Channel Allocated %p\n", chan);
    chan->chan_name = strdup(name);
    chan->chan_type = chan_type;
    chan->dataval = dataptr;
    chan->maxelement = size;
    chan->outstanding = 1;
    
    st = ca_search_and_connect(name, &(chan->chan_id), connect_callback, chan);
    DEBUGP printf("ca_search_and_connect = %d\n", st);
    ca_flush_io();
    return chan;
}
Ejemplo n.º 11
0
/*
 * callback from connection handler: change the state of the channel valid
 * flag depending on the connection being up or down.
 * ASSUMPTIONS: chan_id is valid.
 */
static void
connect_callback(struct connection_handler_args args)
{
    Connector *conp;
    
    Channel *chan = ca_puser( args.chid);
    int status;
    
    DEBUGP printf("connect callback %p\n", chan);
    switch( args.op)
    {
    case CA_OP_CONN_UP:
    	if( chan->initData == 1)
	{
		chan->maxelement = ca_element_count(chan->chan_id);
		chan->chan_type = ca_field_type(chan->chan_id);
		chan->initData = 0;
	}
	/*
	 * note that a dropped and recreated connection can cause a free and alloc. This
	 * is not always redundant, as software may have restarted with different sizes
	 * for the field!
	 */
	if( chan->createData == 1 )
	{
		if( chan->dataval)
			free( chan->dataval);
		chan->dataval = calloc(dbr_size[chan->chan_type], chan->maxelement+1);
	}

	chan->readAccess = ca_read_access( chan->chan_id);
	chan->writeAccess = ca_write_access( chan->chan_id);
	status = ca_array_get_callback( dbf_type_to_DBR_CTRL(ca_field_type(chan->chan_id)), 1, chan->chan_id, getChanInfo, (void*)chan);
	SEVCHK(status, "connect_callback : ca_get_DBR_CTRL_event failed");
	status = ca_replace_access_rights_event( chan->chan_id, getAccessRights);
	SEVCHK(status, "connect_callback : ca_replace_access_rights_event failed");

	chan->valid = 1;
	chan->outstanding = 0;
	if( chan->monitor)
	{
	    chan->status = 100;	/* MAGIC: an absurd status */
	    status = ca_add_array_event(dbf_type_to_DBR_STS(chan->chan_type), chan->maxelement, chan->chan_id, monitorCallback, chan, 
		    		(double) 0.0, (double) 0.0, (double) 0.0, &(chan->eventId));
	    SEVCHK(status, "connect_callback : ca_add_event failed");
	    status = ca_flush_io();
	    SEVCHK(status, "connect_callback : ca_flush_io failed");
	}
	break;
	
    case CA_OP_CONN_DOWN:
	if( chan->valid && chan->eventId)
	    ca_clear_event(chan->eventId);
	chan->valid = 0;
	chan->status = 99;
	
	/*
	 * update the access rights and severity for all the connectors
	 */
	for(conp=chan->first_connector; conp ; conp=conp->next)
	{
	    if(conp->newAccess)
		(*conp->newAccess)(conp);
	    if( conp->newState)
	    	(*conp->newState)(conp);
	}
	
	break;
    default:
	break;
    }

    return;
}
Ejemplo n.º 12
0
int main(int argc,char **argv)
{
    char   *pval;
    double sleepSecs = 0.0;
    int	    clearEvery = 0;
    int     indValue = 1;
    int     indNumberCallback = 1;

    while((argc>1) && (argv[1][0] == '-')) {
        int i;
        char option;
        int  narg;
        option = toupper((argv[1])[1]);
        pval = argv[2];
        argc -= 1; narg = 1;
        if(option=='S') {
            sscanf(pval,"%lf",&sleepSecs);
            argc -= 1; ++narg;
        } else if(option=='C') {
            sscanf(pval,"%d",&clearEvery);
            argc -= 1; ++narg;
        } else if(option=='V') {
            verbose = 1;
        } else {
            usageExit();
        }
        for(i=1; i<argc; i++) argv[i] = argv[i + narg];
    }

    if(argc != 4) usageExit();
    pvname = argv[1];
    pvalue1 = argv[2];
    pvalue2 = argv[3];
    pevent = epicsEventCreate(epicsEventEmpty);
    SEVCHK(ca_context_create(ca_enable_preemptive_callback),
        "ca_task_initialize");
    while(1) {
        SEVCHK(ca_search(pvname,&mychid),"ca_search_and_connect");
        if(ca_pend_io(3.0)!=ECA_NORMAL) {
            epicsThreadSleep(5.0);
            continue;
        }
        while(1) {
            epicsEventWaitStatus status;
            if(indValue==0) {
                indValue = 1; pvalue = pvalue2;
            } else {
                indValue = 0; pvalue=pvalue1;
            }
            if(++indNumberCallback >= MAXnumberCallback) indNumberCallback=0;
            numberCallback[indNumberCallback] = ++expectedCallback;
            status = ca_array_put_callback(DBR_STRING,1,mychid,
                pvalue,putCallback,&numberCallback[indNumberCallback]);
            if(status!=ECA_NORMAL) {
                printf("ca_array_put_callback %s\n",ca_message(status));
                epicsThreadSleep(2.0);
                continue;
            }
            if((clearEvery>0) 
            && ((expectedCallback % clearEvery)==0)) {
                ca_flush_io();
                epicsThreadSleep(sleepSecs);
                SEVCHK(ca_clear_channel(mychid),"ca_clear_channel");
                ca_flush_io();
                expectedCallback = 0;
                epicsThreadSleep(sleepSecs);
                if(verbose) {
                    printTime();
                    printf("Issued ca_clear_channel expectedCallback %d\n",
                        expectedCallback);
                }
                break;
            }
            ca_flush_io();
            if(verbose) {
                printTime();
                printf("Issued ca_put_callback expectedCallback %d\n",
                    expectedCallback);
            }
            while(1) {
                status = epicsEventWaitWithTimeout(pevent,10.0);
                if(status==epicsEventWaitTimeout) {
                    if(verbose) {
                        printTime();
                        printf("timeout after 10 seconds\n");
                    }
                    continue;
                }
                break;
            }
            if(status!=epicsEventWaitOK) {
                int i;
                printTime();
                printf("eventWait status %d\n",status);
                for(i=0; i<MAXnumberCallback; i++) numberCallback[i]=0;
            }
            epicsThreadSleep(sleepSecs);
        }
    }
    ca_task_exit();
    return(0);
}
Ejemplo n.º 13
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);
}