331 lines
6.2 KiB
C
331 lines
6.2 KiB
C
/*************************************************************************\
|
||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||
* National Laboratory.
|
||
* Copyright (c) 2002 The Regents of the University of California, as
|
||
* Operator of Los Alamos National Laboratory.
|
||
* EPICS BASE Versions 3.13.7
|
||
* and higher are distributed subject to a Software License Agreement found
|
||
* in file LICENSE that is included with this distribution.
|
||
\*************************************************************************/
|
||
/* @(#)ca_test.c $Id$
|
||
* Author: Jeff Hill
|
||
* Date: 07-01-91
|
||
*
|
||
* make options
|
||
* -DvxWorks makes a version for VxWorks
|
||
*/
|
||
|
||
/*
|
||
* ANSI
|
||
*/
|
||
#include <string.h>
|
||
#include <stdio.h>
|
||
#include <epicsStdlib.h>
|
||
|
||
#ifndef LOCAL
|
||
#define LOCAL static
|
||
#endif
|
||
|
||
#include "cadef.h"
|
||
#include "epicsTime.h"
|
||
|
||
int ca_test(char *pname, char *pvalue);
|
||
LOCAL int cagft(char *pname);
|
||
LOCAL void printit(struct event_handler_args args);
|
||
LOCAL int capft(char *pname, char *pvalue);
|
||
LOCAL void verify_value(chid chan_id, chtype type);
|
||
|
||
static unsigned long outstanding;
|
||
|
||
|
||
/*
|
||
* ca_test
|
||
*
|
||
* find channel, write a value if supplied, and
|
||
* read back the current value
|
||
*
|
||
*/
|
||
int ca_test(
|
||
char *pname,
|
||
char *pvalue
|
||
)
|
||
{
|
||
int status;
|
||
if(pvalue){
|
||
status = capft(pname,pvalue);
|
||
}
|
||
else{
|
||
status = cagft(pname);
|
||
}
|
||
ca_task_exit();
|
||
return status;
|
||
}
|
||
|
||
|
||
|
||
/*
|
||
* cagft()
|
||
*
|
||
* ca get field test
|
||
*
|
||
* test ca get over the range of CA data types
|
||
*/
|
||
LOCAL int cagft(char *pname)
|
||
{
|
||
const unsigned maxTries = 1000ul;
|
||
unsigned ntries = 0u;
|
||
chid chan_id;
|
||
int status;
|
||
int i;
|
||
|
||
/*
|
||
* convert name to chan id
|
||
*/
|
||
status = ca_search(pname, &chan_id);
|
||
SEVCHK(status,NULL);
|
||
status = ca_pend_io(5.0);
|
||
if(status != ECA_NORMAL){
|
||
SEVCHK(ca_clear_channel(chan_id),NULL);
|
||
printf("Not Found %s\n", pname);
|
||
return -1;
|
||
}
|
||
|
||
printf("name:\t%s\n",
|
||
ca_name(chan_id));
|
||
printf("native type:\t%s\n",
|
||
dbr_type_to_text(ca_field_type(chan_id)));
|
||
printf("native count:\t%lu\n",
|
||
ca_element_count(chan_id));
|
||
|
||
|
||
/*
|
||
* fetch as each type
|
||
*/
|
||
for(i=0; i<=LAST_BUFFER_TYPE; i++){
|
||
if(ca_field_type(chan_id)==DBR_STRING) {
|
||
if( (i!=DBR_STRING)
|
||
&& (i!=DBR_STS_STRING)
|
||
&& (i!=DBR_TIME_STRING)
|
||
&& (i!=DBR_GR_STRING)
|
||
&& (i!=DBR_CTRL_STRING)) {
|
||
continue;
|
||
}
|
||
}
|
||
/* ignore write only types */
|
||
if (
|
||
i == DBR_PUT_ACKT ||
|
||
i == DBR_PUT_ACKS ) {
|
||
continue;
|
||
}
|
||
|
||
status = ca_array_get_callback(
|
||
i,
|
||
ca_element_count(chan_id),
|
||
chan_id,
|
||
printit,
|
||
NULL);
|
||
SEVCHK(status, NULL);
|
||
|
||
outstanding++;
|
||
}
|
||
|
||
/*
|
||
* wait for the operation to complete
|
||
* before returning
|
||
*/
|
||
while ( ntries < maxTries ) {
|
||
unsigned long oldOut;
|
||
|
||
oldOut = outstanding;
|
||
ca_pend_event ( 0.05 );
|
||
|
||
if ( ! outstanding ) {
|
||
SEVCHK ( ca_clear_channel ( chan_id ), NULL );
|
||
printf ( "\n\n" );
|
||
return 0;
|
||
}
|
||
|
||
if ( outstanding == oldOut ) {
|
||
ntries++;
|
||
}
|
||
}
|
||
|
||
SEVCHK ( ca_clear_channel ( chan_id ), NULL );
|
||
return -1;
|
||
}
|
||
|
||
|
||
/*
|
||
* PRINTIT()
|
||
*/
|
||
LOCAL void printit ( struct event_handler_args args )
|
||
{
|
||
if ( args.status == ECA_NORMAL ) {
|
||
ca_dump_dbr ( args.type, args.count, args.dbr );
|
||
}
|
||
else {
|
||
printf ( "%s\t%s\n", dbr_text[args.type], ca_message(args.status) );
|
||
}
|
||
|
||
outstanding--;
|
||
}
|
||
|
||
/*
|
||
* capft
|
||
*
|
||
* test ca_put() over a range of data types
|
||
*
|
||
*/
|
||
LOCAL int capft(
|
||
char *pname,
|
||
char *pvalue
|
||
)
|
||
{
|
||
dbr_short_t shortvalue;
|
||
dbr_long_t longvalue;
|
||
dbr_float_t floatvalue;
|
||
dbr_char_t charvalue;
|
||
dbr_double_t doublevalue;
|
||
unsigned long ntries = 10ul;
|
||
int status;
|
||
chid chan_id;
|
||
|
||
if (((*pname < ' ') || (*pname > 'z'))
|
||
|| ((*pvalue < ' ') || (*pvalue > 'z'))){
|
||
printf("\nusage \"pv name\",\"value\"\n");
|
||
return -1;
|
||
}
|
||
|
||
/*
|
||
* convert name to chan id
|
||
*/
|
||
status = ca_search(pname, &chan_id);
|
||
SEVCHK(status,NULL);
|
||
status = ca_pend_io(5.0);
|
||
if(status != ECA_NORMAL){
|
||
SEVCHK(ca_clear_channel(chan_id),NULL);
|
||
printf("Not Found %s\n", pname);
|
||
return -1;
|
||
}
|
||
|
||
printf("name:\t%s\n", ca_name(chan_id));
|
||
printf("native type:\t%d\n", ca_field_type(chan_id));
|
||
printf("native count:\t%lu\n", ca_element_count(chan_id));
|
||
|
||
/*
|
||
* string value ca_put
|
||
*/
|
||
status = ca_put(
|
||
DBR_STRING,
|
||
chan_id,
|
||
pvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_STRING);
|
||
|
||
if(ca_field_type(chan_id)==0)goto skip_rest;
|
||
|
||
if(sscanf(pvalue,"%hd",&shortvalue)==1) {
|
||
/*
|
||
* short integer ca_put
|
||
*/
|
||
status = ca_put(
|
||
DBR_SHORT,
|
||
chan_id,
|
||
&shortvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_SHORT);
|
||
status = ca_put(
|
||
DBR_ENUM,
|
||
chan_id,
|
||
&shortvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_ENUM);
|
||
charvalue=(dbr_char_t)shortvalue;
|
||
status = ca_put(
|
||
DBR_CHAR,
|
||
chan_id,
|
||
&charvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_CHAR);
|
||
}
|
||
if(sscanf(pvalue,"%d",&longvalue)==1) {
|
||
/*
|
||
* long integer ca_put
|
||
*/
|
||
status = ca_put(
|
||
DBR_LONG,
|
||
chan_id,
|
||
&longvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_LONG);
|
||
}
|
||
if(epicsScanFloat(pvalue, &floatvalue)==1) {
|
||
/*
|
||
* single precision float ca_put
|
||
*/
|
||
status = ca_put(
|
||
DBR_FLOAT,
|
||
chan_id,
|
||
&floatvalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_FLOAT);
|
||
}
|
||
if(epicsScanDouble(pvalue, &doublevalue)==1) {
|
||
/*
|
||
* double precision float ca_put
|
||
*/
|
||
status = ca_put(
|
||
DBR_DOUBLE,
|
||
chan_id,
|
||
&doublevalue);
|
||
SEVCHK(status, NULL);
|
||
verify_value(chan_id, DBR_DOUBLE);
|
||
}
|
||
|
||
skip_rest:
|
||
|
||
/*
|
||
* wait for the operation to complete
|
||
* (outstabnding decrements to zero)
|
||
*/
|
||
while(ntries){
|
||
ca_pend_event(1.0);
|
||
|
||
if(!outstanding){
|
||
SEVCHK(ca_clear_channel(chan_id),NULL);
|
||
printf("\n\n");
|
||
return 0;
|
||
}
|
||
|
||
ntries--;
|
||
}
|
||
|
||
SEVCHK(ca_clear_channel(chan_id),NULL);
|
||
return -1;
|
||
}
|
||
|
||
|
||
/*
|
||
* VERIFY_VALUE
|
||
*
|
||
* initiate print out the values in a database access interface structure
|
||
*/
|
||
LOCAL void verify_value(chid chan_id, chtype type)
|
||
{
|
||
int status;
|
||
|
||
/*
|
||
* issue a get which calls back `printit'
|
||
* upon completion
|
||
*/
|
||
status = ca_array_get_callback(
|
||
type,
|
||
ca_element_count(chan_id),
|
||
chan_id,
|
||
printit,
|
||
NULL);
|
||
SEVCHK(status, NULL);
|
||
|
||
outstanding++;
|
||
}
|