On Mar 24, 2020, at 7:15 AM, D. Peter Siddons via Tech-talk <
tech-talk at aps.anl.gov> wrote:
I never did understand how arrays are handled in EPICS. Do I really need two fields in the database, a value and a buffer? How does it work? If there were only one field it would make
life much simpler!
It is possible to use just one field, not sure when that because possible – I think it was quite a long time ago, but we couldn’t modify the waveform record to do that because of all of the out-of-tree device support code that was written to use two fields.
The newer lsi and lso (long string in/out) records that were added in 3.15 use one field for their VAL (and OVAL) fields like this:
In the Record.dbd file (I have removed some lines that aren’t relevant to this topic):
field(VAL,DBF_NOACCESS) {
prompt("Current Value")
special(SPC_DBADDR)
extra("char *val")
}
The init_record() routine sets the VAL field like this:
prec->val = callocMustSucceed(1, sizv, "lsi::init_record");
In cvt_dbaddr() I do this:
static long cvt_dbaddr(DBADDR *paddr)
{
lsiRecord *prec = (lsiRecord *) paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
if (fieldIndex == lsiRecordVAL) {
paddr->pfield = prec->val;
paddr->special = SPC_MOD;
}
And in the monitor() subroutine the event is posted like this:
db_post_events(prec, prec->val, events);
In cvt_dbaddr, do I need the
paddr->pfield = (void *)(pzDDM->pspct);
statement?
The cvt_dbaddr() routine does have to point paddr->field to the actual array data as that’s where the server copies the array values from. The only time when you could skip doing that is if your DBD file defines the field in extra() as a fixed-size array.
HTH,
- Andrew