I have tried to solve it using the Primitive C Data Type :
typedef struct { chid channel; int status; long number; dbr_char_t value; } epicsWavePV;
....
int main(int argc,char** argv)
{ const dbr_char_t* pValue; epicsWavePV wave; ...... ca_array_get(DBR_CHAR, 10, wave.channel, &wave.value); ...... pValue = &wave.value; for(i=0;i<10;i++) printf("%d ", pValue[i]);
}
And it compiles and runs (now without error during compilation) on Windows. I then compile it on Linux. Compilation no errors. Run and get: Segmentation fault. It seems I have to allocate memory for my wave structure (as in CA reference manual http://www.aps.anl.gov/epics/base/R3-14/12-docs/CAref.html#Channel).
My program, though, is partially based upon Dirk's caTutorial.
Strange, strange... Are there any C clients programmers out there?
Pavel.
On Sat, May 12, 2012 at 11:27 AM, Pavel Masloff <[email protected]> wrote:
It's a strange thing. On Windows (VisualStudio 2010) this code works despite the warning, on Linux I get segmentation fault.
I should have written pValue = wave.value but in this case it doesn't work even on Windows.
Can anyone check my code? I need to read a waveform (FTVL=UCHAR) via CA in C.
On Sat, May 12, 2012 at 1:26 AM, Pavel Masloff <[email protected]> wrote:
Alright, here it works. If someone's interested:
#include <stddef.h>
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "cadef.h"
const char *channel_state_str[4] = { "not found", "connection lost", "connected", "closed" };
typedef struct { chid channel;
int status;
long value; } epicsShortPV;
typedef struct { chid channel; int status; long number; unsigned short* value; } epicsWavePV;
/* Connect a PV to a channel */
#define casearch(name, pv) SEVCHK(\ (pv).status = (ca_search((name), &(pv).channel)), name)
/* get full information about a PV */ #define cainfo(pv, type) SEVCHK(\ (pv).status = (ca_state((pv).channel) != cs_conn ? ECA_DISCONN : \
ca_get(dbf_type_to_DBR(type), (pv).channel, &(pv).value)), ca_name((pv).channel)) /* get only usually changing information about a PV */ #define caget(pv, type) SEVCHK(\ (pv).status = (ca_state((pv).channel) != cs_conn ? ECA_DISCONN : \
ca_get(dbf_type_to_DBR_STS(type), (pv).channel, &(pv).data)), ca_name((pv).channel))
void printPV(const epicsShortPV* pv) { if (ca_state(pv->channel) == cs_conn) { printf("%s = %d \n", ca_name(pv->channel), pv->value);
} else { printf("%s: <%s>\n",ca_name(pv->channel), channel_state_str[ca_state(pv->channel)]); } }
int main(int argc,char** argv) { int i;
char* pValue; epicsShortPV nelm, nord; epicsWavePV wave; double search_timeout = 5.0; double get_timeout = 1.0;
ca_task_initialize(); casearch("file.NELM", nelm);
casearch("file.NORD", nord); casearch("file", wave); SEVCHK(ca_pend_io(search_timeout), "casearch"); /*ca_get(dbf_type_to_DBR(DBR_LONG),nelm.channel,(void*)&nelm.value);
ca_get(dbf_type_to_DBR(DBR_LONG),nord.channel,(void*)&nord.value);*/ cainfo(nelm, DBF_LONG); cainfo(nord, DBF_LONG); ca_array_get(DBR_CHAR, 10, wave.channel, (char*)&wave.value);
SEVCHK(ca_pend_io(get_timeout), "cainfo"); printPV(&nelm); printPV(&nord); pValue = & wave.value; for(i=0;i<10;i++) printf("%d ", pValue[i]);
ca_task_exit(); return 0; }
One thing I can't get, though everything works fine. The compiler goes with a warning at the line pValue = & wave.value :
warning C4047: '=' : 'char *' differs in levels of indirection from 'unsigned short **' How can it be fixed (if nesessary)? Thanks.
On Fri, May 11, 2012 at 7:32 PM, Mark Rivers <[email protected]> wrote:
I don't have much experience with writing CA clients in C, I mostly use IDL, Java, Python, etc. Perhaps someone else can help.
Mark
________________________________
From: Pavel Masloff [[email protected]]
Sent: Friday, May 11, 2012 9:07 AM
To: Mark Rivers
Cc: EPICS Tech Talk
Subject: Re: [CA][waveform] how to NELM?
Thanks, Mark! It works if I am reading just one PV. But when I am reading 2 PVs - (waveform and NELM), my NELM value is enormously big!!!
How can I read several PVs?
This is my code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cadef.h"
int main(int argc,char **argv)
{
int data; /* NELM */
chid mychid;
chid chan; /* WAVEFORM - file*/
int status;
unsigned elementCount, nBytes, i;
struct dbr_time_char * pTD;
const dbr_char_t * pValue;
SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create");
SEVCHK(ca_create_channel("file.NORD",NULL,NULL,10,&mychid),"ca_create_channel failure");
SEVCHK(ca_pend_io(1.0),"ca_pend_io failure");
SEVCHK(ca_get(DBR_INT,mychid,(void *)&data),"ca_get failure");
SEVCHK(ca_pend_io(1.0),"ca_pend_io failure");
printf("file.NORD: %d\n",data);
ca_clear_channel ( mychid );
ca_task_exit ();
SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create");
status = ca_create_channel ( argv[1], 0, 0, 0, & chan );
ca_search(argv[1], &chan);
SEVCHK ( status, "ca_create_channel()" );
status = ca_pend_io ( 1.0 );
if ( status != ECA_NORMAL ) {
fprintf ( stderr, "\"%s\" not found.\n", argv[1] );
return -1;
}
elementCount = ca_element_count ( chan );
nBytes = dbr_size_n ( DBR_TIME_CHAR, elementCount );
pTD = ( struct dbr_time_char * ) malloc ( nBytes );
if ( ! pTD ) {
fprintf ( stderr, "insufficient memory to complete request\n" );
return -1;
}
status = ca_array_get (DBR_TIME_CHAR, elementCount, chan, pTD );
SEVCHK ( status, "ca_array_get()" );
status = ca_pend_io ( 1.0 );
if ( status != ECA_NORMAL ) {
fprintf ( stderr, "\"%s\" didnt return a value.\n", argv[1] );
return -1;
}
pValue = & pTD->value;
for ( i = 0; i < 10; i++ ) printf("%d ", pValue[i]);
printf("\nTotal size: %d\n", elementCount);
printf("Timestamp: %d\n", pTD->stamp.nsec);
ca_clear_channel ( chan );
free ( pTD );
return(0);
}
On Fri, May 11, 2012 at 3:42 PM, Mark Rivers < [email protected]<mailto: [email protected]>> wrote:
You can just do a ca_get of record.NELM.
________________________________
From: [email protected]<mailto:[email protected]> [[email protected]<mailto:[email protected]>] on behalf of Pavel Masloff [[email protected]<mailto:[email protected]>]
Sent: Friday, May 11, 2012 6:39 AM
To: EPICS Tech Talk
Subject: [CA][waveform] how to NELM?
I am writing a simple CA client in C.
The client reads the waveform record. And I need to know how many elements there are in it (NELM field).
There is a function entitled ca_element_count() which happens to read the NORD field.
Does anybody know how can I get the NELM field ?
--
Best regards,
Pavel Maslov, MS
Controls Engineer at Pulsed power Lab
Efremov Institute for Electro-Physical Apparatus
St. Petersburg, Russia
Mobile: +7 (951) 672 22 19
Landline: +7 (812) 461 01 01
--
Best regards,
Pavel Maslov, MS
Controls Engineer at Pulsed power Lab
Efremov Institute for Electro-Physical Apparatus
St. Petersburg, Russia
Mobile: +7 (951) 672 22 19
Landline: +7 (812) 461 01 01
-- Best regards,
Pavel Maslov, MS Controls Engineer at Pulsed power Lab
Efremov Institute for Electro-Physical Apparatus
St. Petersburg, Russia
Mobile: +7 (951) 672 22 19
Landline: +7 (812) 461 01 01
-- Best regards,
Pavel Maslov, MS Controls Engineer at Pulsed power Lab Efremov Institute for Electro-Physical Apparatus
St. Petersburg, Russia
Mobile: +7 (951) 672 22 19
Landline: +7 (812) 461 01 01
-- Best regards,
Pavel Maslov, MS Controls Engineer at Pulsed power Lab Efremov Institute for Electro-Physical Apparatus
St. Petersburg, Russia
Mobile: +7 (951) 672 22 19
Landline: +7 (812) 461 01 01
- References:
- [CA][waveform] how to NELM? Pavel Masloff
- RE: [CA][waveform] how to NELM? Mark Rivers
- Re: [CA][waveform] how to NELM? Pavel Masloff
- RE: [CA][waveform] how to NELM? Mark Rivers
- Re: [CA][waveform] how to NELM? Pavel Masloff
- Re: [CA][waveform] how to NELM? Pavel Masloff
- Navigate by Date:
- Prev:
Re: [CA][waveform] how to NELM? Pavel Masloff
- Next:
Re: [CA][waveform] how to NELM? Matthieu Bec
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: [CA][waveform] how to NELM? Pavel Masloff
- Next:
Re: [CA][waveform] how to NELM? Matthieu Bec
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|