V4 Design: Database Initialization
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
- What is done when an executable that includes support code is loaded?
- What must be done by iocInit?
- 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:
- compute or recompute lock sets
- Add record instance to a scan list