Difference between revisions of "V4 Design: dbdClass"

From EPICSWIKI
Line 1: Line 1:
= EPICS: dbdClasses - IOC record =
= EPICS: dbdClasses - IOC record =
May 27 2005  
June 1 2005  


----
<center>
<center>


Line 35: Line 36:
: A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.
: A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.


=== <tt>dbdTypes.h</tt> ===
=== <tt>dbfTypes.h</tt> ===
  enum dbfType {
  enum dbfType {
     dbfUnknownT,
     dbfUnknownT,
Line 45: Line 46:
     dbfLinkT,
     dbfLinkT,
     dbfDeviceT
     dbfDeviceT
    dbfMDArrayT
  };
  };


Line 57: Line 59:
  };
  };


// Note that EpicsStruct:EpicsStructDef is an DbdStructDef
  class DbfStruct : public EpicsStruct {
  class DbfStruct : public EpicsStruct {
  public:
  public:
Line 94: Line 95:
     DbdDevice *pDbdDevice;
     DbdDevice *pDbdDevice;
     EpicsStruct dataStruct;
     EpicsStruct dataStruct;
};
class DbfMDArray : public EpicsMDArray {
public:
  };
  };


Line 106: Line 111:
DBD types bool,...,string all become an epicsType.
DBD types bool,...,string all become an epicsType.


DBD type array becomes an EpicsArray if the array type maps to an epicsType
DBD type array becomes an EpicsArray if the array type is not
or to DbfArray if the type is not an epicsType.
<tt>epicsUnknownT</tt>. Otherwise it maps to DbfArray.
 
DBD type struct maps to EpicsStruct if no field in the struct is epicsUnknownT.
Otherwise ir maps to DbfStruct.


DBD type struct maps to EpicsStruct if no field in the struct is epicsUnknownT;
otherwise to DbfStruct.


If a record is defined as:
If a record is defined as:
Line 128: Line 134:
         field(displayLimits,struct(displayLimits))
         field(displayLimits,struct(displayLimits))
     }
     }
Then the generated header file will be
Then the generated header file will be
     class xxxRecord : public iocRecord {
     class xxxRecord : public iocRecord {
Line 144: Line 151:
====  DbfArray ====
====  DbfArray ====


This is for array fields with a type that is not a standard epicsType.
This is for array fields with a type <tt>epicsUnknownT</tt>.
DbfArray provides the dbfType.


If a record definition contains:
If a record definition contains:


     struct(calcInpLink) {
     struct(calcInpLink) {
         field(link,link(in))      // NOT a standard epicsType
         field(link,link(in))      // epicsType is epicsUnknownT
         field(value,float64)
         field(value,float64)
     }
     }
Line 164: Line 172:
====  DbfStruct ====
====  DbfStruct ====


This is for a struct field that itself has fields that are not a standard epicsType, i.e. the epicsType is epicsUnknownT.
This is for a struct field with at least one field of type <tt>epicsUnknownT</tt>.


If a record definition contains:
If a record definition contains:


     struct(calcInpLink) {
     struct(calcInpLink) {
         field(link,link(in))    // NOT a standard epicsType
         field(link,link(in))    // epicsType is epicsUnknownT
         field(value,float64)
         field(value,float64)
     }
     }
Line 180: Line 188:
Then the generated code contains:
Then the generated code contains:


     DbfArray inp;
     DbfStruct inp;
      
      


Line 202: Line 210:
     public:
     public:
         epicsInt16  index;
         epicsInt16  index;
         DbfArray *pchoiceArray; // addr of field that is DbfArray on choices
         EpicsArray *pchoiceArray; //EpicsArray of epicsStringT
     };
     };


Line 209: Line 217:
Then the generated header file contains
Then the generated header file contains
     DbfEnum fenum;
     DbfEnum fenum;
<tt>pchoiceArray</tt> is the address of a field in the same record that is a
<tt>pchoiceArray</tt> is the address of a field in the same record that is an
DbfArray of choices.
EpicsArray of type epicsStringT. It contains the choices.
==== DbfLink ====
==== DbfLink ====
<tt>DbfLink</tt> is described as
<tt>DbfLink</tt> is described as
Line 253: Line 261:




// Interface is base class for an interface
  class Interface {}; // Must be an interface, i.e. pure abstract class
  class Interface {};
class InterfaceLocator {
public:
    EpicsString name;
    Interface *pinterface;
};


  class DbdStructFieldAttribute {
  class DbdFieldAttribute {
  public:
  public:
     EpicsString  default;
     EpicsString  default;
Line 268: Line 270:
     epicsBoolean special;
     epicsBoolean special;
     epicsBoolean dynamic;
     epicsBoolean dynamic;
     epicsInt16 asl;
     epicsInt16   asl;
};
 
class DbdField : public EpicsStructField {
public:
    dbfType          dbftype;
    DbdFieldAttribute attribute;
  };
  };


  class DbdStructField : public EpicsStructField {
  class DbdStruct : public EpicsStructDef{ // describes a struct
  public:
  public:
     dbfType    dbftype;
     NODE              node; // for DbdStructList
    DbdStructFieldAttribute attribute;
  };
  };


  class DbdStructDef : public EpicsStructDef{
  class DbdRecord : public EpicsStructDef { // describes a record
  public:
  public:
     NODE              node; // for DbdStructDefList
     NODE              node; // for DbdRecordList
    LIST              instanceList;
    DbdRecordSupport  *psupport;
  };
  };


  class DbdMenu{
  class DbdMenu{
  public:
  public:
    NODE        node; // for DbdMenuList
     EpicsString name;
     EpicsString name;
     epicsInt16  nchoices;
     epicsInt16  nchoices;
Line 291: Line 301:
  class DbdLink{ //describes dbd link statement
  class DbdLink{ //describes dbd link statement
  public:
  public:
     NODE        node; // For DbdLinkList.linkList
     NODE        node; // For DbdLinkList
     LinkDir      dir;
     LinkDir      dir;
     EpicsString  choiceName;
     EpicsString  choiceName;
Line 300: Line 310:
  class DbdDevice { //describes dbd device statement
  class DbdDevice { //describes dbd device statement
  public:
  public:
     NODE        node; // For linkList.deviceList
     NODE        node; // For linkList
     LinkDir    dir;
     LinkDir    dir;
     EpicsString choiceName;
     EpicsString choiceName;
Line 314: Line 324:
     epicsType  type;
     epicsType  type;
     EpicsString dataStructName;
     EpicsString dataStructName;
};
     DbdUserFieldHandler *pinterface;
 
// The following describes a record type
class DbdRecordDef : extends EpicsStructDef { // describes a record type
public:
     NODE              node; // for DbdRecordList.recordType
    LIST              instanceList;
    DbdRecordSupport  *psupport;
  };
  };


Line 330: Line 333:
     EpicsString  name; // field name
     EpicsString  name; // field name
     DbdUserField *pDbdUserField;
     DbdUserField *pDbdUserField;
    DbdUserFieldHandler *pinterface;
     void        *pstorage; // for DbdUserField.type
     void        *pstorage; // for DbdUserField.type
     EpicsStruct  dataStruct;
     EpicsStruct  dataStruct;
  };
  };


// Note that EpicsStruct:EpicsStructDef is an DbdRecordDef
  class DbdRecordInstance : extends EpicsStruct {
  class DbdRecordInstance : extends EpicsStruct {
  public:
  public:
     NODE        node; // for DbdRecord.instanceList;
     NODE        node; // for DbdRecord.instanceList
     EpicsString  name;
     EpicsString  name;
     LIST        userField; // of DbdUserFieldInstance
     LIST        userField; // of DbdUserFieldInstance
Line 344: Line 345:




  class DbdStructDefList {
  class DbdStructList {
  public:
  public:
     LIST structType;
     LIST list;
  };
  };


  class DbdRecordDefList {
  class DbdRecordList {
  public:
  public:
     LIST recordType;
     LIST list;
};
 
class DbdMenuList {
public:
    LIST list;
  };
  };


  class DbdLinkList {
  class DbdLinkList {
  public:
  public:
     LIST linkList;
     LIST list;
  };
  };


  class DbdDeviceList {
  class DbdDeviceList {
  public:
  public:
     LIST deviceList;
     LIST list;
  };
  };


  class DbdUserFieldList {
  class DbdUserFieldList {
  public:
  public:
     LIST userFieldList;
     LIST list;
  };
  };




=== Discussion of dbdStatements ===
=== Discussion of dbdStatements ===
==== DbdStruct ====
==== struct and record ====
The DbdStruct classes describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition. The classes are : <tt>DbdStruct</tt>, <tt>DbdStructField</tt>,and <tt>DbdStructFieldAttribute</tt>
The following classes describe the fields in a dbd <tt>struct</tt> or <tt>record</tt> definition: <tt>DbdStruct</tt>, <tt>DbdRecord</tt>, <tt>DbdField</tt>,and <tt>DbdFieldAttribute</tt>


The fields of <tt>DbdStruct</tt> are:
The fields of <tt>DbdStruct</tt> are:
Line 378: Line 384:
: The name of the struct.
: The name of the struct.
; <tt>plifetime</tt>
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>StructLifetime</tt> or <tt>DbdRecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt> or <record> statement. See below for a description of the Lifetime methods.
: The address of an implementation of interface <tt>DbdStructLifetime</tt>. The implementation is automatically generated from the dbd <tt>struct</tt>. See below for a description of the Lifetime methods.
; <tt>nfields</tt>
; <tt>nfields</tt>
: The number of fields, e.g. fields in the structure.
: The number of fields, e.g. fields in the structure.
; <tt>pfields</tt>
; <tt>pfields</tt>
: pointer to an array of pointers to <tt>DbdStructField</tt>.
: pointer to an array of pointers to <tt>DbdField</tt>.
; <tt>node</tt>
: A node for the list of struct definitions


The fields of <tt>DbdStructField</tt> are:
The fields of <tt>DbdRecord</tt> are;
; <tt>name</tt>
: The name of the record type.
; <tt>plifetime</tt>
: The address of an implementation of interface <tt>DbdRecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the Lifetime methods.
; <tt>nfields</tt>
: The number of fields, e.g. fields in the record.
; <tt>pfields</tt>
: pointer to an array of pointers to <tt>DbdField</tt>.
; <tt>node</tt>
: A node for the list of record definitions
; <tt>node</tt>
: This is a node for <tt>DbdRecordList</tt>
; <tt>instanceList</tt>
: The list of record instances of this record type.
; <tt>psupport</tt>
: The address of the <tt>DbdRecordSupport</tt> for this record type.
 
 
The fields of <tt>DbdField</tt> are:
; <tt>name</tt>
; <tt>name</tt>
: The name of the field
: The name of the field
; <tt>basic</tt>
: The epicsType of the field. Unless this is epicsUnknownT generic code is usually provided for accessing the field.
; <tt>type</tt>
; <tt>type</tt>
: The dbfType for the field. Unless basic is epicsUnknownT this has the value dbfEpicsT.
: The epicsType, which is always <tt>epicsUnknownT</tt>
; <tt>dbftype</tt>
: The dbfType of the field.
; <tt>attribute</tt>
; <tt>attribute</tt>
: An DbdStructFieldAttribute for the field
: DbdFieldAttribute for the field


<tt>DbdStructFieldAttribute</tt> has the attribute values for the field.
The fields of <tt>DbdFieldAttribute</tt> are:
; <tt>default</tt>
: An EpicsString providing a default value for the field.
; <tt>readonly</tt>
: Is the field readonly?
; <tt>design</tt>
: Is the field a design fields for DCTs?
; <tt>special</tt>
: Should DbdRecordSupport:special be called if the field is modified.
; <tt>dynamic</tt>
: Can the field change because of record processing?
; <tt>asl</tt>
: The access security level.


==== Menu ====
==== Menu ====
Line 416: Line 455:
: The link direction
: The link direction
; <tt>choiceName</tt>
; <tt>choiceName</tt>
: The name that matches a DbdLink for a DbfLink instance.
: The name that connects a DbdLink to a DbfLink instance.
; <tt>dataStructName</tt>
; <tt>dataStructName</tt>
: The class name of a DbfStruct for the Interface implementation
: The class name of an EpicsStruct for the Interface implementation
; <tt>pinterface</tt>
; <tt>pinterface</tt>
: The address of the Interface implementation. The interface class is DbdLinkSupport
: The address of the DbdLinkSupport Interface implementation.


==== Device ====
==== Device ====
Line 430: Line 469:
: The link direction
: The link direction
; <tt>choiceName</tt>
; <tt>choiceName</tt>
: The name that matches a DbdDevice for a DbfDevice instance.
: The name that matches a DbdDevice to a DbfDevice instance.
; <tt>dataStructName</tt>
; <tt>dataStructName</tt>
: The class name of a DbfStruct for the Interface implementation
: The class name of an EpicsStruct for the Interface implementation
; <tt>interfaceName</tt>
; <tt>interfaceName</tt>
: The name of the interface class implemented by the device support
: The name of the interface type implemented by the device support
; <tt>pinterface</tt>
; <tt>pinterface</tt>
: The address of the Interface implementation.
: The address of the Interface implementation.


==== Record ====
 
A record type has an associated class: <tt>DbdRecord</tt>.
==== User Defined Fields ====
The fields of <tt>DbdRecord</tt> are the same as fields in <tt>DbdStruct</tt> except that they refer to a record instead of a structure.
 
Each dbd <tt>userField</tt> definition has an associated class <tt>DbdUserField</tt> with fields:
; <tt>node</tt>
; <tt>node</tt>
: This is a node for <tt>DbdRecordList</tt>
: This is a node for <tt>DbdUserFieldList</tt>
; <tt>instanceList</tt>
; <tt>choiceName</tt>
: The list of record instances of this record type.
: The name that matches a DbdUserField to a DbdUserFieldInstance
; <tt>name</tt>
; <tt>type</tt>
: The name of the record type.
: The epicsType for the user field
; <tt>plifetime</tt>
; <tt>dataStructName</tt>
: The address of an implementation of interface <tt>DbdRecordLifetime</tt>. The implementation is automatically generated from the dbd <tt>record</tt> statement. See below for a description of the <tt>RecordLifetime</tt> methods.
: The class name of an EpicsStruct for the DbdUserFieldHandler
; <tt>psupport</tt>
; <tt>pinterface</tt>
: The address of the <tt>DbdRecordSupport</tt> for this record type.
: The address of the DbdUserFieldHandler implementation.
; <tt>nfields</tt>
: The number of fields, e.g. fields in the record.
; <tt>pfields</tt>
: pointer to an array of pointers to <tt>DbdStructField</tt>. Each DbdStructField contains the name and type of the fields.
 


==== Record Instance ====
==== Record Instance ====
Line 465: Line 500:
: A node for list <tt>DbdRecordInstance.userField</tt>
: A node for list <tt>DbdRecordInstance.userField</tt>
; <tt>name</tt>
; <tt>name</tt>
: The name of the user defined field
: The name of the user defined field, i.e. the psuedo field name
; <tt>type</tt>
; <tt>pDbdUserField</tt>
: The dbfType for the field.
: The DbdUserField that describes the field
; <tt>pfield</tt>
; <tt>pstorage</tt>
: Address of storage for field.
: Address of storage for the dbfType.
; <tt>pinterface</tt>
; <tt>dataStruct</tt>
: The address of an implementation of interface userFieldHandler;
: An EpicsStruct that holds the private data for the DbdUserFieldHandler.


The fields of <tt>DbdRecordInstance</tt> are:
The fields of <tt>DbdRecordInstance</tt> are:


; <tt>pstructDef</tt>
: address of the DbdRecord describing the record
; <tt>pstorage</tt>
; address of the storage for the record instance
; <tt>node</tt>
; <tt>node</tt>
: A node for list <tt>DbdRecord.instanceList</tt>
: A node for list <tt>DbdRecord.instanceList</tt>
; <tt>name</tt>
; <tt>name</tt>
: The name of the record instance
: The name of the record instance
; <tt>pDbdRecord</tt>
: The address of the description of the record type
; <tt>precord</tt>
: The address of the storage for the record instance.
; <tt>userField</tt>
; <tt>userField</tt>
: A DbdUserFieldInstance list for the record instance.
: A DbdUserFieldInstance list for the record instance.


=== DbdStructList ===
==== Lists ====
 
A list of all the struct definitions. The nodes are described by <tt>DbdStructNode</tt> which has fields:
 
; <tt>node</tt>
: The node for the list.
; <tt>isEpicsType<tt>
: determines if the structure is a EpicsStructDef or a DbdStruct
; <tt>pdef</tt>
: The address of the <tt>EpicsStructDef<tt> or <tt>Db<tt> that describes the structure.
 
=== DbdRecordList ===
 
The list of record types
 
=== DbdLinkList ===


List of <tt>DbdLink</tt>
The following provide lists of various things:


=== DbdDeviceList ===
; <tt>DbdStructList</tt>
 
: The list of each struct definition
List of <tt>DbdDevice</tt>
; <tt>DbdRecordList</tt>
: The list of each record type definition
; <tt>DbdMenuList</tt>
: The list of each menu definition
; <tt>DbdLinkList</tt>
: The list of each link definition
; <tt>DbdDeviceList</tt>
: The list of each device definition
; <tt>DbdUserFieldList</tt>
: The list of each userField definition


----
----
Line 523: Line 552:


  // The following is implemented by database access
  // The following is implemented by database access
  class DbdRecordEpicsFieldPutString {
  class DbdFieldPutString {
     virtual void epicsPrimitive(EpicsString *pfrom, epicsType type,
     virtual void primitive(EpicsString *pfrom, epicsType type,
                               void *pstorage) = 0;
                               void *pstorage) = 0;
     virtual void epicsString(EpicsString *pfrom,
     virtual void string(EpicsString *pfrom,
                               EpicsString *pEpicsString) = 0;
                               EpicsString *pEpicsString) = 0;
     virtual void epicsArray(EpicsString *pfrom,
     virtual void array(EpicsString *pfrom,
                               EpicsArray *pEpicsArray) = 0;
                               EpicsArray *pEpicsArray) = 0;
     virtual void epicsStruct(EpicsString *pfrom,
     virtual void epicsStruct(EpicsString *pfrom,
Line 544: Line 573:
  };
  };


  // For record definitions an DbdRecordLifetime is automatically generated.
  // For record definitions a DbdRecordLifetime is automatically generated.
  class DbdRecordLifetime : public EpicsStructLifetime{
  class DbdRecordLifetime : public EpicsStructLifetime{
  public:
  public:
Line 551: Line 580:
  };
  };


  // every link support module implements the following interface
  // link support modules implement the following interface
  class DbdLinkSupport {
  class DbdLinkSupport {
  public:
  public:
     virtual void report(EpicsString *errorMessage,
     virtual void report(iocRecord *precord, DbfLink *pdbfLink) = 0;
                      iocRecord *precord, DbfLink *pdbfLink) = 0;
     virtual bool initialize(EpicsString *errorMessage,
     virtual bool initialize(EpicsString *errorMessage,
                      iocRecord *precord, DbfLink *pdbfLink) = 0;
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
     virtual bool finalize(EpicsString *errorMessage,
     virtual bool finalize(EpicsString *errorMessage,
                      iocRecord *precord, DbfLink *pdbfLink) = 0;
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
     virtual bool connect(EpicsString *errorMessage,
     virtual bool connect(EpicsString *errorMessage,
                      iocRecord *precord, DbfLink *pdbfLink) = 0;
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
     virtual bool disconnect(epicsfString *errorMessage,
     virtual bool disconnect(EpicsString *errorMessage,
                      iocRecord *precord, DbffLink *pdbfLink) = 0;
                    iocRecord *precord, DbffLink *pdbfLink) = 0;
     virtual bool get(EpicsString *errorMessage,
     virtual bool get(EpicsString *errorMessage,
                      iocRecord *precord, DbffLink *pdbfLink,
                    iocRecord *precord, DbffLink *pdbfLink,
                      dbfType type, void *pfield) = 0;
                    epicsType type, void *pfield) = 0;
     virtual bool put(EpicsString *errorMessage,
     virtual bool put(EpicsString *errorMessage,
                       iocRecord *precord, DbfLink *pdbfLink,
                       iocRecord *precord, DbfLink *pdbfLink,
                       dbfType type, void *pfield) = 0;
                       epicsType type, void *pfield) = 0;
  };
  };


Line 578: Line 606:
     virtual bool initConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
     virtual bool initConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
     virtual bool breakConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
     virtual bool breakConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool process(DbdRecordInstance *pDbdRecordInstance) = 0;
     virtual void special(DbdRecordInstance *pDbdRecordInstance,
     virtual void special(DbdRecordInstance *pDbdRecordInstance,
             bool  after,
             bool  after,
Line 597: Line 626:
=== Discussion of dbdInterfaces ===
=== Discussion of dbdInterfaces ===


=== <tt>DbdRecordEpicsFieldPutString</tt> ===
=== <tt>DbdFieldPutString</tt> ===


This is an interface, which has an implementation provided by iocCore,
This is an interface, which has an implementation provided by iocCore,
that convert an <tt>EpicsString</tt> to an epicsType.
that convert an <tt>EpicsString</tt> to an epicsType.
The methods are:
The methods are:
; <tt>epicsPrimitive</tt>
; <tt>primitive</tt>
: This convert a string to one of the types: <tt>epicsBoolT</tt>, ..., <epicsFloat64T</tt>
: This convert a string to one of the types: <tt>epicsBoolT</tt>, ..., <epicsFloat64T</tt>
; <tt>epicsString</tt>
; <tt>string</tt>
: Copies a string from pfrom to pEpicsString.
: Copies a string from pfrom to pEpicsString.
; <tt>epicsArray</tt>
; <tt>array</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:epicsPrimitive or EpicsString:epicsString to convert the value and put it into the correct element of <tt>EpicsArray</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:primitive or EpicsString:string to convert the value and put it into the correct element of <tt>EpicsArray</tt>
; <tt>epicsStruct</tt>
; <tt>epicsStruct</tt>
: Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls epicsPrimitive, epicsString, or epicsArray to convert the value and put the result of the correct field of <tt>EpicsStruct</tt> The structure must not contain any unknown field types.
: Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of <tt>EpicsStruct</tt> The structure must not contain any unknown field types.
; <tt>epicsMDArray</tt>
; <tt>epicsMDArray</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:epicsPrimitive or EpicsString:epicsString to convert the value and put it into the correct element of <tt>EpicsMDArray</tt>
: Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:primitive or EpicsString:string to convert the value and put it into the correct element of <tt>EpicsMDArray</tt>
==== <tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> ====
=== <tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> ===
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation. A tool is provided that automatically generates the implementation form the dbd definition.
Every dbd <tt>struct</tt> and <tt>record</tt> has an associated Lifetime interface implementation.
A tool is provided that automatically generates the implementation from the dbd definition.


Lifetime has the following fields:
<tt>DbdStructLifetime</tt> and <tt>DbdRecordLifetime</tt> each has the following fields:
; <tt>allocate</tt>
; <tt>allocate</tt>
: Creates storage for the struct or record.
: Creates storage for the struct or record.
; <tt>destroy</tt>
: frees storage
; <tt>exposeField</tt>
: Given an index it returns the address of the storage for the field. Note the the generated header files assign an index to each field.
; <tt>initialize</tt>
; <tt>initialize</tt>
: initializes the struct or record
: initializes the struct or record
; <tt>finalize</tt>
; <tt>finalize</tt>
: cleans up but does not free storage
: cleans up but does not free storage
; <tt>destroy</tt>
: frees storage
; <tt>expose</tt>
: Given an index it returns the address of the storage. Note the the generated header files assign an index to each field.


==== <tt>DbdLinkSupport</tt> ====
=== <tt>DbdLinkSupport</tt> ===
This describes the interface implemented by link support.
 
==== <tt>DbdRecordSupport</tt> ====
This is the interface implemented by the support associated with each DBD link.
This is the interface implemented by record support.
 
==== <tt>UserFieldHandler</tt> ====
<tt>DbdLinkSupport</tt> has the following methods:
; <tt>report</tt>
: generate a report about the link instance
; <tt>initialize</tt>
: perform initialization but do not connect
; <tt>finalize</tt>
: undo initialization. It is assumed that disconnect has already been called.
; <tt>connect</tt>
: connect to external source of data
; <tt>disconnect</tt>
: disconnect from external source of data
; <tt>get</tt>
: get a value from the external source. <tt>type</tt> specified the field type and <tt>pfield</tt> is the address of where to store the data.
; <tt>put</tt>
: put a value from the external source. <tt>type</tt> specified the field type and <tt>pfield</tt> is the address of where to obtain the data.
=== <tt>DbdRecordSupport</tt> ===
 
This is the interface implemented by each record support module.
<tt>DbdRecordSupport</tt> has the following methods:
 
; <tt>initBuffers</tt>
: This is called during record initialization. It is responsible for creating the buffers associated with each string and array field. It may call associated support to do the initialization.
; <tt>initConnections</tt>
: This is called to connect to external sources.  It may call associated support to make the connections.
; <tt>breakConnections</tt>
: This is called to disconnect to external sources.  It may call associated support to break the connections.
; <tt>process</tt>
: Process the record.
; <tt>special</tt>
: This is called whenever an external source modifies a field with attribute special set to true.
 
 
=== <tt>DbdUserFieldHandler</tt> ===
This is the interface implemented by code for user extensible fields.
This is the interface implemented by code for user extensible fields.


<tt>DbdUserFieldHandler</tt> has the following fields:
; <tt>initialize</tt>
: Initialize the user field.
; <tt>finalize</tt>
: undo what was done during initialization
; <tt>process</tt>
: Called near the end of record processing just before monitors are handled.
=== Device Support Interfaces ===
Multiple interface definitions for device support will be defined.
Record Support and device support must agree on which interface type
is used for communication.
----
----

Revision as of 19:20, 1 June 2005

EPICS: dbdClasses - IOC record

June 1 2005


Overview

This document describes the C++ class definitions for code that implements the semantics for records created from Database Definitions. The definitions are intended for code that:

  • includes header files generated from dbd definitions. Header files are generated from the following dbd definitions:
    • record - Should only be included by record support.
    • struct - Included by code that understands the struct.
    • menu - Included by code that understands the menu.
  • does not include the header files.

The following headers files are described:

  • dbfTypes.h - Type definitions for field definitions in struct or record> DBD definitions.
  • dbdStatements.h - Type definitions for DBD statements.
  • dbdInterfaces.h - Type definitions for interfaces related to DBD definitions.

dbfTypes

File dbfTypes.h describes types and classes that are used in header files generated from dbd struct or record field definitions. The following naming conventions are used:

Dbf
any class starting with Dbf describes a field in a generated header file. For example DbfString describes a field generated from field(name,string).
Dbd
A class name starting with Dbd describes something related to dbd definitions. For example DbdLinkSupport describes a dbd link definition.

dbfTypes.h

enum dbfType {
    dbfUnknownT,
    dbfEpicsT,  // an epicsType except epicsUnknownT
    dbfArrayT,
    dbfStructT,
    dbfMenuT,
    dbfEnumT,
    dbfLinkT,
    dbfDeviceT
    dbfMDArrayT
};
class DbdStruct; //describes a dbd struct definition
class DbdMenu; //describes a dbd menu definition
class DbdLink;    //describes dbd link statement
class DbdDevice;  //describes dbd device statement
class DbfArray : public EpicsArray {
public:
    dbfType dbftype;
};
class DbfStruct : public EpicsStruct {
public:
};
class DbfMenu{
public:
    epicsInt16 index;
    DbdMenu    *pmenuDef; /* address of global menu */
};
class DbfEnum{
public:
    epicsInt16 index;
    EpicsArray *pchoiceArray; // addr of field that is array of string
};

enum LinkDir {
    LinkDirNone,
    LinkDirForward,
    LinkDirIn,
    LinkDirOut,
    LinkDirInOut
};
class DbfLink{ 
public:
    LinkDir   dir;
    DbdLink   *plinkDef;
    EpicsStruct dataStruct;
};
class DbfDevice{
public:
    LinkDir   dir;
    DbdDevice *pDbdDevice;
    EpicsStruct dataStruct;
};
class DbfMDArray : public EpicsMDArray {
public:
};

Discussion of dbfTypes

The classes defined in dbfTypes together with the definitions from epicsTypes is a complete list of the definitions that appear in header files generated from struct and record dbd definitions.

Epics Types

DBD types bool,...,string all become an epicsType.

DBD type array becomes an EpicsArray if the array type is not epicsUnknownT. Otherwise it maps to DbfArray.

DBD type struct maps to EpicsStruct if no field in the struct is epicsUnknownT. Otherwise ir maps to DbfStruct.


If a record is defined as:

    struct(displayLimits) {
        field(low,double)
        field(high,double)
    }
    record(xxx) extends iocRecord {
        ...
        field(fbool,bool)
        field(foctet,octet)
        ...
        field(ffloat64,float64)
        ...
        field(fstring,string)
        field(darray,array(double[])
        field(displayLimits,struct(displayLimits))
    }

Then the generated header file will be

    class xxxRecord : public iocRecord {
    public:
        epicsBoolean fbool;
        epicsOctet   foctet;
        ...
        epicsFloat64 ffloat64;
        ...
        EpicsString  fstring;
        EpicsArray   darray;
        EpicsStruct  displayLimits;
   };

DbfArray

This is for array fields with a type epicsUnknownT. DbfArray provides the dbfType.

If a record definition contains:

    struct(calcInpLink) {
        field(link,link(in))       // epicsType is epicsUnknownT
        field(value,float64)
    }
    record(calc) extends iocRecord {
        ...
        field(inp,array(struct(calcInpLink)[]))
        ...
    }

Then the generated code contains:

    DbfArray inp;

DbfStruct

This is for a struct field with at least one field of type epicsUnknownT.

If a record definition contains:

    struct(calcInpLink) {
        field(link,link(in))     // epicsType is epicsUnknownT
        field(value,float64)
    }
    record(calc) extends iocRecord {
        ...
        field(inp,struct(calcInpLink))
        ...
    }

Then the generated code contains:

    DbfStruct inp;
    

DbfMenu

DbfMenu is described as:

    class DbfMenu{
    public:
        epicsInt16    index;
        DbdMenu  *pmenuDef;
    };

If a record definition contains

    field(fmenu,menu(name))

Then the generated header file contains

    DbfMenu fmenu;

DbfMenu provides the current menu index and also the menu definition.

DbfEnum

DbfEnum is described as:

    class DbfEnum{
    public:
        epicsInt16  index;
        EpicsArray  *pchoiceArray; //EpicsArray of epicsStringT
    };

If a record definition contains

    field(fenum,enum)

Then the generated header file contains

    DbfEnum fenum;

pchoiceArray is the address of a field in the same record that is an EpicsArray of type epicsStringT. It contains the choices.

DbfLink

DbfLink is described as

    class DbfLink{ 
    public:
        LinkDir   dir;
        DbdLink   *plinkDef;
        EpicsStruct dataStruct;
    };

If a record definition contains

    field(flink,link(in))

Then the generated header file contains

    DbfLink flink;

The fields of DbfLink are initialized by locating a dbd link definition that matches the dir specified in the dbd field definition.

The fields of DbfLink are initialized as follows:

dir
This is taken from either the field definition or from the DbdLink definition and is the most restrictive. For example if one says inout and the other says in then dir will be in.
plinkDef
This is the address of the DbdLink.
dataStruct
The describes the data structure specified in the dbd link definition. It contains data used by the link support.

Note that link support always implements interface DbdLinkSupport

DbfDevice

A DbfDevice is similar to a DbfLink except that the interface implemented by the device support is also specified, i.e. instead of implementing interface DbdLinkSupport, the device support implements an interface that both record support and device support understand.



dbdStatements

The definitions in dbdStatements.h allow introspection of ioc records. They describe everything defined in DBD definitions.

NODE and LIST specify a doubly linked list. An implementation is not specified.

dbdStatements.h

class Interface {}; // Must be an interface, i.e. pure abstract class
class DbdFieldAttribute {
public:
    EpicsString  default;
    epicsBoolean readonly;
    epicsBoolean design;
    epicsBoolean special;
    epicsBoolean dynamic;
    epicsInt16   asl;
};
class DbdField : public EpicsStructField {
public:
    dbfType           dbftype;
    DbdFieldAttribute attribute;
};
class DbdStruct : public EpicsStructDef{ // describes a struct
public:
    NODE              node; // for DbdStructList
};
class DbdRecord : public EpicsStructDef { // describes a record
public:
    NODE              node; // for DbdRecordList
    LIST              instanceList;
    DbdRecordSupport  *psupport;
};
class DbdMenu{
public:
    NODE        node; // for DbdMenuList
    EpicsString name;
    epicsInt16  nchoices;
    EpicsString *pchoice[];
};
class DbdLink{ //describes dbd link statement
public:
    NODE         node; // For DbdLinkList
    LinkDir      dir;
    EpicsString  choiceName;
    EpicsString  dataStructName;
    DbdLinkSupport  *pinterface;
};
class DbdDevice { //describes dbd device statement
public:
    NODE        node; // For linkList
    LinkDir     dir;
    EpicsString choiceName;
    EpicsString dataStructName;
    EpicsString interfaceName;
    Interface   *pinterface;
};
class DbdUserField{ // describes a dbd userField statement
public:
    NODE   node; // For DbdUserFieldList
    EpicsString choiceName;
    epicsType   type;
    EpicsString dataStructName;
    DbdUserFieldHandler *pinterface;
};
// The following describes a record instance
class DbdUserFieldInstance {
public:
    NODE         node; // for DbdRecordInstance.userField
    EpicsString  name; // field name
    DbdUserField *pDbdUserField;
    void         *pstorage; // for DbdUserField.type
    EpicsStruct  dataStruct;
};
class DbdRecordInstance : extends EpicsStruct {
public:
    NODE         node; // for DbdRecord.instanceList
    EpicsString  name;
    LIST         userField; // of DbdUserFieldInstance
};


class DbdStructList {
public:
    LIST list;
};
class DbdRecordList {
public:
    LIST list;
};
class DbdMenuList {
public:
    LIST list;
};
class DbdLinkList {
public:
    LIST list;
};
class DbdDeviceList {
public:
    LIST list;
};
class DbdUserFieldList {
public:
    LIST list;
};


Discussion of dbdStatements

struct and record

The following classes describe the fields in a dbd struct or record definition: DbdStruct, DbdRecord, DbdField,and DbdFieldAttribute

The fields of DbdStruct are:

name
The name of the struct.
plifetime
The address of an implementation of interface DbdStructLifetime. The implementation is automatically generated from the dbd struct. See below for a description of the Lifetime methods.
nfields
The number of fields, e.g. fields in the structure.
pfields
pointer to an array of pointers to DbdField.
node
A node for the list of struct definitions

The fields of DbdRecord are;

name
The name of the record type.
plifetime
The address of an implementation of interface DbdRecordLifetime. The implementation is automatically generated from the dbd record statement. See below for a description of the Lifetime methods.
nfields
The number of fields, e.g. fields in the record.
pfields
pointer to an array of pointers to DbdField.
node
A node for the list of record definitions
node
This is a node for DbdRecordList
instanceList
The list of record instances of this record type.
psupport
The address of the DbdRecordSupport for this record type.


The fields of DbdField are:

name
The name of the field
type
The epicsType, which is always epicsUnknownT
dbftype
The dbfType of the field.
attribute
DbdFieldAttribute for the field

The fields of DbdFieldAttribute are:

default
An EpicsString providing a default value for the field.
readonly
Is the field readonly?
design
Is the field a design fields for DCTs?
special
Should DbdRecordSupport:special be called if the field is modified.
dynamic
Can the field change because of record processing?
asl
The access security level.

Menu

A dbd menu is described by class DbdMenu

The fields of DbdMenu are:

name
The menu name.
nchoices
The number of menu choices.
pchoice
The address of an array of pointers to EpicsString. Each EpicsString is a choice.

Link

Each dbd link definition has an associated class DbdLink with fields:

node
This is a node for DbdLinkList
dir
The link direction
choiceName
The name that connects a DbdLink to a DbfLink instance.
dataStructName
The class name of an EpicsStruct for the Interface implementation
pinterface
The address of the DbdLinkSupport Interface implementation.

Device

Each dbd device definition has an associated class DbdDevice with fields:

node
This is a node for DbdDeviceList
dir
The link direction
choiceName
The name that matches a DbdDevice to a DbfDevice instance.
dataStructName
The class name of an EpicsStruct for the Interface implementation
interfaceName
The name of the interface type implemented by the device support
pinterface
The address of the Interface implementation.


User Defined Fields

Each dbd userField definition has an associated class DbdUserField with fields:

node
This is a node for DbdUserFieldList
choiceName
The name that matches a DbdUserField to a DbdUserFieldInstance
type
The epicsType for the user field
dataStructName
The class name of an EpicsStruct for the DbdUserFieldHandler
pinterface
The address of the DbdUserFieldHandler implementation.

Record Instance

A record instance has two associated classes:DbdUserFieldInstance and DbdRecordInstance.

DbdUserFieldInstance contains information for a user defined field:

node
A node for list DbdRecordInstance.userField
name
The name of the user defined field, i.e. the psuedo field name
pDbdUserField
The DbdUserField that describes the field
pstorage
Address of storage for the dbfType.
dataStruct
An EpicsStruct that holds the private data for the DbdUserFieldHandler.

The fields of DbdRecordInstance are:

pstructDef
address of the DbdRecord describing the record
pstorage
address of the storage for the record instance
node
A node for list DbdRecord.instanceList
name
The name of the record instance
userField
A DbdUserFieldInstance list for the record instance.

Lists

The following provide lists of various things:

DbdStructList
The list of each struct definition
DbdRecordList
The list of each record type definition
DbdMenuList
The list of each menu definition
DbdLinkList
The list of each link definition
DbdDeviceList
The list of each device definition
DbdUserFieldList
The list of each userField definition

dbdInterfaces

dbdInterfaces describes standard interfaces implemented by code that supports runtime database access.

dbdInterfaces.h

dbdInterfaces.h contains the following:

// The following is implemented by database access
class DbdFieldPutString {
    virtual void primitive(EpicsString *pfrom, epicsType type,
                              void *pstorage) = 0;
    virtual void string(EpicsString *pfrom,
                              EpicsString *pEpicsString) = 0;
    virtual void array(EpicsString *pfrom,
                              EpicsArray *pEpicsArray) = 0;
    virtual void epicsStruct(EpicsString *pfrom,
                              EpicsStruct *pEpicsStruct) = 0;
    virtual void epicsMDArray(EpicsString *pfrom,
                              EpicsMDArray *pEpicsMDArray) = 0;
}
// For struct definitions that become EpicsStruct or DbfStruct fields
// An DbdStructLifetime interface is automatically generated.
class DbdStructLifetime : public EpicsStructLifetime {
public:
    virtual bool initialize(DbfStruct *pDbfStruct) = 0;
    virtual bool finalize(DbfStruct *pDbfStruct) = 0;
};
// For record definitions a DbdRecordLifetime is automatically generated.
class DbdRecordLifetime : public EpicsStructLifetime{
public:
    virtual bool initialize(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool finalize(DbdRecordInstance *pDbdRecordInstance) = 0;
};
// link support modules implement the following interface
class DbdLinkSupport {
public:
    virtual void report(iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool initialize(EpicsString *errorMessage,
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool finalize(EpicsString *errorMessage,
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool connect(EpicsString *errorMessage,
                    iocRecord *precord, DbfLink *pdbfLink) = 0;
    virtual bool disconnect(EpicsString *errorMessage,
                    iocRecord *precord, DbffLink *pdbfLink) = 0;
    virtual bool get(EpicsString *errorMessage,
                    iocRecord *precord, DbffLink *pdbfLink,
                    epicsType type, void *pfield) = 0;
    virtual bool put(EpicsString *errorMessage,
                     iocRecord *precord, DbfLink *pdbfLink,
                     epicsType type, void *pfield) = 0;
};
/* record support implements the following*/
class DbdRecordSupport {
public:
    virtual bool initBuffers(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool initConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool breakConnections(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual bool process(DbdRecordInstance *pDbdRecordInstance) = 0;
    virtual void special(DbdRecordInstance *pDbdRecordInstance,
            bool  after,
            epicsInt16 nlevels, // number of elements in fieldIndex
            epicsInt16 fieldIndex[] // array of field indices
            ) = 0;
};
class DbdUserFieldHandler {
public:
    virtual bool initialize(EpicsString *errorMessage,
                     iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
    virtual bool finalize(EpicsString *errorMessage,
                     iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
    virtual bool process(EpicsString *errorMessage,
                     iocRecord *precord,DbdUserFieldInstance *puserField) = 0;
};

Discussion of dbdInterfaces

DbdFieldPutString

This is an interface, which has an implementation provided by iocCore, that convert an EpicsString to an epicsType. The methods are:

primitive
This convert a string to one of the types: epicsBoolT, ..., <epicsFloat64T
string
Copies a string from pfrom to pEpicsString.
array
Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:primitive or EpicsString:string to convert the value and put it into the correct element of EpicsArray
epicsStruct
Accepts a string that has the DBD struct initialialization syntax, locates the string value associated with each field and calls primitive, string, or array to convert the value and put the result of the correct field of EpicsStruct The structure must not contain any unknown field types.
epicsMDArray
Accepts a string that has the DBD array initialization syntax, locates the string value for each element and calls either EpicsString:primitive or EpicsString:string to convert the value and put it into the correct element of EpicsMDArray

DbdStructLifetime and DbdRecordLifetime

Every dbd struct and record has an associated Lifetime interface implementation. A tool is provided that automatically generates the implementation from the dbd definition.

DbdStructLifetime and DbdRecordLifetime each has the following fields:

allocate
Creates storage for the struct or record.
destroy
frees storage
exposeField
Given an index it returns the address of the storage for the field. Note the the generated header files assign an index to each field.
initialize
initializes the struct or record
finalize
cleans up but does not free storage

DbdLinkSupport

This is the interface implemented by the support associated with each DBD link.

DbdLinkSupport has the following methods:

report
generate a report about the link instance
initialize
perform initialization but do not connect
finalize
undo initialization. It is assumed that disconnect has already been called.
connect
connect to external source of data
disconnect
disconnect from external source of data
get
get a value from the external source. type specified the field type and pfield is the address of where to store the data.
put
put a value from the external source. type specified the field type and pfield is the address of where to obtain the data.

DbdRecordSupport

This is the interface implemented by each record support module. DbdRecordSupport has the following methods:

initBuffers
This is called during record initialization. It is responsible for creating the buffers associated with each string and array field. It may call associated support to do the initialization.
initConnections
This is called to connect to external sources. It may call associated support to make the connections.
breakConnections
This is called to disconnect to external sources. It may call associated support to break the connections.
process
Process the record.
special
This is called whenever an external source modifies a field with attribute special set to true.


DbdUserFieldHandler

This is the interface implemented by code for user extensible fields.

DbdUserFieldHandler has the following fields:

initialize
Initialize the user field.
finalize
undo what was done during initialization
process
Called near the end of record processing just before monitors are handled.

Device Support Interfaces

Multiple interface definitions for device support will be defined. Record Support and device support must agree on which interface type is used for communication.