EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

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

Subject: Re: Record support and user-defined fields
From: Benjamin Franksen <[email protected]>
To: [email protected]
Date: Wed, 6 Jul 2005 14:14:08 +0200
On Tuesday 05 July 2005 20:06, Kay-Uwe Kasemir wrote:
> On Jul 1, 2005, at 18:48, Benjamin Franksen wrote:
> > See V4 Database Access -> V4 Design: Assembling Record Support
> What I don't understand is:
> How do you get process() to include processInvalidOutput() at the
> chosen time?
> Is that code manually written?

Yes, of course.

> Or is it generated, invoking all process<fieldname> routines
> in the order in which the fields are listed in the DBD file?

As I said before: The designer of a record type should have the ultimate 
control over what happens. Code of xxxRecord::process or 
yyyStruct::process is /never/ generated. It is completely impossible 
for a compiler or code generator to guess what the fields of a record 
type are for and how they should interact during processing.

The idea is that (manually) writing such a process routine is greatly 
simplified due to the existence of a large library of already defined 
components (structs+support). It may well be that some of those 
components will need to provide more than one interface routine, i.e. 
not only a simple process(). That depends on how complex the provided 
functionality is. New functionality will be factored out from new 
record types, and put into a struct/support module, so that other new 
record types can take advantage of it.

> > So how do you propose to associate the code that belongs to a
> > certain entension (and implements all this nice dynamic behavior)
> > with the extra field and the record support?
>
> As shown on the wiki page, 

Oops, I wasn't aware of this page, yet. Sorry. I'll take a look.

> you pick the field name, type, parameters 
> to the code and code itself when defining the record instance:
>
> calc("fred")
> {
>     ...
>     user_field(SMOO,  iocFloat64T, "0.5", smoo_handler)
> }

After taking a look at the wiki page, I understand how this is supposed 
to work. You want to use runtime database access to get at the record 
field that the extension wants to read and/or modify. So, which fields 
of the record get modified (or only read) is not a part of the public 
interface of the user field. This is clearly a possibility.

BTW, I take it that the actions performed in the user extension are 
strictly limited to synchronous ones, right?

The code you posted on the wiki handles only the cases you anticipate 
for usage. What if (for MAX and SMOO)

o no VAL field exists, or
o it exists but has not the expected type

All these conditions should be handled in your code.

Another thought: If runtime dbAccess is to go through DA, will we still 
have direct access to fields via a void*? I think not. Your code would 
have to use DA to access the VAL field.

So: inside your smoo_handler, you can only access fields of the record 
that are publicly available thriough dbAccess. Right? Wrong?

> The 'smoo_handler' is located just like device support etc. are
> located via the registry.

Ok.

> The user_field_handler interface has an init routine in which
> smoo_handler can hook into the record's process().

Ok.

> Pro:
> + I can add fields per record instance as needed.
>    I think it's easier for end users to grasp that
>    you have AI, AO, CALC records
>    plus 'average' and 'max' field that I can add to any of them,
>    than to present them with the 3x2=6 custom record types
>    BasicAI, MaxAI, AverageAI, AverageAndMaxAI, BasicAO, MaxAO, ...
> + Under vxWorks, I can do so without recompilation:
>    ld <smoo_handlerLib.o
>    dbLoadDataBase("..../records_that_use_smoo_handler")
>
> Contra:
> - For now, I only saw the necessity to provide process()-hooks in 2
> places.
>    When we need many more, your suggestion of re-writing process()
> and recompiling the whole record is better.
> - the user_field_handler::init() can check the user field type,
>    the record type etc. at runtime, but then you only see errors
>    at runtime.
>    With pre-defined records in the dbd file, more of that could
>    be handled at compile time.

I agree that with your current restrictions (two hooks, no blocking 
actions inside user-field code) user-defined fields are definitely 
manageable.

Nevertheless, I would add to the Contra list:

- While user-defined fields are easy to use, their code is harder to 
write and maintain: more runtime checks, more type casts, more 
boilerplate code.

Ben

Replies:
Re: Record support and user-defined fields Kay-Uwe Kasemir
References:
V4 iocRecord: forward linking Ralph Lange
Re: Record support and user-defined fields Benjamin Franksen
Re: Record support and user-defined fields Kay-Uwe Kasemir

Navigate by Date:
Prev: Re: again: memory management Benjamin Franksen
Next: Re: Record support and user-defined fields Kay-Uwe Kasemir
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Record support and user-defined fields Kay-Uwe Kasemir
Next: Re: Record support and user-defined fields Kay-Uwe Kasemir
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·