epics-modules / asyn

EPICS module for driver and device support
http://epics-modules.github.io/asyn/
Other
37 stars 72 forks source link

autoconnect with ASYN_MULTIDEVICE #186

Open xiaoqiangwang opened 1 year ago

xiaoqiangwang commented 1 year ago

When I test a model-3 asynMotor driver, I notice the asynMotorController::connect method was not invoked by reconnect timer.

Use the testAsynPortDriver driver with the following changes, the problem can be reproduced, i.e. no periodic printout of "connect" message. Without ASYN_MULTIDEVICE flag, the reconnection timer works.

diff --git a/testAsynPortDriverApp/src/testAsynPortDriver.cpp b/testAsynPortDriverApp/src/testAsynPortDriver.cpp
index 359c89a8..22a91f90 100644
--- a/testAsynPortDriverApp/src/testAsynPortDriver.cpp
+++ b/testAsynPortDriverApp/src/testAsynPortDriver.cpp
@@ -51,7 +51,7 @@ testAsynPortDriver::testAsynPortDriver(const char *portName, int maxPoints)
                     1, /* maxAddr */
                     asynInt32Mask | asynFloat64Mask | asynFloat64ArrayMask | asynEnumMask | asynDrvUserMask, /* Interface mask */
                     asynInt32Mask | asynFloat64Mask | asynFloat64ArrayMask | asynEnumMask,  /* Interrupt mask */
-                    0, /* asynFlags.  This driver does not block and it is not multi-device, so flag is 0 */
+                    ASYN_CANBLOCK|ASYN_MULTIDEVICE, /* asynFlags.  This driver does not block and it is not multi-device, so flag is 0 */
                     1, /* Autoconnect */
                     0, /* Default priority */
                     0) /* Default stack size*/
@@ -123,9 +123,15 @@ testAsynPortDriver::testAsynPortDriver(const char *portName, int maxPoints)
         printf("%s:%s: epicsThreadCreate failure\n", driverName, functionName);
         return;
     }
-}

+    this->disconnect(pasynUserSelf);
+}

+asynStatus testAsynPortDriver::connect(asynUser *pasynUser)
+{
+    printf("connect\n");
+    return asynDisconnected;
+}

 void simTask(void *drvPvt)
 {
diff --git a/testAsynPortDriverApp/src/testAsynPortDriver.h b/testAsynPortDriverApp/src/testAsynPortDriver.h
index c9deb4a3..959b376f 100644
--- a/testAsynPortDriverApp/src/testAsynPortDriver.h
+++ b/testAsynPortDriverApp/src/testAsynPortDriver.h
@@ -54,6 +54,7 @@ public:
                                         size_t nElements, size_t *nIn);
     virtual asynStatus readEnum(asynUser *pasynUser, char *strings[], int values[], int severities[],
                                 size_t nElements, size_t *nIn);
+    virtual asynStatus connect(asynUser *pasynUser);

     /* These are the methods that are new to this class */
     void simTask(void);
xiaoqiangwang commented 1 year ago

The reconnection timer is only initiated by asynManager->exceptionDisconnect. If the port was never connected, it will reach an early return and the timer would not start. https://github.com/epics-modules/asyn/blob/9e184b6102fba63bc5a536cb26f1c94094b23692/asyn/asynDriver/asynManager.c#L2094-L2099

It is somewhat related to #147.