-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ticket 4831 cryosms simple start #2
Ticket 4831 cryosms simple start #2
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very complicated IOC. The structure of the db file is good and it seems to cover most of the funcitonality required well. Most of the changes suggested are minor bug fixes and documentation, which is pretty good given the complexity of the device. 👍
I think it would be useful to add to the wiki page which parameters we expect the users to change, and a brief comment saying that IOC initialisation is done in the asyn driver and why. This will make it clearer to someone supporting this device.
It is worth thinking if any of the PVs should be labelled as interesting and archived.
When I ran the IOC system tests there was quite a lot of errors because of mismatches in the protocols which normally we wouldn't expect to see. There might need to be some work on the emulator and the protocol files to fix these bugs.
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
else { | ||
const char *magMode = "Non Persistent"; | ||
|
||
status = putDb("MAGNET:MODE", &magMode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the behaviour will be here, it appears that a string is getting written to a binary (bo) record?
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
|
||
} | ||
|
||
if (std::getenv("USE_SWITCH") == "Yes" && (std::getenv("SWITCH_TEMP_PV") == NULL || std::getenv("SWITCH_HIGH") == NULL || std::getenv("SWITCH_LOW") == NULL || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The switching variables are different here to the specification documentation. SWITCH_TIMEOUT
is missing from this list, and SWITCH_TOLERANCE
, SWITCH_TEMP_TOLERANCE
, HEATER_OUT
have been added?
} | ||
|
||
setHeaterValue { | ||
out "S H %f"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is different to the design document, which specifies SH
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the design document is incorrect in this instance, command is indeed S H
cryosmsSup/cryosms.db
Outdated
record(scalcout, "$(P)OUTPUT") | ||
{ | ||
field(DESC, "Output from the PSU in $(DISPLAY_UNIT)") | ||
field(FLNK, "$(P)GAUSS") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pointing to a PV which does not exist. Is this PV missing or should it be pointing somewhere else?
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
else { | ||
return asynSuccess; | ||
} | ||
} | ||
|
||
asynStatus CRYOSMSDriver::onStart() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's important that the logic here is tested so we are aware if we introduce a bug at a later date. I recommend splitting the if statements up into logical chunks and using googletest to unit test each chunk.
{ | ||
field(DESC, "Raw value returned from the PSU, A or T")# returned during a “GO” command | ||
field(DTYP, "stream") | ||
field(INP, "@cryosms.proto getOutput($(P)) $(PORT)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This protocol also has a mismatch with the emulator, it looks like a CRLF at the end of the return statement. See the devsim logs.
{ | ||
field(DESC, "The status of the ramp from the PSU") | ||
field(DTYP, "stream") | ||
field(INP, "@cryosms.proto getRampStatus $(PORT)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mismatches when running against emulator
@@ -95,8 +448,8 @@ extern "C" | |||
} | |||
// EPICS iocsh shell commands | |||
|
|||
static const iocshArg initArg0 = { "portName", iocshArgString }; ///< A name for the asyn driver instance we will create - used to refer to it from EPICS DB files | |||
static const iocshArg initArg1 = { "devicePrefix", iocshArgString }; | |||
static const iocshArg initArg0 = { "portName", iocshArgString }; ///< Port to connect to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Much clearer
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
else { | ||
return asynSuccess; | ||
} | ||
} | ||
|
||
asynStatus CRYOSMSDriver::onStart() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When started through the IOC test framework these were the commands issued over asyn (logged using an asyn trace mask). This is a different order to what I was expecting from the specification for the cryo sms:
SET TPA 0.037000
T OFF
SET MAX 135.000000
SET RAMP 1.120000
P
HEATER
GET SIGN
T ON
T
RAMP STATUS
GET O
GET RATE
T
If this is the expected command set on booting with the parameters in the IOC test framework this should be noted in the documentation
@@ -2,15 +2,28 @@ | |||
# Database and stream protocol file for Cryogenic Ltd SMS series superconducting magnet controller commands | |||
# | |||
|
|||
record(bi, "$(P)SIM") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SIM and DISABLE records are common to all IOCs to make sure that records behave correctly in recsim. Is there a reason that they have been removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much tidier now, the bulk of my comments fall in to either documentation (e.g. docstrings for the new functions) and error handling (e.g. adding errors to the IOC log file). The google tests are a really useful tool to keep this maintainable in the future.
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
|
||
asynStatus CRYOSMSDriver::checkMaxVolt() | ||
{ | ||
asynStatus status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
status
is the return value for this function, but I can't see where it's modified here. Perhaps this should be initialised to asynSuccess or similar? This applies to other functions
asynStatus CRYOSMSDriver::checkWriteUnit() | ||
{ | ||
asynStatus status; | ||
int trueVal = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use c++ booleans instead of defining your own?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to set the pvs to their desired states we need to pass a reference to the required integers. I chose to name them trueVal and falseVal purely for readability.
|
||
### RAMP: | ||
|
||
record(bo, "$(P)RAMP:LEADS") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this record need ONAM and ZNAM set to true/false?
else { | ||
status = readFile(envVarMap.at("RAMP_FILE")); | ||
if (status != asynSuccess) { | ||
this->writeDisabled = TRUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this condition also have something written to the STAT pv?
CRYOSMSApp/src/tests/CRYOSMSTests.cc
Outdated
ASSERT_EQ(testDriver->writeDisabled, 0); | ||
} | ||
|
||
TEST_F(StartupTests, test_GIVEN_use_switch_yes_WHEN_a_required_value_null_THEN_write_disabled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, tests like this would be parameterised such that we know that all combinations of NULL/not NULL work for all the environment variables. However, testing one is absolutely good enough, especially given the size of the ticket. I don't suggest these changes unless it's a trivial (<20 minute) job
int main(int argc, char **argv) { | ||
::testing::InitGoogleTest(&argc, argv); | ||
return RUN_ALL_TESTS(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a new line at the end of the file
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
pRate_ = (epicsFloat64 *)calloc(INIT_ROW_NUM, sizeof(epicsFloat64)); | ||
pMaxT_ = (epicsFloat64 *)calloc(INIT_ROW_NUM, sizeof(epicsFloat64)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not immediately obvious what these variables do and why they are constructed like this, a comment explaining this would be useful. Becuase they call calloc
, it's also important to call free
after they are no longer useful to stop a memory leak.
"USE_MAGNET_TEMP", "MAGNET_TEMP_PV", "MAX_MAGNET_TEMP", "MIN_MAGNET_TEMP", "COMP_OFF_ACT", "NO_OF_COMP", "MIN_NO_OF_COMP_ON", "COMP_1_STAT_PV", "COMP_2_STAT_PV", "RAMP_FILE" }; | ||
for (std::string envVar : envVarsNames) | ||
{ | ||
envVarMap.insert(std::pair<std::string, const char* >(envVar, std::getenv(envVar.c_str()))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 This is a really good way of ensuring that all the environment variables are available here and can be modified by the tests
…ple_start fixed branches
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
If not supplied, disables puts and posts relevant status message | ||
*/ | ||
{ | ||
asynStatus status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialise to asynSuccess?
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
{ | ||
/* Checks if the user wants to send data to the PSU in units of amps. Sends this choice to the machine if so, otherwise defaults to tesla. | ||
*/ | ||
asynStatus status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialise to asynSuccess
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
FAST:ZERO and RAMP:LEADS to 0 and disable them. | ||
*/ | ||
{ | ||
asynStatus status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialise
CRYOSMSApp/src/CRYOSMSDriver.cpp
Outdated
into memory, then read the current field value from the device and send back an appropriate ramp rate based on the ramp table. | ||
*/ | ||
{ | ||
asynStatus status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialise
ASSERT_EQ(testDriver->writeDisabled, 1); | ||
} | ||
|
||
TEST_F(StartupTests, test_GIVEN_allow_persist_yes_WHEN_required_values_exist_THEN_write_enabled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can there be a test for the case when allow_persist isn't set to yes
? Could also be applied to other functions
CRYOSMSApp/src/tests/CRYOSMSTests.cc
Outdated
} | ||
TEST_F(StartupTests, test_GIVEN_IOC_WHEN_use_magnet_temp_not_yes_THEN_nothing_happens) | ||
{ | ||
testDriver->envVarMap["USE_MAGNET_TEMP"] = "Yes"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sets use_magnet_temp
to yes?
Description of work
IOC now performs startup logic
To test
ISISComputingGroup/IBEX#4831
Acceptance criteria
new tests pass
Code Review
Functional Tests
..._0n
wheren>1
) run correctlymacLib: macro
to find instances ofmacLib: macro [macro name] is undefined...