From 79ef72594d52c158839e94a668891d056b4a549f Mon Sep 17 00:00:00 2001 From: "benjamin.franksen" <benjamin.franksen@helmholtz-berlin.de> Date: Thu, 26 Sep 2013 22:56:22 +0000 Subject: [PATCH] examples: added a C program to test async get in plain CA --- examples/Makefile | 1 + examples/pvGetAsync/Makefile | 12 +++ examples/pvGetAsync/pvGetAsync.c | 127 +++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 examples/pvGetAsync/Makefile create mode 100644 examples/pvGetAsync/pvGetAsync.c diff --git a/examples/Makefile b/examples/Makefile index 07f08198..0ba5b9d9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -6,5 +6,6 @@ DIRS += demo DIRS += johng #DIRS += parallel DIRS += simple +DIRS += pvGetAsync include $(TOP)/configure/RULES_DIRS diff --git a/examples/pvGetAsync/Makefile b/examples/pvGetAsync/Makefile new file mode 100644 index 00000000..3b52d17a --- /dev/null +++ b/examples/pvGetAsync/Makefile @@ -0,0 +1,12 @@ +TOP = ../.. + +include $(TOP)/configure/CONFIG +#---------------------------------------- +# ADD MACRO DEFINITIONS AFTER THIS LINE + +PROD_HOST += pvGetAsync +PROD_LIBS += Com ca + +include $(TOP)/configure/RULES +#---------------------------------------- +# ADD RULES AFTER THIS LINE diff --git a/examples/pvGetAsync/pvGetAsync.c b/examples/pvGetAsync/pvGetAsync.c new file mode 100644 index 00000000..7ede5433 --- /dev/null +++ b/examples/pvGetAsync/pvGetAsync.c @@ -0,0 +1,127 @@ +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "epicsEvent.h" +#include "cadef.h" + +struct var { + struct dbr_time_long get_val; + dbr_long_t put_val; + epicsEventId connected; + epicsEventId put_done; + epicsEventId get_done; + chid ch; +}; + +static struct var var1; +static struct var var2; + +static void connectionHandler (struct connection_handler_args args) +{ + struct var *pvar = (struct var *)ca_puser(args.chid); + switch (args.op) { + case CA_OP_CONN_UP: + epicsEventSignal(pvar->connected); + break; + case CA_OP_CONN_DOWN: + exit(EXIT_FAILURE); + } +} + +static void putHandler(struct event_handler_args args) +{ + if (args.status == ECA_NORMAL) { + struct var *pvar = (struct var *)ca_puser(args.chid); +#if 0 + printf("put type == %ld\n", args.type); + printf("put count == %lu\n", args.count); + assert(args.type == DBR_LONG); + assert(args.count == 1); +#endif + epicsEventSignal(pvar->put_done); + } else { + fprintf(stderr,"bad CA put response for channel %s: %s\n", ca_name(args.chid), ca_message(args.status)); + } +} + +static void getHandler(struct event_handler_args args) +{ + if (args.status == ECA_NORMAL) { + struct var *pvar = (struct var *)ca_puser(args.chid); + printf("get type == %ld\n", args.type); + assert(args.type == DBR_TIME_LONG); + assert(args.count == 1); +#if 0 +#endif + memcpy(&pvar->get_val, args.dbr, sizeof(pvar->get_val)); + epicsEventSignal(pvar->get_done); + } else { + fprintf(stderr,"bad CA get response for channel %s: %s\n", ca_name(args.chid), ca_message(args.status)); + } +} + +int main () +{ + int n = 0; + int wait_status; + var1.connected = epicsEventMustCreate(epicsEventEmpty); + var1.put_done = epicsEventMustCreate(epicsEventEmpty); + var1.get_done = epicsEventMustCreate(epicsEventEmpty); + var2.connected = epicsEventMustCreate(epicsEventEmpty); + var2.put_done = epicsEventMustCreate(epicsEventEmpty); + var2.get_done = epicsEventMustCreate(epicsEventEmpty); + SEVCHK(ca_context_create(ca_enable_preemptive_callback),"ca_context_create"); + SEVCHK(ca_create_channel("pvGetComplete1", connectionHandler, &var1, CA_PRIORITY_DEFAULT, &var1.ch),""); + SEVCHK(ca_create_channel("pvGetComplete2", connectionHandler, &var2, CA_PRIORITY_DEFAULT, &var2.ch),""); + epicsEventWait(var1.connected); + epicsEventWait(var2.connected); + printf("connected\n"); + while (n < 10) { + var1.put_val = 2*n; + var2.put_val = 2*n+1; + var1.get_val.value = 0; + var2.get_val.value = 0; + SEVCHK(ca_put_callback(DBR_LONG, var1.ch, &var1.put_val, putHandler, 0),""); + SEVCHK(ca_put_callback(DBR_LONG, var2.ch, &var2.put_val, putHandler, 0),""); + ca_flush_io(); +#if 0 + printf("waiting for put\n"); +#endif + wait_status = epicsEventWait(var1.put_done); + assert(wait_status == epicsEventWaitOK); + wait_status = epicsEventWait(var2.put_done); + assert(wait_status == epicsEventWaitOK); +#if 0 + printf("put done\n"); +#endif + SEVCHK(ca_get_callback(DBR_TIME_LONG, var1.ch, getHandler, 0),""); + SEVCHK(ca_get_callback(DBR_TIME_LONG, var2.ch, getHandler, 0),""); + ca_flush_io(); +#if 0 + printf("waiting for get\n"); +#endif + wait_status = epicsEventWait(var1.get_done); + assert(wait_status == epicsEventWaitOK); + wait_status = epicsEventWait(var2.get_done); + assert(wait_status == epicsEventWaitOK); +#if 0 + printf("get done\n"); +#endif + if (var1.put_val != var1.get_val.value) { + fprintf(stderr, "var1: put=%d, get=%d\n", var1.put_val, var1.get_val.value); + exit(EXIT_FAILURE); + } + if (var2.put_val != var2.get_val.value) { + fprintf(stderr, "var2: put=%d, get=%d\n", var2.put_val, var2.get_val.value); + exit(EXIT_FAILURE); + } +#if 0 + printf("test %d done\n", n); +#endif + n++; + } + printf("done\n"); + return 0; +} -- GitLab