EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: write to a single element of an array field
From: Ralph Lange via Core-talk <core-talk at aps.anl.gov>
To: EPICS Core Talk <core-talk at aps.anl.gov>
Date: Wed, 18 Mar 2020 13:59:08 +0100
Very nice summary - couldn't have said it better.
Your approach sounds right, too.

Note, however, that the requirements and user interface for the array-on-write filter are not obvious and trivial.

In the implemented read/monitor case, the input is an array, the configuration defines a subset of that input array, and the output is an array that consists of that subset.

On write, does the configuration define which subset of the source is written to the target?
Or does it rather define what part of the target array the source array is being written to?
I think both operations do have valid use cases.

It might be fine to require an additional record instance in some cases, especially for the combination, i.e., writing a well-defined subset of the input array into a well-defined part of the output array.

Cheers,
~Ralph


On Wed, 18 Mar 2020 at 13:36, Ben Franksen via Core-talk <core-talk at aps.anl.gov> wrote:
Hi Ralph, Andrew & whoever else is interested

I am writing this up so you can correct any mistakes in my understanding.

I think I found the missing link (pun, haha) by greping for 'static lset':

> grep 'static lset.*=' *
dbCa.c:static lset dbCa_lset = {
dbConstLink.c:static lset dbConst_lset = {
dbDbLink.c:static lset dbDb_lset = {

That makes sense. These are the three "internal" link types: CONSTANT,
DB, and CA.

(For the following, note that I am working on a version with Dirk's
patches applied.)

Looking at the definitions for dbDb_lset I find that the relevant c
functions are dbGetValue and dbPutValue in dbDbLink.c. I guess what
needs to be done to support filters on put (for DB links) is to change
dbPutValue. Looking at what dbGetValue does I see that two chains of
filters are applied before we finally get the actual value:

        pfl = dbChannelRunPreChain(chan, pfl);
        pfl = dbChannelRunPostChain(chan, pfl);
        status = dbChannelGet(chan, dbrType, pbuffer, NULL, pnRequest, pfl);

This looks a bit mysterious at first: why distinguish Pre and Post
chains when all we do is run them one after the other? Then I found
these comments in the dbChannel.h:

    ELLLIST pre_chain;        /* list of filters to be called
pre-event-queue */
    ELLLIST post_chain;       /* list of filters to be called
post-event-queue */

and indeed the implementation for CA links makes it clear that the pre
chain is run before we call db_post_events, while the post chain is run
when we take things out of the event queue. Again, this makes sense. DB
links aren't queued, so we ignore the distinction and simply run both
chains one after the other.

The next question is what to do about the "pfl" thing i.e. the
db_field_log that gets threaded through the filters. Currently, a
db_field_log is created by one of db_create_event_log or
db_create_read_log. This suggests I need to add some
db_create_write_log, which in turn suggests a new member to enum
dbfl_context i.e.

typedef enum dbfl_context {
    dbfl_context_read = 0,
    dbfl_context_event,
    dbfl_context_write
} dbfl_context;

Searching for code that makes case distinctions depending on the
dbfl_context_*, I see only a few uses in the existing filters:

../../std/filters/decimate.c:    if (pfl->ctx == dbfl_context_read)
../../std/filters/decimate.c-        return pfl;
../../std/filters/sync.c:    if (pfl->ctx == dbfl_context_read)
../../std/filters/sync.c-        return pfl;

I think it makes sense to document this in filters.dbd.pod. Indeed, some
of the filters make sense only in certain contexts. We currently apply
the "Synchronize" and "Decimate" filters only in the event context. I am
not sure if applying "Deadband" and "Sync" make sense in read contexts,
but I won't make any guesses here and keep the code as is, leaving it to
others to review this. Anyway, none of the existing filters except
"Array" seem to make much sense in a write context, so I will update the
existing filters accordingly.

So much for now.

Cheers
Ben

Replies:
Re: write to a single element of an array field Johnson, Andrew N. via Core-talk
Re: write to a single element of an array field Ben Franksen via Core-talk
References:
Re: write to a single element of an array field Ben Franksen via Core-talk

Navigate by Date:
Prev: Re: write to a single element of an array field Ben Franksen via Core-talk
Next: Jenkins build is back to normal : epics-base-7.0-win64 #106 APS Jenkins via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
Navigate by Thread:
Prev: Re: write to a single element of an array field Ben Franksen via Core-talk
Next: Re: write to a single element of an array field Johnson, Andrew N. via Core-talk
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
ANJ, 18 Mar 2020 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·