Compare commits
10 Commits
AxisParamC
...
1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| c65a8de5dd | |||
| 1910eda0b1 | |||
| 977016bdb4 | |||
| ed77125378 | |||
| 4a0c09bd7f | |||
| 1fe21ec192 | |||
| 2fd4851313 | |||
| 55a9fe6f3e | |||
| e618b39687 | |||
| 41dfd1de5a |
23
.gitea/workflows/action.yaml
Normal file
23
.gitea/workflows/action.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: Test And Build
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Lint:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: cppcheck
|
||||||
|
run: cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
|
||||||
|
- name: formatting
|
||||||
|
run: clang-format --style=file --Werror --dry-run src/*.cpp
|
||||||
|
Build:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
- run: |
|
||||||
|
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
|
||||||
|
make install
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
default:
|
|
||||||
image: docker.psi.ch:5000/sinqdev/sinqepics:latest
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- lint
|
|
||||||
- build
|
|
||||||
- test
|
|
||||||
|
|
||||||
cppcheck:
|
|
||||||
stage: lint
|
|
||||||
script:
|
|
||||||
- cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
|
|
||||||
formatting:
|
|
||||||
stage: lint
|
|
||||||
script:
|
|
||||||
- clang-format --style=file --Werror --dry-run src/*.cpp
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
|
|
||||||
build_module:
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
|
|
||||||
- echo "LIBVERSION=${CI_COMMIT_TAG:-0.0.1}" >> Makefile
|
|
||||||
- make install
|
|
||||||
- cp -rT "/ioc/modules/sinqMotor/$(ls -U /ioc/modules/sinqMotor/ | head -1)" "./sinqMotor-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
|
|
||||||
artifacts:
|
|
||||||
name: "sinqMotor-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
|
|
||||||
paths:
|
|
||||||
- "sinqMotor-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}/*"
|
|
||||||
expire_in: 1 week
|
|
||||||
when: always
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
30
README.md
30
README.md
@@ -230,7 +230,15 @@ It calls `doReset` and performs some fast polls after `doReset` returns.
|
|||||||
- `doMove`: This is an empty function which should be overwritten by concrete driver implementations.
|
- `doMove`: This is an empty function which should be overwritten by concrete driver implementations.
|
||||||
- `home`: This function sets the internal status flags for the homing process and then calls doHome.
|
- `home`: This function sets the internal status flags for the homing process and then calls doHome.
|
||||||
- `doHome`: This is an empty function which should be overwritten by concrete driver implementations.
|
- `doHome`: This is an empty function which should be overwritten by concrete driver implementations.
|
||||||
- `poll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`:
|
- `poll`: This is a wrapper around `forcedPoll` which does the following checks before calling `forcedPoll`:
|
||||||
|
- Are there any outstanding fast polls (method `outstandingForcedFastPolls` of the controller returns a value greater zero)?
|
||||||
|
- Was the axis moving last time its status was polled?
|
||||||
|
- Is adaptive polling disabled?
|
||||||
|
- Did an idle period pass since the last poll?
|
||||||
|
If all of these conditions are false, no poll is performed. Otherwise, the `forcedPoll` method is called.
|
||||||
|
This method should not be called in the driver code itself if a poll is needed - use `forcedPoll` instead!
|
||||||
|
|
||||||
|
- `forcedPoll`: This is a wrapper around `doPoll` which performs some bookkeeping tasks before and after calling `doPoll`:
|
||||||
|
|
||||||
Before calling `doPoll`:
|
Before calling `doPoll`:
|
||||||
- Check if the paramLib already contains an old error message. If so, put it into a temporary bufffer
|
- Check if the paramLib already contains an old error message. If so, put it into a temporary bufffer
|
||||||
@@ -277,18 +285,28 @@ To use the library when writing a concrete motor driver, include it in the makef
|
|||||||
|
|
||||||
### Usage as static dependency
|
### Usage as static dependency
|
||||||
|
|
||||||
This repository is included as a git submodule in some of the driver repositories depending upon sinqMotor. When installing via a Makefile (`make install`) using the PSI build system, the following git command is executed within `/ioc/tools/driver.makefile`:
|
This repository is included as a git submodule in the driver repositories depending upon sinqMotor. When installing via a Makefile (`make install`) using the PSI build system, the following git command is executed within `/ioc/tools/driver.makefile`:
|
||||||
|
|
||||||
`git submodule update --init --recursive`
|
`git submodule update --init --recursive`
|
||||||
|
|
||||||
This forces each submodule to be checked out at the latest commit hash stored in the remote repository. However, this is usually unwanted behaviour, since the higher-level drivers are usually designed to be compiled against a specific version of sinqMotor. In order to set the submodule to a specific version, the following steps need to be done BEFORE calling `make install`:
|
This forces each submodule to be checked out at the latest commit hash stored in the remote repository. However, this is usually unwanted behaviour, since the higher-level drivers are usually designed to be compiled against a specific version of sinqMotor. In order to set the submodule to a specific version, the following steps need to be done BEFORE calling `make install`:
|
||||||
|
|
||||||
- `cd sinqMotor`
|
- `cd sinqMotor`
|
||||||
- `git checkout 0.1`
|
- `git checkout 1.0`
|
||||||
- `cd ..`
|
- `cd ..`
|
||||||
|
|
||||||
Then, the fixation of the version to 0.1 needs to be committed in the parent repository:
|
Then, the fixation of the version to 1.0 needs to be committed in the parent repository:
|
||||||
|
|
||||||
- `git commit -m "Update sinqMotor to 0.1"`
|
- `git commit -m "Update sinqMotor to 1.0"`
|
||||||
|
|
||||||
After this commit, running `make install` will use the correct driver version for compilation.
|
After this commit, running `make install` will use the correct driver version for compilation.
|
||||||
|
|
||||||
|
If your driver uses another driver as a static dependency via git submodule which in turn includes a sinqMotor submodule, it is not necessary to specify the version of sinqMotor. Instead, specify the desired commit of the direct dependency, commit this change and then update all submodules:
|
||||||
|
|
||||||
|
- `cd turboPmac`
|
||||||
|
- `git checkout 1.0`
|
||||||
|
- `cd ..`
|
||||||
|
- `git commit -m "Update turboPmac to 1.0"`
|
||||||
|
- `git submodule update --init --recursive`
|
||||||
|
|
||||||
|
This will update sinqMotor to the version specified in the 1.0 commit of turboPmac.
|
||||||
@@ -171,14 +171,7 @@ sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
|
|||||||
sinqAxis::~sinqAxis() = default;
|
sinqAxis::~sinqAxis() = default;
|
||||||
|
|
||||||
asynStatus sinqAxis::poll(bool *moving) {
|
asynStatus sinqAxis::poll(bool *moving) {
|
||||||
|
|
||||||
// Local variable declaration
|
|
||||||
asynStatus pl_status = asynSuccess;
|
|
||||||
asynStatus poll_status = asynSuccess;
|
|
||||||
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:
|
||||||
@@ -201,22 +194,33 @@ asynStatus sinqAxis::poll(bool *moving) {
|
|||||||
Check if both adaptive polling is enabled and no forced fast polls are still
|
Check if both adaptive polling is enabled and no forced fast polls are still
|
||||||
required.
|
required.
|
||||||
*/
|
*/
|
||||||
if (adaptivePolling != 0 && pC_->outstandingForcedFastPolls() == 0) {
|
if (adaptivePolling != 0 && pC_->outstandingForcedFastPolls() == 0 &&
|
||||||
// Motor wasn't moving during the last poll
|
!pSinqA_->wasMoving) {
|
||||||
if (!pSinqA_->wasMoving) {
|
|
||||||
|
|
||||||
// Add the idle poll period
|
// Add the idle poll period
|
||||||
epicsTimeStamp earliestTimeNextPoll = pSinqA_->lastPollTime;
|
epicsTimeStamp earliestTimeNextPoll = pSinqA_->lastPollTime;
|
||||||
epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod());
|
epicsTimeAddSeconds(&earliestTimeNextPoll, pC_->idlePollPeriod());
|
||||||
|
|
||||||
if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) {
|
if (epicsTimeLessThanEqual(&earliestTimeNextPoll, &ts) == 0) {
|
||||||
*moving = false;
|
*moving = false;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return forcedPoll(moving);
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus sinqAxis::forcedPoll(bool *moving) {
|
||||||
|
|
||||||
|
// Local variable declaration
|
||||||
|
asynStatus pl_status = asynSuccess;
|
||||||
|
asynStatus poll_status = asynSuccess;
|
||||||
|
int homing = 0;
|
||||||
|
char waitingMessage[pC_->MAXBUF_] = {0};
|
||||||
|
char newMessage[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
// Update the start time of the last poll
|
// Update the start time of the last poll
|
||||||
|
epicsTimeStamp ts;
|
||||||
|
epicsTimeGetCurrent(&ts);
|
||||||
pSinqA_->lastPollTime = ts;
|
pSinqA_->lastPollTime = ts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -31,6 +31,27 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
*/
|
*/
|
||||||
~sinqAxis();
|
~sinqAxis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if a poll should be performed. If yes, call `forcedPoll`.
|
||||||
|
*
|
||||||
|
This is a wrapper around `forcedPoll` which does the following checks before
|
||||||
|
calling `forcedPoll`:
|
||||||
|
- Are there any outstanding fast polls (method `outstandingForcedFastPolls`
|
||||||
|
of the controller returns a value greater zero)?
|
||||||
|
- Was the axis moving last time its status was polled?
|
||||||
|
- Is adaptive polling disabled?
|
||||||
|
- Did an idle period pass since the last poll?
|
||||||
|
If all of these conditions are false, no poll is performed. Otherwise, the
|
||||||
|
`forcedPoll` method is called. This method should not be called in the
|
||||||
|
driver code itself if a poll is needed - use `forcedPoll` instead!
|
||||||
|
*
|
||||||
|
* @param moving Forwarded to `forcedPoll` or set to false
|
||||||
|
(depending on whether `forcedPoll was called`).
|
||||||
|
* @return asynStatus Forward the status of `forcedPoll` or set to
|
||||||
|
asynSuccess (depending on whether `forcedPoll was called`).
|
||||||
|
*/
|
||||||
|
virtual asynStatus poll(bool *moving);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Perform some standardized operations before and after the concrete
|
* @brief Perform some standardized operations before and after the concrete
|
||||||
`doPoll` implementation.
|
`doPoll` implementation.
|
||||||
@@ -46,7 +67,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
|
|
||||||
- The flags `motorStatusHome_`, `motorStatusHomed_` and
|
- The flags `motorStatusHome_`, `motorStatusHomed_` and
|
||||||
`motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively)
|
`motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively)
|
||||||
in the `poll()` method once the homing procedure is finished. See the
|
in the `forcedPoll()` method once the homing procedure is finished. See the
|
||||||
documentation of the `home()` method for more details.
|
documentation of the `home()` method for more details.
|
||||||
|
|
||||||
- Run `callParamCallbacks()`
|
- Run `callParamCallbacks()`
|
||||||
@@ -56,9 +77,9 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
* @param moving Forwarded to `doPoll`.
|
* @param moving Forwarded to `doPoll`.
|
||||||
* @return asynStatus Forward the status of `doPoll`, unless one of
|
* @return asynStatus Forward the status of `doPoll`, unless one of
|
||||||
the parameter library operation fails (in that case, returns the status of
|
the parameter library operation fails (in that case, returns the status of
|
||||||
the failed operation.
|
the failed operation).
|
||||||
*/
|
*/
|
||||||
virtual asynStatus poll(bool *moving);
|
asynStatus forcedPoll(bool *moving);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the "proper", device-specific poll method. This
|
* @brief Implementation of the "proper", device-specific poll method. This
|
||||||
@@ -142,7 +163,7 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
*
|
*
|
||||||
* The flags `motorStatusHome_`, `motorStatusHomed_` and
|
* The flags `motorStatusHome_`, `motorStatusHomed_` and
|
||||||
`motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively)
|
`motorStatusAtHome_` are set to their idle values (0, 1 and 1 respectively)
|
||||||
in the `poll()` method once the homing procedure is finished.
|
in the `forcedPoll())` method once the homing procedure is finished.
|
||||||
*
|
*
|
||||||
* @param minVelocity Forwarded to `doHome`.
|
* @param minVelocity Forwarded to `doHome`.
|
||||||
* @param maxVelocity Forwarded to `doHome`.
|
* @param maxVelocity Forwarded to `doHome`.
|
||||||
@@ -505,6 +526,8 @@ asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
|||||||
* This function should not be used directly, but rather through its macro
|
* This function should not be used directly, but rather through its macro
|
||||||
* variant `setAxisParamChecked`.
|
* variant `setAxisParamChecked`.
|
||||||
*
|
*
|
||||||
|
* @tparam A
|
||||||
|
* @tparam C
|
||||||
* @tparam T
|
* @tparam T
|
||||||
* @param axis
|
* @param axis
|
||||||
* @param controller
|
* @param controller
|
||||||
@@ -599,9 +622,9 @@ asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
|||||||
const char *callerFunctionName, int lineNumber,
|
const char *callerFunctionName, int lineNumber,
|
||||||
size_t msgSize, TypeTag<bool>) {
|
size_t msgSize, TypeTag<bool>) {
|
||||||
int readValueInt = 0;
|
int readValueInt = 0;
|
||||||
asynStatus status =
|
asynStatus status = getAxisParamImpl(axis, controller, indexName, func,
|
||||||
getAxisParamImpl(axis, indexName, func, &readValueInt,
|
&readValueInt, callerFunctionName,
|
||||||
callerFunctionName, lineNumber, msgSize);
|
lineNumber, msgSize, TypeTag<int>{});
|
||||||
*readValue = readValueInt != 0;
|
*readValue = readValueInt != 0;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user