Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: Re: [CA][waveform] how to NELM?
From: Pavel Masloff <pavel.masloff@gmail.com>
To: Matthieu Bec <mbec@gmto.org>
Cc: EPICS Tech Talk <tech-talk@aps.anl.gov>
Date: Mon, 14 May 2012 00:50:38 +0400
Hello Matthieu and Rod,

Thank you! I have finally succeeded! Caget.c is really a good example.

On Sat, May 12, 2012 at 6:57 PM, Matthieu Bec <mbec@gmto.org> wrote:

Hello Pavel,
look at the mechanics in catools/caget.c for inspiration.
your last attempt segfaults because at one point or another you need to provide a buffer with sufficient (usually allocated) space to hold the result. when that happens depends on the 'callback' flag - in your synchronous case, follow callback=false.
your first attempt seemed somewhat closer because you did malloc.

Regards
Matthieu



On 05/12/12 00:27, Pavel Masloff 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 <pavel.masloff@gmail.com
<mailto:pavel.masloff@gmail.com>> 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
   <rivers@cars.uchicago.edu <mailto:rivers@cars.uchicago.edu>> 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 [pavel.masloff@gmail.com
       <mailto:pavel.masloff@gmail.com>]

       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
       <rivers@cars.uchicago.edu
       <mailto:rivers@cars.uchicago.edu><mailto:rivers@cars.uchicago.edu <mailto:rivers@cars.uchicago.edu>>>

       wrote:
       You can just do a ca_get of record.NELM.
       ________________________________
       From: tech-talk-bounces@aps.anl.gov
       <mailto:tech-talk-bounces@aps.anl.gov><mailto:tech-talk-bounces@aps.anl.gov
       <mailto:tech-talk-bounces@aps.anl.gov>>
       [tech-talk-bounces@aps.anl.gov
       <mailto:tech-talk-bounces@aps.anl.gov><mailto:tech-talk-bounces@aps.anl.gov

       <mailto:tech-talk-bounces@aps.anl.gov>>] on behalf of Pavel
       Masloff [pavel.masloff@gmail.com
       <mailto:pavel.masloff@gmail.com><mailto:pavel.masloff@gmail.com

       <mailto:pavel.masloff@gmail.com>>]
       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


--
Matthieu Bec                GMTO Corp.
cell:  +1 626 354 9367      P.O. Box 90933
phone: +1 626 204 0527      Pasadena, CA 91109-0933




--
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
Re: [CA][waveform] how to NELM? Matthieu Bec

Navigate by Date:
Prev: [aSub] using external libraries Pavel Masloff
Next: Re: [aSub] using external libraries Eric Norum
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017 
Navigate by Thread:
Prev: Re: [CA][waveform] how to NELM? Matthieu Bec
Next: 'reconnect' in asyn / streamDevice Emmanuel Mayssat
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  2015  2016  2017 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·