Added version check prototype
This commit is contained in:
@@ -12,6 +12,18 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
These two constants store the major and the minor firmware version this driver
|
||||||
|
needs. The following constraints need to be fulfilled:
|
||||||
|
Actual major version == FIRMWARE_MAJOR_VERSION
|
||||||
|
Actual minor version >= FIRMWARE_MINOR_VERSION
|
||||||
|
If one of these constraints is not fulfilled, the driver will shut down the IOC.
|
||||||
|
If the firmware version cannot be read (e.g. because the variable used to do so
|
||||||
|
does not exist yet), the conditions outlined above are seen as fulfilled.
|
||||||
|
*/
|
||||||
|
const int FIRMWARE_MAJOR_VERSION = 2;
|
||||||
|
const int FIRMWARE_MINOR_VERSION = 2;
|
||||||
|
|
||||||
struct masterMacsControllerImpl {
|
struct masterMacsControllerImpl {
|
||||||
double comTimeout;
|
double comTimeout;
|
||||||
|
|
||||||
@@ -65,6 +77,7 @@ masterMacsController::masterMacsController(const char *portName,
|
|||||||
|
|
||||||
// Initialization of local variables
|
// Initialization of local variables
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
|
char response[MAXBUF_] = {0};
|
||||||
|
|
||||||
pMasterMacsC_ =
|
pMasterMacsC_ =
|
||||||
std::make_unique<masterMacsControllerImpl>((masterMacsControllerImpl){
|
std::make_unique<masterMacsControllerImpl>((masterMacsControllerImpl){
|
||||||
@@ -116,6 +129,55 @@ masterMacsController::masterMacsController(const char *portName,
|
|||||||
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort());
|
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
|
// Check the firmware version according to the conditions outlined in the
|
||||||
|
// comment for FIRMWARE_MAJOR_VERSION and FIRMWARE_MINOR_VERSION
|
||||||
|
status = read(0, 99, response);
|
||||||
|
|
||||||
|
if (status == asynSuccess) {
|
||||||
|
|
||||||
|
// Just interpret the version if the variable already exists
|
||||||
|
double versionRaw = 0.0;
|
||||||
|
int nvals = sscanf(response, "%lf", &versionRaw);
|
||||||
|
if (nvals == 1 && versionRaw != 0.0) {
|
||||||
|
// Discard decimal part
|
||||||
|
long long versionInt = (long long)versionRaw;
|
||||||
|
|
||||||
|
// Extract bugfix (last 3 digits)
|
||||||
|
// Currently not used, just here for completions sake
|
||||||
|
// int bugfix = versionInt % 1000;
|
||||||
|
versionInt /= 1000;
|
||||||
|
|
||||||
|
// Extract minor (next 3 digits)
|
||||||
|
int minor = versionInt % 1000;
|
||||||
|
versionInt /= 1000;
|
||||||
|
|
||||||
|
// Remaining is major
|
||||||
|
int major = (int)versionInt;
|
||||||
|
|
||||||
|
// Compare to target values
|
||||||
|
if (FIRMWARE_MAJOR_VERSION != major ||
|
||||||
|
FIRMWARE_MINOR_VERSION > minor) {
|
||||||
|
asynPrint(
|
||||||
|
this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\" => %s, line %d\nFATAL ERROR (Incorrect "
|
||||||
|
"version number of firmware: Expected major version equal "
|
||||||
|
"to %d, got %d. Expected minor version equal to or larger "
|
||||||
|
"than %d, got %d).\nTerminating IOC",
|
||||||
|
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
FIRMWARE_MAJOR_VERSION, major, FIRMWARE_MINOR_VERSION,
|
||||||
|
minor);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\" => %s, line %d\nCould not read firmware "
|
||||||
|
"version\n",
|
||||||
|
portName, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -199,12 +261,6 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
comTimeout = pMasterMacsC_->comTimeout;
|
comTimeout = pMasterMacsC_->comTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
|
||||||
if (axis == nullptr) {
|
|
||||||
// We already did the error logging directly in getAxis
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the full command depending on the inputs to this function
|
// Build the full command depending on the inputs to this function
|
||||||
if (isRead) {
|
if (isRead) {
|
||||||
snprintf(fullCommand, MAXBUF_ - 1, "%dR%02d\x0D", axisNo, tcpCmd);
|
snprintf(fullCommand, MAXBUF_ - 1, "%dR%02d\x0D", axisNo, tcpCmd);
|
||||||
@@ -286,17 +342,23 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log the overall status (communication successfull or not)
|
// Log the overall status (communication successfull or not)
|
||||||
|
if (axisNo != 0) {
|
||||||
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
|
if (axis == nullptr) {
|
||||||
|
// We already did the error logging directly in getAxis
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
setAxisParamChecked(axis, motorStatusCommsError, false);
|
setAxisParamChecked(axis, motorStatusCommsError, false);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Since the communication failed, there is the possibility that the
|
Since the communication failed, there is the possibility that the
|
||||||
controller is not connected at all to the network. In that case, we
|
controller is not connected at all to the network. In that case, we
|
||||||
cannot be sure that the information read out in the init method of the
|
cannot be sure that the information read out in the init method of
|
||||||
axis is still up-to-date the next time we get a connection. Therefore,
|
the axis is still up-to-date the next time we get a connection.
|
||||||
an info flag is set which the axis object can use at the start of its
|
Therefore, an info flag is set which the axis object can use at the
|
||||||
poll method to try to initialize itself.
|
start of its poll method to try to initialize itself.
|
||||||
*/
|
*/
|
||||||
axis->setNeedInit(true);
|
axis->setNeedInit(true);
|
||||||
|
|
||||||
@@ -314,6 +376,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
setAxisParamChecked(axis, motorStatusCommsError, false);
|
setAxisParamChecked(axis, motorStatusCommsError, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -334,7 +397,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
bool responseValid = false;
|
bool responseValid = false;
|
||||||
int responseStart = 0;
|
int responseStart = 0;
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
int prevConnected = 0;
|
int prevConnected = 1;
|
||||||
char printableCommand[MAXBUF_] = {0};
|
char printableCommand[MAXBUF_] = {0};
|
||||||
char printableResponse[MAXBUF_] = {0};
|
char printableResponse[MAXBUF_] = {0};
|
||||||
|
|
||||||
@@ -342,12 +405,14 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
if (axis == nullptr) {
|
if (axisNo != 0 && axis == nullptr) {
|
||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was the motor previously connected?
|
// Was the motor previously connected?
|
||||||
|
if (axis != nullptr) {
|
||||||
getAxisParamChecked(axis, motorConnected, &prevConnected);
|
getAxisParamChecked(axis, motorConnected, &prevConnected);
|
||||||
|
}
|
||||||
|
|
||||||
// We don't use strlen here since the C string terminator 0x00
|
// We don't use strlen here since the C string terminator 0x00
|
||||||
// occurs in the middle of the char array.
|
// occurs in the middle of the char array.
|
||||||
@@ -371,16 +436,19 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
"connected.\n",
|
"connected.\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
if (axis != nullptr) {
|
||||||
setAxisParamChecked(axis, motorConnected, true);
|
setAxisParamChecked(axis, motorConnected, true);
|
||||||
status = callParamCallbacks();
|
status = callParamCallbacks();
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d:\nCould not update parameter library\n",
|
"%d:\nCould not update parameter library\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if (fullResponse[i] == '\x15') {
|
} else if (fullResponse[i] == '\x15') {
|
||||||
@@ -399,16 +467,19 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
"disconnected.\n",
|
"disconnected.\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
if (axis != nullptr) {
|
||||||
setAxisParamChecked(axis, motorConnected, false);
|
setAxisParamChecked(axis, motorConnected, false);
|
||||||
status = callParamCallbacks();
|
status = callParamCallbacks();
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d:\nCould not update parameter library\n",
|
"%d:\nCould not update parameter library\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} else if (fullResponse[i] == '\x18') {
|
} else if (fullResponse[i] == '\x18') {
|
||||||
// CAN
|
// CAN
|
||||||
|
|||||||
Reference in New Issue
Block a user