Compare commits

..

6 Commits

Author SHA1 Message Date
275672aaef Removed lock in reset and replaced it with wakeupPoller call
Trying to lock the controller from one of its axes may lead to
segfaults, hence it is not advisable.
2025-05-16 15:50:26 +02:00
61c5ec749e Merge branch 'main' of gitea.psi.ch:lin-epics-modules/sinqMotor 2025-05-15 14:26:15 +02:00
1cf4b9ab25 Made some functions virtual so they can be overwritten 2025-05-15 14:26:00 +02:00
a0b674b26e Made some functions virtual so they can be overwritten 2025-05-15 14:24:53 +02:00
e088bfbbcb Added initial value for motorMessageText 2025-05-15 11:39:47 +02:00
3c345e37da Fixed char array undefined symbol bug 2025-05-15 11:25:56 +02:00
2 changed files with 76 additions and 20 deletions

View File

@@ -8,6 +8,17 @@
#include <math.h>
#include <unistd.h>
// Generic fallback - if the compiler tries to compile this function, it fails.
template <typename T>
asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), T writeValue,
const char *callerFunctionName, int lineNumber) {
static_assert(
sizeof(T) == 0,
"no specialization of setAxisParam exists for the given type");
return asynError;
}
template <>
asynStatus setAxisParam<int>(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), int writeValue,
@@ -43,6 +54,20 @@ setAxisParam<double>(sinqAxis *axis, const char *indexName,
return asynSuccess;
}
template <>
asynStatus setAxisParam<char *>(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), char *writeValue,
const char *callerFunctionName,
int lineNumber) {
int indexValue = (axis->pController()->*func)();
asynStatus status = axis->setStringParam(indexValue, writeValue);
if (status != asynSuccess) {
return axis->pController()->paramLibAccessFailed(
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
}
return asynSuccess;
}
template <>
asynStatus setAxisParam<const char *>(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(),
@@ -58,6 +83,17 @@ asynStatus setAxisParam<const char *>(sinqAxis *axis, const char *indexName,
return asynSuccess;
}
// Generic fallback - if the compiler tries to compile this function, it fails.
template <typename T>
asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), T *readValue,
const char *callerFunctionName, int lineNumber) {
static_assert(
sizeof(T) == 0,
"no specialization of getAxisParam exists for the given type");
return asynError;
}
template <>
asynStatus getAxisParam<int>(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), int *readValue,
@@ -112,6 +148,16 @@ asynStatus getAxisParam<char>(sinqAxis *axis, const char *indexName,
return asynSuccess;
}
template <size_t N>
asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
int (sinqController::*func)(), char (&readValue)[N],
const char *callerFunctionName, int lineNumber) {
// Decay the array to char*
return getAxisParam<char>(axis, indexName, func,
static_cast<char *>(readValue),
callerFunctionName, lineNumber);
}
template <>
asynStatus
getAxisParam<std::string>(sinqAxis *axis, const char *indexName,
@@ -159,6 +205,21 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
exit(-1);
}
/*
Initialize the parameter library entry for the motor message text, because
it is read during the first poll before it has been written to.
*/
status = setStringParam(pC_->motorMessageText(), "");
if (status != asynSuccess) {
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
"(setting a parameter value failed "
"with %s)\n. Terminating IOC",
pC->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->stringifyAsynStatus(status));
exit(-1);
}
// Motor is assumed to be enabled
status = setIntegerParam(pC_->motorEnableRBV(), 1);
if (status != asynSuccess) {
@@ -309,7 +370,8 @@ asynStatus sinqAxis::poll(bool *moving) {
"waitingMessage" is briefly put into the paramLib again, then the PVs are
updated and then the message text is cleared again.
*/
getAxisParamChecked(this, motorMessageText, &waitingMessage);
getAxisParamChecked(this, motorMessageText,
static_cast<char *>(waitingMessage));
// Clear the communication
setAxisParamChecked(this, motorStatusCommsError, false);
@@ -331,9 +393,11 @@ asynStatus sinqAxis::poll(bool *moving) {
If doPoll cleared the error message paramLib entry, but an old message
is still waiting, set the old message.
*/
getAxisParamChecked(this, motorMessageText, &newMessage);
getAxisParamChecked(this, motorMessageText,
static_cast<char *>(newMessage));
if (newMessage[0] == '\0') {
setAxisParamChecked(this, motorMessageText, waitingMessage);
setAxisParamChecked(this, motorMessageText,
static_cast<char *>(waitingMessage));
}
setAxisParamChecked(this, motorStatusProblem, true);
} else {
@@ -479,15 +543,7 @@ asynStatus sinqAxis::reset() {
if (status == asynSuccess) {
// Perform some fast polls
pC_->lock();
bool moving = false;
for (int i = 0; i < 5; i++) {
epicsThreadSleep(pC_->movingPollPeriod());
if (poll(&moving) == asynSuccess) {
break;
}
}
pC_->unlock();
pC_->wakeupPoller();
}
status = assertConnected();

View File

@@ -49,7 +49,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
the parameter library operation fails (in that case, returns the status of
the failed operation.
*/
asynStatus poll(bool *moving);
virtual asynStatus poll(bool *moving);
/**
* @brief Implementation of the "proper", device-specific poll method. This
@@ -79,8 +79,8 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
the parameter library operation fails (in that case, returns the failed
operation status).
*/
asynStatus move(double position, int relative, double minVelocity,
double maxVelocity, double acceleration);
virtual asynStatus move(double position, int relative, double minVelocity,
double maxVelocity, double acceleration);
/**
* @brief Implementation of the "proper", device-specific move method. This
@@ -143,8 +143,8 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
the parameter library operation fails (in that case, returns the failed
operation status).
*/
asynStatus home(double minVelocity, double maxVelocity, double acceleration,
int forwards);
virtual asynStatus home(double minVelocity, double maxVelocity,
double acceleration, int forwards);
/**
* @brief Implementation of the "proper", device-specific home method. This
@@ -170,7 +170,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
*
* @return asynStatus
*/
asynStatus reset();
virtual asynStatus reset();
/**
* @brief Implementation of the "proper", device-specific `reset` method.
@@ -240,7 +240,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
used to get the values for the timeout calculation failed, return that
status, otherwise return asynSuccess.
*/
asynStatus startMovTimeoutWatchdog();
virtual asynStatus startMovTimeoutWatchdog();
/**
* @brief Check if the watchdog timed out
@@ -274,7 +274,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
* @return asynStatus Return asynError, if the watchdog timed out,
and asynSuccess otherwise.
*/
asynStatus checkMovTimeoutWatchdog(bool moving);
virtual asynStatus checkMovTimeoutWatchdog(bool moving);
/**
* @brief Enable / disable the watchdog. Also available in the IOC shell