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  2018  2019  2020  2021  2022  2023  2024  <20252026  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  2018  2019  2020  2021  2022  2023  2024  <20252026 
<== Date ==> <== Thread ==>

Subject: RE: asynPortDriver derived class connect() method not being called when expected
From: "Pearson, Matthew via Tech-talk" <[email protected]>
To: Mark Rivers <[email protected]>, "Thomas, Patrick" <[email protected]>, Michael Davidsaver <[email protected]>
Cc: "[email protected] Talk" <[email protected]>
Date: Tue, 19 Aug 2025 21:47:25 +0000

Hi Mark,

 

Is the static connect function called as part of the asynPortDriver constructor (perhaps via asynManager)? Then the derived object wouldn’t be created in time for that initial call.

 

Cheers,

Matt

 

From: Tech-talk <[email protected]> On Behalf Of Mark Rivers via Tech-talk
Sent: Tuesday, August 19, 2025 4:23 PM
To: Thomas, Patrick <[email protected]>; Michael Davidsaver <[email protected]>
Cc: [email protected] Talk <[email protected]>
Subject: [EXTERNAL] asynPortDriver derived class connect() method not being called when expected

 

Folks, I have renamed this thread since the topic has changed from the original. I have pursued this problem and found that an asynPortDriver derived class connect() method will only be called if the asyn flag ASYN_MULTIDEVICE is set, and it

Folks,

 

I have renamed this thread since the topic has changed from the original.

 

I have pursued this problem and found that an asynPortDriver derived class connect() method will only be called if the asyn flag ASYN_MULTIDEVICE is set, and it is only called after iocInit().

 

I modified the asynPortDriver class to print messages in the static function connect() and asynPortDriver::connect().  The static connect() function calls the class method connect(), so it should call the derived class method if it is defined.

 

I also modified testAsynPortDriverApp (which derives from asynPortDriver) to add the connect() method, which prints a message and then calls the base class asynPortDriver::connect() method.

 

This is what I see if ASYN_MULTIDEVICE is not set.

 

testAsynPortDriverConfigure("testAPD", 1000)

asynPortDriver static connect method entry

asynPortDriver::connect entry pasynUser=0x1cff7e8

dbLoadRecords("../../db/testAsynPortDriver.db","P=testAPD:,R=scope1:,PORT=testAPD,ADDR=0,TIMEOUT=1,NPOINTS=1000")

dbLoadRecords("../../db/asynRecord.db","P=testAPD:,R=asyn1,PORT=testAPD,ADDR=0,OMAX=80,IMAX=80")

#asynSetTraceMask("testAPD",0,0xff)

asynSetTraceIOMask("testAPD",0,0x2)

iocInit()

Starting iocInit

############################################################################

## EPICS R7.0.9

## Rev. R7.0.9-dirty

## Rev. Date Git: 2025-02-21 17:31:33 -0600

############################################################################

cas WARNING: Configured TCP port was unavailable.

 

Note that the static connect() method and asynPortDriver::connect() are called immediately after the driver object is created.  However, the derived class is not called.  There are no connect() calls after iocInit.

 

This is what I see if ASYN_MULTIDEVICE is set.

 

testAsynPortDriverConfigure("testAPD", 1000)

asynPortDriver static connect method entry

asynPortDriver::connect entry pasynUser=0xa57a58

dbLoadRecords("../../db/testAsynPortDriver.db","P=testAPD:,R=scope1:,PORT=testAPD,ADDR=0,TIMEOUT=1,NPOINTS=1000")

dbLoadRecords("../../db/asynRecord.db","P=testAPD:,R=asyn1,PORT=testAPD,ADDR=0,OMAX=80,IMAX=80")

#asynSetTraceMask("testAPD",0,0xff)

asynSetTraceIOMask("testAPD",0,0x2)

iocInit()

Starting iocInit

############################################################################

## EPICS R7.0.9

## Rev. R7.0.9-dirty

## Rev. Date Git: 2025-02-21 17:31:33 -0600

############################################################################

asynPortDriver static connect method entry

testAsynPortDriver::connect entry

asynPortDriver::connect entry pasynUser=0xa56988

 

Note that the static connect() method and asynPortDriver::connect() are called immediately after the driver object is created, and the derived class is still not called there.

 

However, after iocInit, the static method is called, followed by the derived class method testAsynPortDriver::connect(), which then calls asynPortDriver::connect().

 

I don’t understand 2 things:

-       Why is the derived class method not called when the object is first created, but only the base class method?

-       Why does setting ASYN_MULTIDEVICE cause static connect() function to be called again after iocInit(), and this time it does calls derived class method?

 

Thanks,

Mark

 

 

 

From: Thomas, Patrick <[email protected]>
Sent: Tuesday, August 19, 2025 12:44 PM
To: Michael Davidsaver <[email protected]>
Cc: Mark Rivers <[email protected]>; [email protected] Talk <[email protected]>
Subject: Re: synchronizing the value of a read/write record

 

 

The code I am using is attached.

 


From: Thomas, Patrick <[email protected]>
Sent: Tuesday, August 19, 2025 10:39 AM
To: Michael Davidsaver <[email protected]>
Cc: Mark Rivers <[email protected]>; [email protected] Talk <[email protected]>
Subject: Re: synchronizing the value of a read/write record

 

Thank you. It still seems to compile after adding the override keyword, but not get called.


From: Michael Davidsaver <[email protected]>
Sent: Tuesday, August 19, 2025 10:32 AM
To: Thomas, Patrick <[email protected]>
Cc: Mark Rivers <[email protected]>; [email protected] Talk <[email protected]>
Subject: Re: synchronizing the value of a read/write record

 

On 8/19/25 10:21, Thomas, Patrick via Tech-talk wrote:

Hello,

 

I'm working through implementing a class that inherits from asynPortDriver and attempting to override the 'connect' virtual method. However, the code I have overridden it with never appears to be called. Is there a configuration parameter or something else that I need to do to have this work?

This might be a simple c++ issue with attempting to override a method, but providing an incorrect argument list.  With C++11, the "override" keyword can help detect this.

 

http ://www.en.cppreference.com/w/cpp/language/override.html

 

 

 

Thank you,

Patrick


From: Tech-talk <[email protected]> on behalf of Thomas, Patrick via Tech-talk <[email protected]>
Sent: Wednesday, August 13, 2025 10:45 AM
To: Mark Rivers <[email protected]>; [email protected] Talk <[email protected]>
Subject: Re: synchronizing the value of a read/write record

 

Hi Mark,

 

I did see that and was starting to look at using asyn, but I was having trouble figuring out how to do so. Is there a minimal working example that I might be able to modify? Do I need to create separate driver and device support?

 

The other thought I had was if this could be handled by somehow creating record support for read/write records.

 

Thank you,

Patrick

 


From: Mark Rivers <[email protected]>
Sent: Wednesday, August 13, 2025 5:48 AM
To: [email protected] Talk <[email protected]>; Thomas, Patrick <[email protected]>
Subject: Re: synchronizing the value of a read/write record

 

Hi Patrick,

 

As Ralph said, if your driver is written using asyn then you can use the info(asyn:READBACK) tag on your output record.

 

 

·       Is there any way to synchronize things so that write requests coming from channel access are always written to the hardware and not overridden by periodic updates from reading the hardware?

 

I'm not sure what you mean here.  I think the EPICS record locking an asyn port locking will guarantee that all EPICS writes get sent to the hardware atomically, and that all callbacks from the driver that update the output record will be atomic.  However, once EPICS writes the value to the hardware, the next poll of the hardware could quickly change the output record.  Maybe I am not understanding your question.

 

Mark

 

 

 


From: Tech-talk <[email protected]> on behalf of Thomas, Patrick via Tech-talk <[email protected]>
Sent: Tuesday, August 12, 2025 7:41 PM
To: [email protected] Talk <[email protected]>
Subject: synchronizing the value of a read/write record

 

Hello,

 

I'm attempting to write device support to handle the scenario where changes to the value of a hardware device can be made from both EPICS and another source. I would like the value of the hardware to be changed if I write a value to the record through channel access, and also to continuously monitor the hardware device for changes made from the other source and update the value of the record to match. One approach I have considered is to use separate output and input records, where the output records write values set from channel access to the hardware and the input records periodically scan the hardware and update their values accordingly. I am wondering however if there is a way to do this with the val field of just an output record. Is there any way to synchronize things so that write requests coming from channel access are always written to the hardware and not overridden by periodic updates from reading the hardware?

 

Thank you,

Patrick

 

 


References:
synchronizing the value of a read/write record Thomas, Patrick via Tech-talk
Re: synchronizing the value of a read/write record Mark Rivers via Tech-talk
Re: synchronizing the value of a read/write record Thomas, Patrick via Tech-talk
Re: synchronizing the value of a read/write record Thomas, Patrick via Tech-talk
Re: synchronizing the value of a read/write record Michael Davidsaver via Tech-talk
Re: synchronizing the value of a read/write record Thomas, Patrick via Tech-talk
Re: synchronizing the value of a read/write record Thomas, Patrick via Tech-talk
asynPortDriver derived class connect() method not being called when expected Mark Rivers via Tech-talk

Navigate by Date:
Prev: asynPortDriver derived class connect() method not being called when expected Mark Rivers via Tech-talk
Next: dinosaur question: is there a command to alias another commend in a (3.13.8) startup file? Maren Purves via Tech-talk
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  2018  2019  2020  2021  2022  2023  2024  <20252026 
Navigate by Thread:
Prev: asynPortDriver derived class connect() method not being called when expected Mark Rivers via Tech-talk
Next: Re: synchronizing the value of a read/write record Johnson, Andrew N. via Tech-talk
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  2018  2019  2020  2021  2022  2023  2024  <20252026 
ANJ, 19 Mar 2026 · Home · News · About · Talk · Base · Modules · Extensions ·
· Distributions · Download · Documents · Links · Licensing ·