EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  <20182019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  <20182019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Problems with soft motors
From: Michael Davidsaver <[email protected]>
To: Mark Rivers <[email protected]>, Andrew Johnson <[email protected]>, "Mooney, Tim M." <[email protected]>, "Peterson, Kevin M." <[email protected]>
Cc: "[email protected]" <[email protected]>
Date: Sun, 9 Sep 2018 07:27:38 +0100
On 09/08/2018 09:07 PM, Mark Rivers wrote:
> Hi Michael,
> 
> You said:
>>> 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).
> 
> I find this a bit confusing.  devSup.h defines the following:
> 
> #ifdef __cplusplus
> extern "C" {
>     typedef long (*DEVSUPFUN)(void *);  /* ptr to device support function*/
> #else
>     typedef long (*DEVSUPFUN)();        /* ptr to device support function*/
> #endif

In C an empty argument list 'funcname()' declares a function which can accept _any_ argument list.
An actual empty argument list is 'funcname(void)'.  I'm not going to try to explain the c++ aspect
now as I can't remember the reasoning.

It may be sufficient to show that in C the following is valid.

> DEVSUPFUN fn = ...;
> (*fn)(0); // call as fn(int)
> (*fn)("foo"); // call as fn(const char *)

> typedef struct dset {   /* device support entry table */
>     long        number;         /*number of support routines*/
>     DEVSUPFUN   report;         /*print report*/
>     DEVSUPFUN   init;           /*init support layer*/
>     DEVSUPFUN   init_record;    /*init device for particular record*/
>     DEVSUPFUN   get_ioint_info; /* get io interrupt information*/
>     /*other functions are record dependent*/
> } dset;
> 
> So the init function is defined to be a DEVSUPFUN, which is function taking a void * argument and returning a long.

If you're confused that init is really 'init(int)', consider that get_ioint_info is
really 'get_ioint_info(int,dbCommon*,IOCSCANPVT*)'.

> There are no examples of the implementation of a device support init() function in the 3.15.5 Application Developer's Guide, though it does say in section 12.4.2 that the definition of the DSET init() function is:
> long init( int after);
>
> The only examples I can find of DSET init() functions in base are the devXXSoftCallback.c functions, where XX = ai, bi, si, etc.  These do define init() to take an int argument.
> 
> It appears to me that this is a very common mistake in synApps.   This is a search of the entire synApps tree for files named dev*.c* which contain the string "init(void".  

It is, in synapps and elsewhere.  I'm hoping to begin moving away from untyped function pointers with:

https://code.launchpad.net/~epics-core/epics-base/+git/dtypedset/+merge/332730

Have a look at the proposed new 'struct typed_dset'.
 
...
> Does this mean that all of these files need to be changed to work reliably on systems where a void * and an int are different sizes?

Yes.


> Thanks,
> 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
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
> 


References:
Problems with soft motors Mark Rivers
Re: Problems with soft motors Mooney, Tim M.
Re: Problems with soft motors Andrew Johnson
Re: Problems with soft motors Michael Davidsaver
RE: Problems with soft motors Mark Rivers

Navigate by Date:
Prev: RE: Keithley 2001 Digital multimeter IOC Mark Rivers
Next: RE: Problems with soft motors Mark Rivers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  <20182019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: Problems with soft motors Mark Rivers
Next: RE: Problems with soft motors Mark Rivers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  <20182019  2020  2021  2022  2023  2024 
ANJ, 09 Sep 2018 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·