EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Weird waveform behavior
From: Dirk Zimoch <[email protected]>
To: Zhichu Chen <[email protected]>
Cc: [email protected]
Date: Tue, 17 Jun 2008 14:46:55 +0200
Hi Chen,

we run into similar problems at the SLS recently. The problem is the difference between how we think array support should work and how it is actually implemented. All EPICS records which deal with arrays always copy buffers. Manipulating pointers is not supported!

That means:
Do not modify pwf->bptr. It simply does not do what you would expect.

Reason:
The value of pwf->bptr is read by channel access on connect only. Thus reading the same record multiple times (get or monitor) from the same application always reads the same buffer. Modifications of pwf->bptr after the client has connected have no effect. Thus, touching pwf->bptr after record initialization must be considered illegal. You have to copy buffers instead of moving pointers.


Pointing pwf->bptr to a local variable as in your code is even worse. long BUFFER[10000] exists on the stack only and is vanishes as soon as read_wf() finishes. Thus giving a pointer to BUFFER to the outside world is generally illegal in C, not only in EPICS. I can't see why you did this. pwf->bptr is already pointing to a buffer of NELM longs. The record has set up the buffer for you. In your case, 10000 is probably the better value for NELM. Don't forget to check NELM in your code before looping to 10000 to avoid array bounds violations. You can also get a stack overflow on embedded systems like vxWorks when you use huge local arrays variables. Never do that.

A similar thing happens inside subArray. The record first copies all input into is own buffer (instead of just looking at a pointer). For that, it needs enough bufferspace for the whole input, not only for its own region of interest. Thus, MALM must be the same size as the record INP is pointing to, 5000 (or 10000?) in your case. Then, subArray copies the interesting part into yet another buffer because of the way channel access only reads the bptr when connecting. All in all a huge waste of performance, but that's how it is at the moment.

Dirk

Zhichu Chen wrote:
Hi,

I've written a waveform support but I can't make it readable by other records,
so I wrote a soft one like this:
======================================================
static long read_wf(waveformRecord *pwf)
{
    CALLBACK *pcallback=(CALLBACK *)(pwf->dpvt);

    unsigned long i;
    long     BUFFER[10000];
    for (i = 0 ; i < 1500 ; i++) {
        BUFFER[i] = 10 + (i%2) ;
    }
    for (i = 1500 ; i < 4500 ; i++) {
        BUFFER[i] = 510 + (i%2) ;
    }
    for (i = 4500 ; i < 10000 ; i++) {
        BUFFER[i] = 10 + (i%2) ;
    }
    long     *pbuffer;


if(pwf->pact) { pbuffer = BUFFER ; pwf->nelm = pwf->nord = 5000; pwf->bptr = pbuffer; } else{ if(pwf->disv<=0) return(2); pwf->pact=TRUE; callbackRequestProcessCallbackDelayed( pcallback,pwf->prio,pwf,(double)pwf->disv); pwf->pact=TRUE; }

	return 0;
}
======================================================
and exported it to a device type as "SOFT" and wrote a db file like:
======================================================
record (waveform,   "wf") {
		field(FTVL, "LONG")
		field(SCAN, "1 second")
		field(NELM, "5000")
		field(DTYP, "SOFT")
}

record (subArray,   "sa") {
		field(INP,  "wf.VAL")
		field(SCAN, "1 second")
		field(FTVL, "LONG")
		field(MALM, "100")
		#field(INDX, "0")
		field(NELM, "100")
}
======================================================
the "wf" record gave a correct 5000 points emulated signal array but the "sa"
record just gave me 100 zeros. I've tried some combinations in the DB file like
some of you said it could be better to use "wf.VAL CA" in the INP field of "sa"
or "wf.VAL CP" etc., but I have no luck.

Then I think maybe the waveform support needs modification. So can any of
you give me some advice about how to write the correct waveform support.

By the way, I put another soft waveform record and the subArray could read it.
So basicly, it's not the problem of my EPICS release.


-- Dr. Dirk Zimoch Paul Scherrer Institut, WBGB/006 5232 Villigen PSI, Switzerland Phone +41 56 310 5182

Replies:
Re: Weird waveform behavior Zhichu Chen
Re: Weird waveform behavior Tim Mooney
References:
Weird waveform behavior Zhichu Chen

Navigate by Date:
Prev: unhandled exception in timerQueue Matthew Pearson
Next: Re: unhandled exception in timerQueue Matthew Pearson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Weird waveform behavior Geoff Savage
Next: Re: Weird waveform behavior Zhichu Chen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·