|
|
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
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |