Added function to set the number of forced fast polls.
This commit is contained in:
12
README.md
12
README.md
@ -107,6 +107,11 @@ actualDriverAxis("$(DRIVER_PORT)",5);
|
||||
# Set the number of subsequent timeouts
|
||||
setMaxSubsequentTimeouts("$(DRIVER_PORT)", 20);
|
||||
|
||||
# Set the number of forced fast polls performed after the poller is "woken up".
|
||||
# When the poller is "woken up", it performs the specified number of polls with
|
||||
# the previously stated busy poll period.
|
||||
setForcedFastPolls("$(DRIVER_PORT)", 10);
|
||||
|
||||
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed in 300 seconds before an alarm message is sent.
|
||||
setThresholdComTimeout("$(DRIVER_PORT)", 300, 10);
|
||||
|
||||
@ -153,7 +158,7 @@ be further reduced by this offset in order to avoid errors due to slight oversho
|
||||
on the motor controller. For example, if this value is 1.0 and the read-out limits
|
||||
are [-10.0 10.0], the EPICS limits are set to [-9.0 9.0]. This parameter uses engineering units (EGU). Defaults to 0.0.
|
||||
- `CANSETSPEED`: If set to 1, the motor speed can be modified by the user. Defaults to 0.
|
||||
- `ADAPTPOLL`: If set to any value other than 0, adaptive polling is enabled for this particular axis. Adaptive polling is designed to reduce the communication load in case some axis is moving. By default, if at least one axis is moving, all axes are polled using the busy / moving poll period (see [IOC startup script](#ioc-startup-script)). Adaptive polling modifies this behaviour so that the affected axis is only polled with the busy / moving poll period if it itself is moving. Defaults to 1.
|
||||
- `ADAPTPOLL`: If set to any value other than 0, adaptive polling is enabled for this particular axis. Adaptive polling is designed to reduce the communication load in case some axis is moving. By default, if at least one axis is moving, all axes are polled using the busy / moving poll period (see [IOC startup script](#ioc-startup-script)). Adaptive polling modifies this behaviour so that the affected axis is only polled with the busy / moving poll period if it itself is moving. This setting is ignored for "forced fast polls" (when the poller is woken up, e.g. after an axis received a move command). Defaults to 1.
|
||||
|
||||
### Motor record resolution MRES
|
||||
|
||||
@ -210,9 +215,10 @@ sinqMotor offers a variety of additional methods for children classes to standar
|
||||
- `paramLibAccessFailed`: Write a standardized message if accessing the parameter library failed.
|
||||
- `stringifyAsynStatus`: Convert the enum `asynStatus` into a human-readable string.
|
||||
- `checkComTimeoutWatchdog`: Calculates the timeout frequency (number of timeouts in a given time) and informs the user if a specified limit has been exceeded.
|
||||
- `setThresholdComTimeout`: Set the maximum number of timeouts and the time window size for the timeout frequency limit.
|
||||
- `setThresholdComTimeout`: Set the maximum number of timeouts and the time window size for the timeout frequency limit. This function is also available in the IOC shell.
|
||||
- `checkMaxSubsequentTimeouts`: Check if the number of subsequent timeouts exceeds a specified limit.
|
||||
- `setMaxSubsequentTimeouts`: Set the limit for the number of subsequent timeouts before the user is informed.
|
||||
- `setMaxSubsequentTimeouts`: Set the limit for the number of subsequent timeouts before the user is informed. This function is also available in the IOC shell.
|
||||
- `setForcedFastPolls`: Set the number of forced fast polls which are performed after the poller has been "woken up" ( = after `wakePoller()` is called). This function is also available in the IOC shell.
|
||||
|
||||
#### sinqAxis.h
|
||||
- `enable`: This function is called if the `$(INSTR)$(M):Enable` PV from db/sinqMotor.db is set.
|
||||
|
@ -645,6 +645,8 @@ extern "C" {
|
||||
* @brief Set the threshold for the communication timeout frequency (FFI
|
||||
* implementation)
|
||||
*
|
||||
* @param portName Name of the low-level asyn port the controller is
|
||||
* using.
|
||||
* @param comTimeoutWindow Size of the time window used to calculate
|
||||
* the moving average of timeout events in seconds. Set this value to 0 to
|
||||
* deactivate the watchdog.
|
||||
@ -688,11 +690,10 @@ static void setThresholdComTimeoutCallFunc(const iocshArgBuf *args) {
|
||||
/**
|
||||
* @brief Set the maximum number of subsequent timeouts (FFI implementation)
|
||||
*
|
||||
* @param comTimeoutWindow Size of the time window used to calculate
|
||||
* the moving average of timeout events. Set this value to 0 to deactivate
|
||||
* the watchdog.
|
||||
* @param maxNumberTimeouts Maximum number of timeouts which may occur
|
||||
* within the time window before the watchdog is triggered.
|
||||
* @param portName Name of the low-level asyn port the controller is
|
||||
* using.
|
||||
* @param maxSubsequentTimeouts Maximum number of timeouts which may occur
|
||||
* subsequently before an error is reported.
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus setMaxSubsequentTimeouts(const char *portName,
|
||||
@ -746,12 +747,73 @@ static void setMaxSubsequentTimeoutsCallFunc(const iocshArgBuf *args) {
|
||||
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @brief Set the number of forced fast polls which happen after a call to
|
||||
* `wakePoller`.
|
||||
*
|
||||
* @param portName Name of the low-level asyn port the controller is
|
||||
* using.
|
||||
* @param forcedFastPolls Number of fast polls done after calling
|
||||
* `wakePoller`.
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus setForcedFastPolls(const char *portName, int forcedFastPolls) {
|
||||
void *ptr = findAsynPortDriver(portName);
|
||||
if (ptr == nullptr) {
|
||||
/*
|
||||
We can't use asynPrint here since this macro would require us
|
||||
to get a pasynOctetSyncIOipPort_ from a pointer to an asynPortDriver.
|
||||
However, the given pointer is a nullptr and therefore doesn't
|
||||
have a pasynOctetSyncIOipPort_! printf is an EPICS alternative which
|
||||
works w/o that, but doesn't offer the comfort provided
|
||||
by the asynTrace-facility
|
||||
*/
|
||||
errlogPrintf("Controller \"%s\" => %s, line %d:\nPort %s not found.",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__, portName);
|
||||
return asynError;
|
||||
}
|
||||
// Unsafe cast of the pointer to an asynPortDriver
|
||||
asynPortDriver *apd = (asynPortDriver *)(ptr);
|
||||
|
||||
// Safe downcast
|
||||
sinqController *pC = dynamic_cast<sinqController *>(apd);
|
||||
if (pC == nullptr) {
|
||||
errlogPrintf(
|
||||
"Controller \"%s\" => %s, line %d:\ncontroller on port %s is not a "
|
||||
"turboPmacController.",
|
||||
portName, __PRETTY_FUNCTION__, __LINE__, portName);
|
||||
return asynError;
|
||||
}
|
||||
|
||||
// Set the new value
|
||||
pC->setForcedFastPolls(forcedFastPolls);
|
||||
|
||||
return asynSuccess;
|
||||
}
|
||||
|
||||
static const iocshArg SetForcedFastPollsArg0 = {"Controller name (e.g. mcu1)",
|
||||
iocshArgString};
|
||||
static const iocshArg SetForcedFastPollsArg1 = {
|
||||
"Number of fast polls after \"waking\" the poller (e.g. after issueing a "
|
||||
"move command).",
|
||||
iocshArgInt};
|
||||
static const iocshArg *const SetForcedFastPollsArgs[] = {
|
||||
&SetForcedFastPollsArg0, &SetForcedFastPollsArg1};
|
||||
static const iocshFuncDef setForcedFastPollsDef = {"setForcedFastPolls", 2,
|
||||
SetForcedFastPollsArgs};
|
||||
static void setForcedFastPollsCallFunc(const iocshArgBuf *args) {
|
||||
setForcedFastPolls(args[0].sval, args[1].ival);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// This function is made known to EPICS in sinqMotor.dbd and is called by EPICS
|
||||
// in order to register all functions in the IOC shell
|
||||
static void sinqControllerRegister(void) {
|
||||
iocshRegister(&setThresholdComTimeoutDef, setThresholdComTimeoutCallFunc);
|
||||
iocshRegister(&setMaxSubsequentTimeoutsDef,
|
||||
setMaxSubsequentTimeoutsCallFunc);
|
||||
iocshRegister(&setForcedFastPollsDef, setForcedFastPollsCallFunc);
|
||||
}
|
||||
epicsExportRegistrar(sinqControllerRegister);
|
||||
|
||||
|
@ -341,6 +341,12 @@ class epicsShareClass sinqController : public asynMotorController {
|
||||
* initializes the `outstandingForcedFastPolls` variable and then defers to
|
||||
* the base class method.
|
||||
*
|
||||
* The `wakePoller` function of the base class `asynController` sends a
|
||||
* signal to the poller thread which forces the latter to perform a number
|
||||
* of fast / busy polls with the busy poll period regardless of whether the
|
||||
* motor is moving or not. The number of polls is specified by
|
||||
* "forcedFastPolls()" and can be set with `setForcedFastPolls()`.
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus wakeupPoller();
|
||||
|
Reference in New Issue
Block a user