Experimental Physics and
| |||||||||||||||
|
Hi Andrew,
You're right that my status = (*dbFastPutConvertRoutine[DBR_STRING][field_type]) call doesn't specify DBF_NOACCESS for field_type. I missed the reassignment to field_type.
This code is called from two initHooks: initHookAfterInitDevSup (before record init) and initHookAfterInitDatabase (after record and device init). DBF_NOACCESS fields, including arrays, are skipped in the first call.
I don't have a way of distinguishing arrays of one element from scalars. At save time, I'm using ca_element_count() to determine the number of array elements, and treating PVs with one element as scalars.
At boot-time restore, I'm using the text that was written at save time to tell me how to restore the PV's value.
I also noticed that paddr->pfield was being set in different calls - get_array_info() or cvt_dbaddr() - and that this changed from 3.14.12.5 to 3.15.5. But when I pulled the 3.14.12.5 version of the waveform record into 3.15.5 and it didn't fix the problem, I assumed this was not the source of the problem. Maybe I should try again, more carefully this time.
Tim Mooney ([email protected]) (630)252-5417
Beamline Controls Group (www.aps.anl.gov) Advanced Photon Source, Argonne National Lab From: [email protected] <[email protected]> on behalf of Andrew Johnson <[email protected]>
Sent: Tuesday, July 11, 2017 6:58:38 PM To: [email protected] Subject: Re: Autosave for waveform with 1 element Hi Tim,
On 07/11/2017 05:10 PM, Mooney, Tim M. wrote: > I think the line in dbrestore.c that isn't doing the same thing under > 3.15.5 that it did under 3.14.12.5 is this: > > status = (*dbFastPutConvertRoutine[DBR_STRING][field_type]) > > where field_type has the value DBF_NOACCESS. If your code really is looking up dbFastPutConvertRoutine[DBR_STRING][DBF_NOACCESS] then it isn't getting the function pointer that it's looking for, because the second index into that array only goes up to DBF_DEVICE which is 4 less than DBF_NOACCESS. More likely the field_type value was replaced when dbNameToAddr() called the prset->cvt_dbaddr() routine, which sets paddr->field_type from prec->ftvl or the equivalent field. Hmm, is this dbrestore code being run from initHooks during iocInit()? Which hooks do you use when dealing with array fields, and how do you detect and distinguish between arrays and scalars? Michael Davidsaver added some tests to Base-3.16 which check the APIs that autosave uses so we shouldn't break them when we modify Base, but he doesn't actually call dbPut() in the initHookAfterInitDatabase state so we might have subtly changed the behaviour without knowing it (and of course those tests are present in 3.16, not 3.15). > But I don't understand how > the aSubRecord's .A field behaves differently than the waveform record's > .VAL field, because they are both one element array fields. Arrays with one element look to some parts of the IOC code like they are regular fields, but to other parts like they are arrays. That distinction has changed slightly in more recent versions. One subtle difference that I know about is when the field's buffer pointer gets copied into paddr->pfield. Both the waveform and aao record types do this in their get_array_info() method: paddr->pfield = prec->bptr; In the aSub record though paddr->pfield is set in the cvt_dbaddr() method instead: paddr->pfield = (&prec->a )[offset]; Thus the behaviour difference you see might be explained by something not calling the get_array_info() method properly in 3.15.5 at the time when you're accessing the array field. - Andrew -- Arguing for surveillance because you have nothing to hide is no different than making the claim, "I don't care about freedom of speech because I have nothing to say." -- Edward Snowdon
| ||||||||||||||
ANJ, 21 Dec 2017 |
·
Home
·
News
·
About
·
Base
·
Modules
·
Extensions
·
Distributions
·
Download
·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing · |