Experimental Physics and
| |||||||||||||||||
|
here is the working one: http://lansce.lanl.gov/EPICSdata/ca/client/caX5Ftutor-1.html You will find attached the C file we are using, it was reconstructed from the above link, Section 3 Writing to PVs and Using Connection Handlers. the function call that doesn't work correctly is the "ca_put_callback" and the callback function is "an_event_handler" We tryied with the command line, and we can reproduce the problem, here is the result: [haquin@accep1 haquin]$ caput -c LB-DIA-ALB-TST2:Read_16bits_Reg.DESC "abcdefg" Old : LB-DIA-ALB-TST2:Read_16bits_Reg.DESC It's 14-NOV-2008 16:52:23.04 New : LB-DIA-ALB-TST2:Read_16bits_Reg.DESC a [haquin@accep1 haquin]$ caput LB-DIA-ALB-TST2:Read_16bits_Reg.DESC "abcdefg" Old : LB-DIA-ALB-TST2:Read_16bits_Reg.DESC a New : LB-DIA-ALB-TST2:Read_16bits_Reg.DESC abcdefg Thanx Andrew Johnson a Ãcrit : Hi Christophe, #include <cadef.h> #include <stdio.h> #define MAXLEN 20 #define POLL 1.0e-9 #define SHRT_DLY 0.1 #define LNG_DLY 0.25 struct Channel{ dbr_string_t name; chid chan; struct Channel *next; struct Channel *prev;} *pFirst = NULL, *pLast; void connect_handler1(struct connection_handler_args); void connect_handler2(struct connection_handler_args); void an_event_handler(struct event_handler_args); struct Channel *search(char *Name); struct Channel *search(char *Name) { struct Channel *pCurrent; int flag = 0; if(pFirst != NULL){ for(pCurrent = pFirst; pCurrent != NULL; pCurrent = pCurrent->next){ if(strcmp(pCurrent->name, Name) == 0){ flag = 1; break; } } } if(flag) return (pCurrent); else return (NULL); } void an_event_handler(struct event_handler_args handler_args) { if (handler_args.status != ECA_NORMAL){ printf("channel %s: put operation not sucessful.\n", ca_name(handler_args.chid)); SEVCHK(handler_args.status, NULL); } else printf("channel %s: put operation completed.\n", ca_name(handler_args.chid)); return; } void connect_handler1(struct connection_handler_args connect_args) { struct Channel *pCurrent; /* set point to user-supplied address */ pCurrent = ca_puser(connect_args.chid); /* if connection up, intialize list or add node */ if(connect_args.op == CA_OP_CONN_UP){ if(pFirst == NULL){ pFirst = pCurrent; pFirst->prev = NULL; pLast = pCurrent; } pLast->next = pCurrent; pCurrent->prev = pLast; pCurrent->next = NULL; pLast = pCurrent; printf("%s is connected.\n", pCurrent->name); } /* if connection down, print message. This block */ /* is unlikely to ever be used. */ else printf("%s is not connected.\n", pCurrent->name); return; } void connect_handler2(struct connection_handler_args connect_args) { struct Channel *pCurrent; struct Channel *pPrevious, *pNext; /* if connection down, free memory of user */ /* supplied address, and delete nodes from list. */ if (connect_args.op == CA_OP_CONN_DOWN){ pCurrent = ca_puser(connect_args.chid); if(pCurrent != pLast && pCurrent != pFirst){ pPrevious = pCurrent->prev; pNext = pCurrent->next; pPrevious->next = pNext; pNext->prev = pPrevious; free(pCurrent); } else if (pCurrent == pLast && pCurrent != pFirst){ pLast = pCurrent->prev; pLast->next = NULL; free(pCurrent); } else if (pCurrent == pFirst && pCurrent != pLast){ pFirst = pCurrent->next; pFirst->prev = NULL; free(pCurrent); } else if(pCurrent == pFirst && pCurrent == pLast){ pFirst = NULL; pLast = NULL; free(pCurrent); } printf("%s: channel disconnected.\n", ca_name(connect_args.chid)); } /* if re-connected, re-allocate memory */ else if(connect_args.op == CA_OP_CONN_UP){ strcpy(pCurrent->name, ca_name(connect_args.chid)); pCurrent->chan = connect_args.chid; if (pFirst == NULL){ pFirst = pCurrent; pFirst->prev = NULL; pLast = pCurrent; pCurrent->next = NULL; } else{ pLast->next = pCurrent; pCurrent->prev = pLast; pCurrent->next = NULL; pLast = pCurrent; } printf("%s: channel re-connected.\n", pCurrent->name); } return; } int main() { int status, i, j, k; dbr_float_t *pValue; dbr_string_t Value; dbr_string_t Name[MAXLEN]; struct Channel *pCurrent; unsigned long Nelem; /* initialize Channel Access task */ SEVCHK(ca_task_initialize(), "Unable to initialize"); /* Get channel names and establish connection for each.*/ /* Allocate memory for first node, and then for each */ /* addtional node after connection is established. Loop */ /* until user enters"quit". */ for (printf("Enter a channel name.\n"), pCurrent=(struct Channel *)calloc(1, sizeof(struct Channel)); gets(pCurrent->name) != NULL && strcmp(pCurrent->name, "quit") != 0; printf("Enter a channel name or \"quit\" to stop.\n")){ status = ca_search_and_connect(pCurrent->name, /* name string */ &(pCurrent->chan),/* chid */ connect_handler1, /* connection handler */ pCurrent /* user-supplied address */ ); SEVCHK(status, NULL); ca_pend_event(LNG_DLY); if (ca_state(pCurrent->chan) != cs_conn) printf("couldn't establish connection to %s; ignoring\n", pCurrent->name); else pCurrent =(struct Channel *) calloc(1,sizeof(struct Channel)); } /* Install a different connection handler on each channel. */ if(pFirst != NULL){ for (pCurrent = pFirst; pCurrent != NULL; pCurrent = pCurrent->next){ status=ca_change_connection_event(pCurrent->chan, connect_handler2); SEVCHK(status, "ca_change_connection_event: couldn't change handler"); } ca_flush_io(); /* Loop until "quit" is entered. Get Channel name. If */ /* found, prompt for values; else skip rest of loop. */ /* Call ca_put_callback(). */ for (i = 0, printf("%s\n%s\n", "Enter the PV's name", "Enter \"quit\" to stop"); gets(Name) != NULL && strcmp(Name, "quit") !=0; printf("%s\n", "Enter PV name or \"quit\" to stop")){ ca_pend_event(POLL); pCurrent = search(Name); if(pCurrent == NULL){ printf("Cannot find channel name in list. Disconnected?\n"); continue; } Nelem = ca_element_count(pCurrent->chan); if(Nelem == 1){ printf("Enter value.\n"); if(gets(Value) != NULL){ status = ca_put_callback(DBR_STRING, /* external type */ pCurrent->chan, /* chid */ Value, /* string of value */ an_event_handler, /* callback */ pCurrent /* user supplied address */); SEVCHK(status, NULL); } } else if (Nelem > 1){ printf("Enter up to %u values or q to quit.\n", Nelem); pValue = (float *) calloc(Nelem, sizeof(*pValue)); for(k = 0; (j = scanf("%f", pValue+k)) == 1&& j != EOF && k < Nelem; k++) ; j = getchar(); status = ca_array_put_callback(DBR_FLOAT, /* external type */ Nelem, /* no. of elements to be sent */ pCurrent->chan, /* chid */ pValue, /* array of values */ an_event_handler, /* callback */ pCurrent /* user supplied address */ ); SEVCHK(status, NULL); } ca_pend_event(SHRT_DLY); } return(0); } } begin:vcard fn:Christophe Haquin n:Haquin;Christophe email;internet:[email protected] tel;work:02 31 45 46 61 x-mozilla-html:FALSE version:2.1 end:vcard
| ||||||||||||||||
ANJ, 02 Sep 2010 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |