Simplified paramLib access and show error messages for one poll cycle
Simplified getting and setting paramLib entries via a macro and created a mechanism within poll() which makes sure that error messages are shown for at least one poll cycle. Also moved MAXBUF_ to the SinqController level.
This commit is contained in:
@ -233,13 +233,14 @@ It calls `doReset` and performs some fast polls after `doReset` returns.
|
|||||||
- `poll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`:
|
- `poll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`:
|
||||||
|
|
||||||
Before calling `doPoll`:
|
Before calling `doPoll`:
|
||||||
- Reset the status problem flag, the communication error flag and the error message.
|
- Check if the paramLib already contains an old error message. If so, put it into a temporary bufffer
|
||||||
|
|
||||||
After calling `doPoll`:
|
After calling `doPoll`:
|
||||||
- Call `checkMovTimeoutWatchdog`. If the movement timed out, create an error message for the user
|
- Call `checkMovTimeoutWatchdog`. If the movement timed out, create an error message for the user
|
||||||
- Update the readback-value for the axis enablement.
|
- Update the readback-value for the axis enablement.
|
||||||
- Reset `motorStatusProblem_`, `motorStatusCommsError_` and `motorMessageText_` if `doPoll` returned `asynSuccess`
|
- If `doPoll` returns anything other than `asynSuccess` or if an old error message is waiting in the temporary buffer, set `motorStatusProblem` to true, otherwise to false. If an old error message is waiting in the temporary buffer, but `doPoll` returned `asynSuccess`, overwrite the paramLib entry for `motorMessageText` with the old error message.
|
||||||
- Run `callParamCallbacks`
|
- Run `callParamCallbacks`
|
||||||
|
- Reset `motorMessageText` AFTER updating the PVs. This makes sure that the error message is shown for at least one poll cycle.
|
||||||
- Return the status of `doPoll`
|
- Return the status of `doPoll`
|
||||||
- `motorPosition`: Returns the parameter library value of the motor position, accounted for the motor record resolution (see section "Motor record resolution MRES")
|
- `motorPosition`: Returns the parameter library value of the motor position, accounted for the motor record resolution (see section "Motor record resolution MRES")
|
||||||
- `setMotorPosition`: Writes the given value into the parameter library, accounted for the motor record resolution (see section "Motor record resolution MRES")
|
- `setMotorPosition`: Writes the given value into the parameter library, accounted for the motor record resolution (see section "Motor record resolution MRES")
|
||||||
|
@ -100,7 +100,7 @@ asynStatus getAxisParam<char>(sinqAxis *axis, const char *indexName,
|
|||||||
int (sinqController::*func)(), char *readValue,
|
int (sinqController::*func)(), char *readValue,
|
||||||
const char *callerFunctionName, int lineNumber) {
|
const char *callerFunctionName, int lineNumber) {
|
||||||
|
|
||||||
int maxChars = 190;
|
int maxChars = 200;
|
||||||
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
int indexValue = (axis->pController()->*func)();
|
||||||
asynStatus status = axis->pController()->getStringParam(
|
asynStatus status = axis->pController()->getStringParam(
|
||||||
@ -259,6 +259,8 @@ asynStatus sinqAxis::poll(bool *moving) {
|
|||||||
asynStatus poll_status = asynSuccess;
|
asynStatus poll_status = asynSuccess;
|
||||||
int homing = 0;
|
int homing = 0;
|
||||||
int adaptivePolling = 0;
|
int adaptivePolling = 0;
|
||||||
|
char waitingMessage[pC_->MAXBUF_] = {0};
|
||||||
|
char newMessage[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If adaptive polling is enabled:
|
If adaptive polling is enabled:
|
||||||
@ -300,35 +302,42 @@ asynStatus sinqAxis::poll(bool *moving) {
|
|||||||
lastPollTime_ = ts;
|
lastPollTime_ = ts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
At the beginning of the poll, it is assumed that the axis has no status
|
If the "motorMessageText" record currently contains an error message, it
|
||||||
problems and therefore all error indicators are reset. This does not affect
|
should be shown for at least one poll period. To assure this, it is read out
|
||||||
the PVs until callParamCallbacks has been called!
|
here from the paramLib into "waitingMessage". If no new error message was
|
||||||
|
added to the parameter library at the end of the poll cycle, the
|
||||||
The motorStatusProblem_ field changes the motor record fields SEVR and STAT.
|
"waitingMessage" is briefly put into the paramLib again, then the PVs are
|
||||||
|
updated and then the message text is cleared again.
|
||||||
*/
|
*/
|
||||||
setAxisParamChecked(this, motorStatusCommsError, false);
|
getAxisParamChecked(this, motorMessageText, &waitingMessage);
|
||||||
setAxisParamChecked(this, motorMessageText, "");
|
|
||||||
|
|
||||||
// The poll function is just a wrapper around doPoll and
|
// Clear the communication
|
||||||
// handles mainly the callParamCallbacks() function. This wrapper is used
|
setAxisParamChecked(this, motorStatusCommsError, false);
|
||||||
// to make sure callParamCallbacks() is called in case of a premature
|
|
||||||
// return.
|
/*
|
||||||
|
The poll function is just a wrapper around doPoll and handles mainly the
|
||||||
|
callParamCallbacks() function. This wrapper is used to make sure
|
||||||
|
callParamCallbacks() is called in case of a premature return.
|
||||||
|
*/
|
||||||
poll_status = doPoll(moving);
|
poll_status = doPoll(moving);
|
||||||
|
|
||||||
// If the poll did not succeed, something went wrong and the motor has a
|
/*
|
||||||
// status problem.
|
If the poll did not succeed OR if an error message is waiting, something
|
||||||
if (poll_status == asynSuccess) {
|
went wrong and the motor has a status problem. Otherwise, delete the error
|
||||||
setAxisParamChecked(this, motorStatusProblem, false);
|
message entry which is currently in the paramLib.
|
||||||
} else {
|
*/
|
||||||
|
if (poll_status != asynSuccess || waitingMessage[0] != '\0') {
|
||||||
setAxisParamChecked(this, motorStatusProblem, true);
|
setAxisParamChecked(this, motorStatusProblem, true);
|
||||||
|
} else {
|
||||||
|
setAxisParamChecked(this, motorMessageText, "");
|
||||||
|
setAxisParamChecked(this, motorStatusProblem, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAxisParamChecked(this, motorStatusHome, &homing);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Motor is in homing mode, was moving, but is not moving anymore -> It can be
|
Motor is in homing mode, was moving, but is not moving anymore -> It can be
|
||||||
assumed that the homing procedure is done.
|
assumed that the homing procedure is done.
|
||||||
*/
|
*/
|
||||||
|
getAxisParamChecked(this, motorStatusHome, &homing);
|
||||||
if (homing == 1 && !(*moving) && wasMoving_) {
|
if (homing == 1 && !(*moving) && wasMoving_) {
|
||||||
setAxisParamChecked(this, motorStatusHome, false);
|
setAxisParamChecked(this, motorStatusHome, false);
|
||||||
setAxisParamChecked(this, motorStatusHomed, true);
|
setAxisParamChecked(this, motorStatusHomed, true);
|
||||||
@ -363,6 +372,12 @@ asynStatus sinqAxis::poll(bool *moving) {
|
|||||||
poll_status = pl_status;
|
poll_status = pl_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete the error message AFTER updating the PVs so it is not there anymore
|
||||||
|
during the next poll.
|
||||||
|
*/
|
||||||
|
setAxisParamChecked(this, motorMessageText, "");
|
||||||
|
|
||||||
return poll_status;
|
return poll_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +431,6 @@ asynStatus sinqAxis::home(double minVelocity, double maxVelocity,
|
|||||||
|
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
|
|
||||||
setAxisParamChecked(this, motorMessageText, "Reference drive");
|
|
||||||
setAxisParamChecked(this, motorStatusHome, true);
|
setAxisParamChecked(this, motorStatusHome, true);
|
||||||
setAxisParamChecked(this, motorStatusHomed, false);
|
setAxisParamChecked(this, motorStatusHomed, false);
|
||||||
setAxisParamChecked(this, motorStatusAtHome, false);
|
setAxisParamChecked(this, motorStatusAtHome, false);
|
||||||
|
@ -500,40 +500,8 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* return asynSuccess;
|
* return asynSuccess;
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*
|
|
||||||
* If `readValue` is a `char *`, the size of the buffer needs to be provided as
|
|
||||||
* well:
|
|
||||||
* ```
|
|
||||||
* char readValue[20] = {0};
|
|
||||||
* getAxisParamChecked(this, motorStatusProblem_, &readValue, sizeof(readValue))
|
|
||||||
* ```
|
|
||||||
* expands to
|
|
||||||
* ```
|
|
||||||
* {
|
|
||||||
* int indexValue = axis->pController()->motorStatusProblem_();
|
|
||||||
* asynStatus status = axis->pController()->getStringParam(axis->axisNo(),
|
|
||||||
* indexValue, sizeof(readValue), readValue); if (status != asynSuccess) {
|
|
||||||
* return axis->pController()->paramLibAccessFailed( status,
|
|
||||||
* "motorStatusProblem_", axis->axisNo(), __PRETTY_FUNCTION__,
|
|
||||||
* __LINE__);
|
|
||||||
* }
|
|
||||||
* return asynSuccess;
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
// #define getAxisParamChecked(axis, indexGetterFunction, readValue, ...) \
|
|
||||||
// { \
|
|
||||||
// asynStatus getStatus = getAxisParam( \
|
|
||||||
// axis, #indexGetterFunction, \
|
|
||||||
// &std::remove_pointer< \
|
|
||||||
// decltype(axis->pController())>::type::indexGetterFunction, \
|
|
||||||
// readValue, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
||||||
// if (getStatus != asynSuccess) { \
|
|
||||||
// return getStatus; \
|
|
||||||
// } \
|
|
||||||
// }
|
|
||||||
|
|
||||||
#define getAxisParamChecked(axis, indexGetterFunction, readValue) \
|
#define getAxisParamChecked(axis, indexGetterFunction, readValue) \
|
||||||
{ \
|
{ \
|
||||||
asynStatus getStatus = getAxisParam( \
|
asynStatus getStatus = getAxisParam( \
|
||||||
|
@ -490,17 +490,12 @@ asynStatus sinqController::checkComTimeoutWatchdog(int axisNo,
|
|||||||
|
|
||||||
asynStatus sinqController::checkComTimeoutWatchdog(sinqAxis *axis) {
|
asynStatus sinqController::checkComTimeoutWatchdog(sinqAxis *axis) {
|
||||||
|
|
||||||
char motorMessage[200] = {0};
|
char errorMessage[MAXBUF_] = {0};
|
||||||
|
|
||||||
asynStatus status =
|
asynStatus status =
|
||||||
checkComTimeoutWatchdog(axis->axisNo(), motorMessage, 200);
|
checkComTimeoutWatchdog(axis->axisNo(), errorMessage, MAXBUF_);
|
||||||
if (status == asynError) {
|
if (status == asynError) {
|
||||||
status = axis->setStringParam(motorMessageText_, motorMessage);
|
setAxisParamChecked(axis, motorMessageText, motorMessage);
|
||||||
if (status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(status, "motorMessageText_",
|
|
||||||
axis->axisNo(), __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -543,17 +538,12 @@ asynStatus sinqController::checkMaxSubsequentTimeouts(int timeoutNo, int axisNo,
|
|||||||
asynStatus sinqController::checkMaxSubsequentTimeouts(int timeoutNo,
|
asynStatus sinqController::checkMaxSubsequentTimeouts(int timeoutNo,
|
||||||
sinqAxis *axis) {
|
sinqAxis *axis) {
|
||||||
|
|
||||||
char motorMessage[200] = {0};
|
char motorMessage[MAXBUF_] = {0};
|
||||||
|
|
||||||
asynStatus status = checkMaxSubsequentTimeouts(timeoutNo, axis->axisNo(),
|
asynStatus status = checkMaxSubsequentTimeouts(timeoutNo, axis->axisNo(),
|
||||||
motorMessage, 200);
|
motorMessage, MAXBUF_);
|
||||||
if (status == asynError) {
|
if (status == asynError) {
|
||||||
status = axis->setStringParam(motorMessageText_, motorMessage);
|
setAxisParamChecked(axis, motorMessageText, motorMessage);
|
||||||
if (status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(status, "motorMessageText_",
|
|
||||||
axis->axisNo(), __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -376,6 +376,11 @@ class epicsShareClass sinqController : public asynMotorController {
|
|||||||
*/
|
*/
|
||||||
int outstandingForcedFastPolls() { return outstandingForcedFastPolls_; }
|
int outstandingForcedFastPolls() { return outstandingForcedFastPolls_; }
|
||||||
|
|
||||||
|
// Maximum error message buffer size. This is an empirical value which must
|
||||||
|
// be large enough to avoid overflows for all commands to the device /
|
||||||
|
// responses from it.
|
||||||
|
static const uint32_t MAXBUF_ = 200;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Reference in New Issue
Block a user