V4 Design: Database Initialization

From EPICSWIKI

EPICS: IOC Database Initialization

May 27 2005

Overview

This document gives a summary of actions required to initialize an IOC database. This includes actions that must be taken when an IOC is booted and also during on-line add/delete of record intances, link support, and device support.

QUESTION? Should iocRecord.dbd define a field

    field(pDbdRecord,private("DbdRecord *")

I think yes becaise given the address of an iocRecord instance it's description is available.


IOC Initialization

What must be done to prepare an IOC? This should include everything so that an IOC is prepared to handle everything connected with an IOC database. This includes things like:

  • error logging system
  • scan threads
  • ???

record types, etc

This section describes how the following are created.

  • DbdStructList - The list of the description of each structure type.
  • DbdRecordList - The list of the description of each record type.
  • DbdLinkList - The list of the description of each DBD link definition
  • DbdDeviceList - The list of the description of each DBD device definition.

Not yet defined. Some Questions

  1. What is done when an executable that includes support code is loaded?
  2. What must be done by iocInit?
  3. How is on-line add/delete of new support code handled?



iocLoadRecords

iocLoadRecords loads and initializes new record instances. This can be done during IOC initialization or on-line.

Initialization consists of the following phases:

  • Allocate storage
  • Allocate buffer managers
  • Initialize storage
  • Initialize external connections
  • Enable record processing

Allocate Storage

Storage is allocated for each record and for any structures that are within the record. Note that buffer storage for strings and arrays are not allocated during this phase.

For each instance of the set of records being loaded do the following:

pDbdRecord  is set to record type
pDbdRecordInstance = // just allocate it
pDbdRecordInstance->pDbdRecord = pDbdRecord;
pDbdRecordInstance->precord = pDbdRecord->plifetime->allocate

for each pDbdStructField in pDbdRecord->pfield[]
    get address of field via pDbdRecord->plifetime->expose
    switch pDbdStructField->type
        case dbfEpicsT
            if(pDbdStructField->basic==epicsStructT)
                pEpicsStruct = pDbdRecord->plifetime=>expose
                initialize pEpicsStruct->pstructDef
                pEpicsStruct->pstorage =
                    pEpicsStruct->pstructDef->plifetime->allocate
            default:
                nothing to do for other basic types
        case dbfStructT
            pDbfStruct = pDbdRecord->plifetime=>expose
            initialize pDbfStruct->pDbdStruct;
            pDbfStruct->pstorage = pDbfStruct->pDbdStruct->plifetime->allocate
        case dbfMenuT
            initialize pDbfMenu->pmenuDef
        case dbfEnumT
            initialize pDbfEnum->pchoiceArray
        case dbfLinkT
            initialize pDbfLink->dir
            initialize pDbfLink->plinkDef
            initialize pDbfLink->dataStruct.pstructDef
            pDbfLink->dataStruct.pstorage =
                pDbfLink->dataStruct.pstructDef->plifetime->allocate
        case dbfDeviceT
            initialize pDbfDevice->dir
            initialize pDbfDevice->pDbdDevice
            initialize pDbfDevice->dataStruct.pstructDef
            pDbfDevice->dataStruct.pstorage =
                pDbfDevice->dataStruct.pstructDef->plifetime->allocate

DbdRecordLifetime.allocate just allocates storage for the record instance not for any arrays or structures that are part of the record.

EpicsStructDef.plifetime.allocate must allocate storage for a structure instance and if any of its fields are of type epicsStructT it must

   initialize pEpicsStruct->pstructDef by locating the fields EpicsStructDef
   pEpicsStruct->pstorage = pEpicsStruct->pstructDef->plifetime->allocate

DbdStruct.plifetime.allocate must allocate storage for structure instance and also allocate storage associated with fields of type epicsStructT or dbfStructT.

For epicsStructT fields it must

   initialize pEpicsStruct->pstructDef by locating the fields EpicsStructDef
   pEpicsStruct->pstorage = pEpicsStruct->pstructDef->plifetime->allocate

For dbfStructT fields it must

   initialize pDbfStruct->pDbdStruct by locating the fields DbdStruct
   pDbfStruct->pstorage = pDbfStruct->pDbdStruct->plifetime->allocate

Allocate Buffer Managers

The buffer managers associated with epicsStringT, epicsArrayT, epicsStructT, epicsMDArrayT, dbfArrayT, and dbfStructT are allocated during this phase. Allocating the buffer managers is the responsibility of record support. Record support may call interfaces associated with epicsStructT or dbfStructT so that aother support can decide the type of buffer manager.

Thus for each record instance the following is called

    pDbdRecord->psupport->initBuffers

Initialize storage

The allocated storage is initialized. This does NOT include initializing connections outside the record.

For each instance of the set of records being loaded do the following:

for each DbdStructField in DbdRecord.pfield
    EpicsString *pfrom = DbdStructField.pattribute.default
    if(pfrom->pbuffer==null) next // no default defined
    get address of field via DbdRecordLifetime.expose
    switch DbdStructField.type
        case: epicsBooleanT, ..., epicsFloat64T
            DbdRecordEpicsFieldPutString:epicsPrimitive
            break;
        case: epicsStringT
            DbdRecordEpicsFieldPutString:epicsString
            break;
        case: epicsArrayT
            DbdRecordEpicsFieldPutString:epicsArray
            break;
        case: epicsStructT
            DbdRecordEpicsFieldPutString:epicsStruct
            break;
        case: epicsMDArrayT
            DbdRecordEpicsFieldPutString:epicsMDArray
            break;
        case: dbfArrayT
        case: dbfStructT
            do nothing. Let record support handle it
        case: dbfMenuT
            index = DbdRecordEpicsFieldPutString:epicsPrimitive
        case dbfEnumT
            index = DbdRecordEpicsFieldPutString:epicsPrimitive
        case dbfLinkT
            dataStruct = DbdRecordEpicsFieldPutString:epicsStruct
        case dbfDeviceT
            dataStruct = DbdRecordEpicsFieldPutString:epicsStruct
DbdRecord.psupport->initBuffers

Record support is expected to create buffers for all strings or arrays in the record. It may call associated support to create the buffers for structure fields managed by the support.


Initialize connections

The next step is to make external connections from record instances. This is the responsibility of record support. Record support may call interfaces associated with link and/or device support.

Thus for each record instance the following is called

    pDbdRecord->psupport->initConnections

prepare the record for processing

TBD

Amoung the things to do are:

  1. compute or recompute lock sets
  2. Add record instance to a scan list