EPICS Home

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: EPICS base V4: iocCore database
From: Andrew Johnson <[email protected]>
To: Marty Kraimer <[email protected]>
Cc: [email protected]
Date: Tue, 22 Feb 2005 09:44:20 -0600
Marty Kraimer wrote:

Benjamin Franksen wrote:

(1) I don't think type BOOL is needed. We can use a MENU instead, e.g.

menu(menuBool) {
   choice(menuBoolFalse,"False")
   choice(menuBoolTrue,"True")
}

Perhaps bool is such a fundamental data type that we should support it?

Both the C++ and C99 standards committees decided that bool should be added to their respective languages and we need a way to be able to interface to their types anyhow. The problem with using a menu is that an IOC designer might think they're allowed to change the menu definition, such as swapping the order of the choices or adding extra onces. Trying that would reveal the hidden internal dependencies that exists - False must always be the first choice, and any extra choices will probably act as synonyms for True, but some code might not work with them. I'd rather just have a fundamental type for boolean values - there are fields in the current dbCommon that are defined as DBF_CHAR to minimize memory usage (note that ENUM/MENU are both currently 16 bits), but which are used to hold boolean values.

(2) The keyword "registrar" is obscure, IMO. Why not name it something like "function" (in accordance with keyword "variable")?

What about this and also variable. What do we want to do for V4?

A 'registrar' entry is used for any software that needs to be run at startup to register iocsh commands or perform other initialization. It implies a particular operation that the named function must perform, and also requires the function's signature be
	void registrar(void);
Note that the signature match is essential for use on Windows, which mangles the names. I would be willing to rename the keyword if someone comes up with a better one, but I don't think 'function' is correct for that - it implies something a lot more generic than a registrar function.

The 'variable' keyword is used to allow the named variables, usually debug variables, to be accessed (set) by the iocsh.

(3) record support's special

Marty and I discussed this, and we agree that it could be better. We think the best solution would be to require the special routine itself to be responsible for putting the value into the field; the pass argument would go away, and instead the special routine be given the dbAddr specifying the field and the value it's to be set to. We also removed the argument from the field attribute special - if the field belongs to dbCommon the core libraries are responsible for doing the special processing, otherwise the record support will be called instead.

(4) include "filename": At the moment it is used for two purposes:

(a) At the beginning of a record type declaration. This is poor man's inheritance. It can be replaced by *naming a struct or record type* to be included at this point. (The same goes for the new 'struct'). Like this:

struct(dbCommon) {
   fields...
}

record(name) {
   inherit "dbCommon"
   fields...
}

The "inherited" part can be declared in the same file, or imported from another one (see (b) below).

Something very like this idea could be implemented using the new struct definition without any changes:

struct(dbCommon) {
  fields ...
}

record(name) {
  field(all, struct(dbCommon))
}

However this does move all the dbCommon fields inside the 'all' field (or whatever name we pick): xxx:yyy.all.scan etc. I don't really like that very much. It might be intersting if we wanted split up dbCommon into different subsystems, so there'd be a scan struct (scan, pini, phas, evnt, disv, disa, diss, sdis, proc), a monitor struct (mlok, mlst), an alarm struct (stat, sevr, nsta, nsev, ...) etc. However I'm not completely sure of the advantage of this yet other than code modularity.

The same mechanism can be used for menus.

The idea of having an inheritance mechanism is interesting, and I think it would be relatively easy to implement for records, structs and menus. However I want to put my stamp on it (of course!). I think the keyword would be better outside of the braces, maybe like this:

struct(dbCommon) {
  fields ...
}

record(calc) extends(dbCommon) {
  fields ...
}

record(calcOut) extends(calc) {
  fields ...
}

What actually happens inside the parser is that the child gets created by copying the complete definition of the parent object, rather than from scratch. Note that I'm allowing a record to inherit from a struct above, I think that's probably a reasonable thing to do. However the DBD file is as far as the inheritance would go, the record support routines would be on their own. Maybe we should ensure that calcOut can find and call calc's support routines relatively easily, but we haven't really thought about this properly - I'm just saying at this stage that we could do the above textual inheritance if we want to. The same syntax would work for menus:

menu(menuScanBasic) {
  choice(menuScanPassive, "Passive")
  choice(menuScanEvent,"Event")
  choice(menuScanI_O_Intr, "I/O Intr")
}

menu(menuScan) extends(menuScanBasic) {
  choice(menuScan10Second,"10 second")
  ...
}


(b) At the top-level: This is poor man's modularization. But complete textual inclusion is often too coarse. I propose a limited form of module import (allowed only at the top-level):

import <module-name> (<element-name>, ...)

for element-wise import (i.e. only the listed names are imported) or

import <module-name> [ hiding (<element-name>, ...) ]

for importing everything, where the optional 'hiding' clause can be used to list names that should not be imported. <module-name> would be the filename of the imported module without the extension.

I don't see any advantage of providing import like that, and do see lots of disadvantages - DBD files are not an attempt at being able to create any kind of data structure, and it would require us to store significantly more meta-data than we currently do - what elements come from which file, what the hiding scope is of each name (not least how do we convert name hiding into equivalent C code, and what the search path is to a name in any particular context).

The advantage of the include technique that we're currently using is that it's actually pretty simple to code and understand. There is no need to remember which file a definition came from or its scope.

Unless you can explain what this permits us to accomplish that we couldn't with the much simpler textual inclusion, I see no point is spending more time on implementing something that we need to.

- Andrew
--
Dear God, I didn't think orange went with purple until I saw
the sunset you made last night.  That was really cool. - Caro



Replies:
Re: EPICS base V4: iocCore database: Booleans Benjamin Franksen
Re: EPICS base V4: iocCore database: registrar, special Benjamin Franksen
Re: EPICS base V4: iocCore database: include/extend/expand Benjamin Franksen
References:
Re: EPICS base V4: iocCore database Marty Kraimer

Navigate by Date:
Prev: Re: EPICS base V4: iocCore database Benjamin Franksen
Next: RE: [Fwd: RE: EPICS base V4: iocCore database] Jeff Hill
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: EPICS base V4: iocCore database Benjamin Franksen
Next: Re: EPICS base V4: iocCore database: Booleans Benjamin Franksen
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024