Closed Sidney28 closed 1 year ago
profileTimes variable is a part of the asynMotorController class, not asynMotorAxis class. So, in previous version of the asynMotorController::writeFloat64Array function, getAxis will return 0 and profileTimes will not be written.
I don't understand that comment. I just tested writing profileTimes from a Channel Access client and it works fine without this PR.
This is a plot of Prof1:Times when the IOC boots:
I then create an array of times and write it using the IDL CA client:
IDL> times = findgen(250)/250.
IDL> t = caput('DMC01:Prof1:Times', times)
This is the plot after doing that:
I don't understand why you say that getAxis will return 0. It should return a pointer to axis 0, because asyn addr=0 is used for both the controller itself and for the first axis.
Do you have an example where it fails, since I clearly have an example where it does not fail.
I realized my test above does not prove that asynMotorController::writeFloat64Array is not getting 0 for getAxis. It just proves that the the waveform record was written to OK.
I then made this change to add debugging to asynMotorController::writeFloat64Array:
corvette:motor/motorApp/MotorSrc>git diff .
diff --git a/motorApp/MotorSrc/asynMotorController.cpp b/motorApp/MotorSrc/asynMotorController.cpp
index e5d069d..fde4e8e 100644
--- a/motorApp/MotorSrc/asynMotorController.cpp
+++ b/motorApp/MotorSrc/asynMotorController.cpp
@@ -440,6 +440,7 @@ asynStatus asynMotorController::writeFloat64Array(asynUser *pasynUser, epicsFloa
static const char *functionName = "writeFloat64Array";
pAxis = getAxis(pasynUser);
+printf("%s::%s pAxis=%p\n", driverName, functionName, pAxis);
if (!pAxis) return asynError;
if (nElements > maxProfilePoints_) nElements = maxProfilePoints_;
Now when I write to Prof1:Times from IDL I see this message on the IOC:
asynMotorController::writeFloat64Array pAxis=0x2466fb0
That proves that getAxis is not returning 0, it is returning a pointer to the first axis.
So I don't understand what error was motivating this PR.
Thank you for the answer and sorry for my late response.
I faced with this problem, while writing a driver for a custom controller. It has a bus where axes boards have its internal addresses 128 and 129. And I have to add an address of a board in packages, that I send to it. So I used this addresses, when I created an Axes object. I thought that it is a proper way to use asyn address.
As I do not have axis with address 0 (only 128 and 129), a call of getAxis(pasynUser) for putting profile time array returns nullptr. I assume that in your test there was an axis with address 0. That is why it works fine.
In read/write methods in my controller class I firstly check if pasynUser->reason is related to the controller (and if so handle it), then call getAxis(pasynUser) and handle axis related reasons, and if it is not reason of my driver implementation, I call the base class implementation. That is why other parts of driver works fine for me.
I thought that it is a proper way to use asyn address. And I thought if some one will have controller, that has no axis with address 0, calling writeFloat64Array for putting profile time array will fail.
So, if I an not right, I think I should rewrite my driver implementation to fix my problem without changes in asynMotorController.
But if you think that it is possible to have no axis with address 0 (as in my case), then this PR may be useful.
I think the correct approach is to rewrite the driver implementation to fix the problem without changes to asynMotorController.
profileTimes variable is a part of the asynMotorController class, not asynMotorAxis class. So, in previous version of the asynMotorController::writeFloat64Array function, getAxis will return 0 and profileTimes will not be written.
In this version if (function == profileTimeArray_)... is executed first to fix the problem.