I believe I have found the change in EPICS
base that caused the soft motor device to stop working.
In 3.15.5 dbStaticRun.c::dbAllocRecord contains the following:
case DBF_DEVICE:
if(!pflddes->ftPvt) dbGetDeviceMenu(pdbentry);
break;
case DBF_INLINK:
case DBF_OUTLINK:
case DBF_FWDLINK: {
DBLINK *plink = (DBLINK *)pfield;
plink->type = CONSTANT;
if(pflddes->initial) {
plink->value.constantStr =
dbCalloc(strlen(pflddes->initial)+1,sizeof(char));
strcpy(plink->value.constantStr,pflddes->initial);
}
}
break;
case DBF_NOACCESS:
So it copies the initial value of the link string to plink->value.constantStr.
In 7.0.1 this is the code in that function:
case DBF_DEVICE:
if(!pflddes->ftPvt) dbGetDeviceMenu(pdbentry);
break;
case DBF_INLINK:
case DBF_OUTLINK:
case DBF_FWDLINK: {
DBLINK *plink = (DBLINK *)pfield;
plink->type = CONSTANT;
if(pflddes->initial) {
plink->text =
dbCalloc(strlen(pflddes->initial)+1,sizeof(char));
strcpy(plink->text,pflddes->initial);
}
}
break;
case DBF_NOACCESS:
So it copies the initial value to plink->text, rather than plink->value.constantStr, where the soft motor device support was expecting to find it. In both cases it sets
plink->type to CONSTANT. Presumably the link type may get changed later to PV_LINK, CA_LINK, or DB_LINK when it is parsed.
I understand that plink->value.constantStr should only be used if plink->type==CONSTANT, but is there a chance that this change is going to break other code that was
relying on the previous behavior?
Mark
-----Original Message-----
From: Michael Davidsaver <[email protected]>
Sent: Saturday, September 8, 2018 1:43 AM
To: Andrew Johnson <[email protected]>; Mooney, Tim M. <[email protected]>; Mark Rivers <[email protected]>; Peterson, Kevin M. <[email protected]>
Cc: [email protected]
Subject: Re: Problems with soft motors
On 09/07/2018 06:47 PM, Andrew Johnson wrote:
> Hi Tim,
>
> That code definitely looks kinkey, anything that relies on relative
> thread priorities isn't going to work properly on an OS that doesn't
> have a strict priority scheduler (Linux, Windows etc.).
>
> Whether that's what's causing Mark's issue I can't say though, I did
> no more than look at the routine you pointed to.
> long soft_init(void *after)
> {
> int before_after = (after == 0) ? 0 : 1
Device support init() is called with 'int'. So this test behaves unpredictably when sizeof(void*) != sizeof(int).
soft_motor_task() is accessing records w/o locking. Also, access of union members 'mr->dinp.value.constantStr' vs. '.pv_link' w/o first testing 'mr->dinp.type' CONSTANT vs. CA_LINK/DB_LINK seems to me a recipe for surprise.
> - Andrew
>
>
> On 09/07/2018 12:15 PM, Mooney, Tim M. wrote:
>> Hi Mark,
>>
>>
>> I'll make a wild guess: The function, soft_init(), in
>> motor/motorApp/SoftMotorSrc/devSoftAux.cc, seems vulnerable to
>> changes in EPICS base that might not have had consequences for other
>> code I know of. This code has always seemed a little hinky to me.
>> Do you see the error message "cannot find dbCaLink task." in the IOC
>> console output after iocInit?
>>
>>
>> Tim Mooney ([email protected]) (630)252-5417 Beamline Controls Group
>> (www.aps.anl.gov) Advanced Photon Source, Argonne National Lab
>>
>> ---------------------------------------------------------------------
>> ---
>> *From:* Mark Rivers <[email protected]>
>> *Sent:* Thursday, September 6, 2018 6:23:32 PM
>> *To:* Peterson, Kevin M.; Mooney, Tim M.; Johnson, Andrew N.
>> *Cc:* [email protected]
>> *Subject:* Problems with soft motors
>>
>> Hi,
>>
>>
>> I am having a serious problem with soft motor device support. These
>> are databases that have worked fine for over 10 years. The databases
>> are the ones in motorApp/Db: pseudoMotor.db and sumDiff2D.db.
>>
>>
>> The databases are very simple: there are 2 real motors and 2 soft
>> motors. One soft motor moves both real motors in the same direction,
>> and the other soft motor moves the real motors in the opposite
>> direction. The readback of the first soft motor is the average of
>> the real motors, while the other is the difference of the real
>> motors. The calculations are done in transform records. There is
>> also a transform record that calculates when the soft motors are done
>> moving, which is just the logical AND of the real motor .DMOV fields.
>>
>>
>> The main problem I am seeing is that the transform records are
>> updating OK, but for some motors these values are not getting back
>> into the motor record.
>>
>>
>> Here is an example of the debugging output of the devSoft.cc when a
>> real motor is moved, and the soft motors, pm5 and pm6 are updating
>> during that real motor move.
>>
>>
>> soft_dinp_func(): HARDMOVE set for 13BMD:pm5.
>> soft_rdbl_func(): updated RMP = 901 for 13BMD:pm5.
>> update(): dmov=0 for 13BMD:pm5.
>> update(): DMOV=0 for 13BMD:pm5.
>> soft_rdbl_func(): updated RMP = 23 for 13BMD:pm6.
>> update(): dmov=1 for 13BMD:pm6.
>> update(): DMOV=1 for 13BMD:pm6.
>> soft_rdbl_func(): updated RMP = 930 for 13BMD:pm5.
>> update(): dmov=0 for 13BMD:pm5.
>> update(): DMOV=0 for 13BMD:pm5.
>> soft_rdbl_func(): updated RMP = 80 for 13BMD:pm6.
>> update(): dmov=1 for 13BMD:pm6.
>> update(): DMOV=1 for 13BMD:pm6.
>> soft_dinp_func(): Done moving set for 13BMD:pm5.
>> update(): dmov=0 for 13BMD:pm5.
>> update(): DMOV=1 for 13BMD:pm5.
>> soft_rdbl_func(): updated RMP = 940 for 13BMD:pm5.
>> update(): dmov=1 for 13BMD:pm5.
>> update(): DMOV=1 for 13BMD:pm5.
>> soft_rdbl_func(): updated RMP = 101 for 13BMD:pm6.
>> update(): dmov=1 for 13BMD:pm6.
>> update(): DMOV=1 for 13BMD:pm6.
>>
>> In this case pm5 is working fine. It detected that dmov initially
>> went to 0, and so at the end of the move it set the VAL field to
>> match the RBV field.
>>
>> However, pm6 is not working correctly. It is detecting the readback
>> changes, but it does not get the correct value of dmov. It always
>> sees it as 1, not as 0 which it should. This means that at the end
>> of the move it does not set the VAL field to match RBV. pm5 and pm6
>> are configured identically, and they both get their DMOV value from
>> the same field of the same transform record. Why does one work and one not work?
>>
>> Here are some symptoms of the problem:
>>
>> - Some soft motors work fine, and others do not, even when they are
>> apparently configured identically. For one set of soft motors in one
>> of my IOCs there are no updates printed with debugging in devSoft.cc.
>> For these soft motors neither the RBV fields nor the VAL fields
>> update at all when the real motors are moved.
>>
>> - The behavior of a particular motor is always the same, through
>> multiple reboots, i.e. it either works or does not work.
>>
>> - This has all worked fine until this shutdown when I made a lot of changes:
>> Base 3.15.5 > 7.0.1.1
>> synApps modules (motor, calc, etc.): master January 2018 to
>> master August 2018.
>>
>> - The devSoft.cc has not changed since 2015 so that cannot be the problem.
>>
>> - I tried reverting the motorRecord.cc to the commit from Jan. 4,
>> 2018 which is what I was using in the last run when it worked fine.
>> That did NOT fix the problem, which was very surprising. This
>> suggests that perhaps the problem has something to do with links in
>> the transform record, or some change in base?
>>
>> - I reverted the entire IOC application to the version I was running
>> in the last run (3.15.5, master branch of synApps from January 2018)
>> and all of the soft motors work fine. This seems to prove it is some
>> software change in base 7.0.1 vs 3.15.5, or a change in synApps since
>> January. But it is NOT the motor record itself.
>>
>> Help!
>>
>> Thanks,
>> Mark
>>
>>
>>
>>
>>
>>
>>
>