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 2025 | 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 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: [AsynDriver] getAddress and callbacks |
From: | Mark Rivers via Tech-talk <[email protected]> |
To: | 'Joao Afonso' <[email protected]> |
Cc: | "[email protected]" <[email protected]> |
Date: | Wed, 19 Jun 2019 20:04:37 +0000 |
Ø
Do you foresee adding them in a future release? I have changed the calls from pasynManager->getAddr() to asynPortDriver::getAddress() in all of the callback routines in asynPortDriver. This will call your overridden getAddress() method, while having no impact on existing code that does
not override this method. Ø
The only problem I noticed is that the TIME field is now always showing <undefined>. I don't know if it was triggered by this, because I didn't look that much into it. I did not observe that, the TIME fields of records which process as a result of asynPortDriver callbacks seem fine. Perhaps you were looking at some records that had not yet processed? My changes are on the master branch of asyn if you want to test them. Mark From: Joao Afonso <[email protected]>
Hi Mark, Thank you for the clarification. I was also wondering if those changes could be done. I tried it like you suggested and it worked mostly fine. The only problem I noticed is that the TIME field is now always showing <undefined>. I don't know if it was triggered by this, because I didn't look that much into
it. Anyway, I prefer not to have a dependency on a custom asynPortDriver modification, so I will try a different approach that doesn't depend on these changes. Do you foresee adding them in a future release? Best regards, Joao From: Mark Rivers [[email protected]] Hi Joao, Perhaps I spoke too soon. It seems like it might work to replace this in asynPortDriver. pasynManager->getAddr(pInterrupt->pasynUser, &address); with this this->getAddress(pInterrupt->pasynUser, &address); Why don’t you try that and see if it works? If asynPortDriver::getAddress has not been overridden then this should not affect the existing behavior. Mark From:
[email protected] <[email protected]>
On Behalf Of Mark Rivers via Tech-talk Hi Joao, Ø
In those cases, the IOC will get the address from
"pasynManager->getAddr()", and not from getAddress(), which breaks the program.
Ø
(for ex. in paramList::octetCallback()) The callbacks are traversing a linked list of clients that have registered for callbacks. This is typically asyn device support, but it is not limited to that. That linked list is created outside of asynPortDriver
by asynManager when each client registers for callbacks. For example, this is the abbreviated code in devAsynInt32.c pasynUser = pasynManager->createAsynUser(processCallback, 0); pPvt->pasynUser = pasynUser; status = pasynEpicsUtils->parseLink(pasynUser, plink, &pPvt->portName, &pPvt->addr, &pPvt->userParam); status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr); status = pPvt->pint32->registerInterruptUser( pPvt->int32Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,&pPvt->registrarPvt); So that pPvt->pasynUser has been connected to a particular port and address, typically specified in the OUT in INP link in the record. The asynPortDriver callback functions are retrieving the address stored in
that pasynUser in the linked list node via pasynManager->get_addr(). pnode = (interruptNode *)ellFirst(pclientList); while (pnode) { asynInt32Interrupt *pInterrupt = (asynInt32Interrupt *) pnode->drvPvt; pasynManager->getAddr(pInterrupt->pasynUser, &address); /* If this is not a multi-device then address is -1, change to 0 */ if (address == -1) address = 0; if ((command == pInterrupt->pasynUser->reason) && (address == addr)) { I don’t see how it could have access to the address that your getAddress() method is generating? Mark From: Joao Afonso <[email protected]>
Hello Mark, Sorry to bother you, I have a question regarding the usage of this function: I have a use case where it is useful to override
asynPortDriver::getAddress() to get a custom reason and address. These values are chosen previously by
drvUserCreate(), and stored in pasynUser->drvUser and pasynUser->reason. This seems to work well for gets and puts, but not when a callback for for a "I/O Intr" record is executed. In those cases, the IOC will get the address from
"pasynManager->getAddr()", and not from getAddress(), which breaks the program. (for ex. in paramList::octetCallback()) Is there a way to make the callbacks also use the custom
asynPortDriver::getAddress() value? Thank you in advance, Joao |