mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-06 01:50:40 +02:00
updating kernel like program fpga, execute command to print which module failed, unlinking temporary file while programming bug fix
This commit is contained in:
parent
98cf908918
commit
6e49b77b08
@ -20,7 +20,7 @@ This document describes the differences between vx.x.x and v6.0.0.
|
|||||||
1. New or Changed Features
|
1. New or Changed Features
|
||||||
==========================
|
==========================
|
||||||
- kernelversion
|
- kernelversion
|
||||||
|
- updatekernel
|
||||||
|
|
||||||
|
|
||||||
2. Resolved Issues
|
2. Resolved Issues
|
||||||
@ -30,6 +30,8 @@ This document describes the differences between vx.x.x and v6.0.0.
|
|||||||
- rx id in config file was not taken into account. fixed.
|
- rx id in config file was not taken into account. fixed.
|
||||||
- programming firmware failure for blackfin, fixed but requires new kernel.
|
- programming firmware failure for blackfin, fixed but requires new kernel.
|
||||||
- nios kernel check updated (ensuring right kernel)
|
- nios kernel check updated (ensuring right kernel)
|
||||||
|
- executecommand now says which module failed
|
||||||
|
- programming firmware did not delete temporary file created. fixed.
|
||||||
|
|
||||||
3. Known Issues
|
3. Known Issues
|
||||||
===============
|
===============
|
||||||
|
@ -1520,7 +1520,10 @@ void init_det(py::module &m) {
|
|||||||
(void (Detector::*)(const std::string &, const std::string &,
|
(void (Detector::*)(const std::string &, const std::string &,
|
||||||
sls::Positions)) &
|
sls::Positions)) &
|
||||||
Detector::copyDetectorServer,
|
Detector::copyDetectorServer,
|
||||||
py::arg(), py::arg(), py::arg() = Positions{})
|
.def("updateKernel",
|
||||||
|
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||||
|
Detector::updateKernel,
|
||||||
|
py::arg(), py::arg() = Positions{})
|
||||||
.def("rebootController",
|
.def("rebootController",
|
||||||
(void (Detector::*)(sls::Positions)) & Detector::rebootController,
|
(void (Detector::*)(sls::Positions)) & Detector::rebootController,
|
||||||
py::arg() = Positions{})
|
py::arg() = Positions{})
|
||||||
|
@ -277,4 +277,5 @@ int get_udp_first_dest(int);
|
|||||||
int set_udp_first_dest(int);
|
int set_udp_first_dest(int);
|
||||||
int get_readout_speed(int);
|
int get_readout_speed(int);
|
||||||
int set_readout_speed(int);
|
int set_readout_speed(int);
|
||||||
int get_kernel_version(int);
|
int get_kernel_version(int);
|
||||||
|
int copy_kernel(int);
|
@ -415,6 +415,8 @@ void function_table() {
|
|||||||
flist[F_GET_READOUT_SPEED] = &get_readout_speed;
|
flist[F_GET_READOUT_SPEED] = &get_readout_speed;
|
||||||
flist[F_SET_READOUT_SPEED] = &set_readout_speed;
|
flist[F_SET_READOUT_SPEED] = &set_readout_speed;
|
||||||
flist[F_GET_KERNEL_VERSION] = &get_kernel_version;
|
flist[F_GET_KERNEL_VERSION] = &get_kernel_version;
|
||||||
|
flist[F_COPY_KERNEL] = ©_kernel;
|
||||||
|
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||||
@ -9434,3 +9436,139 @@ int get_kernel_version(int file_des) {
|
|||||||
}
|
}
|
||||||
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
|
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int copy_kernel(int file_des) {
|
||||||
|
ret = OK;
|
||||||
|
memset(mess, 0, sizeof(mess));
|
||||||
|
char args[2][MAX_STR_LENGTH];
|
||||||
|
char retvals[MAX_STR_LENGTH] = {0};
|
||||||
|
|
||||||
|
memset(args, 0, sizeof(args));
|
||||||
|
memset(retvals, 0, sizeof(retvals));
|
||||||
|
|
||||||
|
if (receiveData(file_des, args, sizeof(args), OTHER) < 0)
|
||||||
|
return printSocketReadError();
|
||||||
|
|
||||||
|
#ifdef VIRTUAL
|
||||||
|
functionNotImplemented();
|
||||||
|
#else
|
||||||
|
|
||||||
|
// only set
|
||||||
|
if (Server_VerifyLock() == OK) {
|
||||||
|
char *sname = args[0];
|
||||||
|
char *hostname = args[1];
|
||||||
|
LOG(logINFOBLUE, ("Copying kernel image %s from host %s\n", sname, hostname));
|
||||||
|
char cmd[MAX_STR_LENGTH] = {0};
|
||||||
|
|
||||||
|
// tftp server
|
||||||
|
char *format = "tftp %s -r %s -g";
|
||||||
|
if (snprintf(cmd, MAX_STR_LENGTH, format, hostname, sname) >=
|
||||||
|
MAX_STR_LENGTH) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not copy detector server. Command to copy "
|
||||||
|
"server too long\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (tftp). %s\n", retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tServer copied\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// give permissions
|
||||||
|
if (ret == OK) {
|
||||||
|
if (snprintf(cmd, MAX_STR_LENGTH, "chmod 777 %s", sname) >=
|
||||||
|
MAX_STR_LENGTH) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not copy detector server. Command to give "
|
||||||
|
"permissions to server is too long\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (permissions). %s\n",
|
||||||
|
retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tPermissions modified\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// symbolic link
|
||||||
|
if (ret == OK) {
|
||||||
|
if (snprintf(cmd, MAX_STR_LENGTH, "ln -sf %s %s", sname,
|
||||||
|
LINKED_SERVER_NAME) >= MAX_STR_LENGTH) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not copy detector server. Command to "
|
||||||
|
"create symbolic link too long\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (symbolic link). %s\n",
|
||||||
|
retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tSymbolic link created\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blackfin boards (respawn) (only kept for backwards compatibility)
|
||||||
|
#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || \
|
||||||
|
defined(GOTTHARDD)
|
||||||
|
// delete every line with DetectorServer in /etc/inittab
|
||||||
|
if (ret == OK) {
|
||||||
|
strcpy(cmd, "sed -i '/DetectorServer/d' /etc/inittab");
|
||||||
|
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(
|
||||||
|
mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (del respawning). %s\n",
|
||||||
|
retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tinittab: DetectoServer line deleted\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new link name to /etc/inittab
|
||||||
|
if (ret == OK) {
|
||||||
|
format = "echo 'ttyS0::respawn:/./%s' >> /etc/inittab";
|
||||||
|
if (snprintf(cmd, MAX_STR_LENGTH, format, LINKED_SERVER_NAME) >=
|
||||||
|
MAX_STR_LENGTH) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not copy detector server. Command "
|
||||||
|
"to add new server for spawning is too long\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (respawning). %s\n",
|
||||||
|
retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tinittab: updated for respawning\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// sync
|
||||||
|
if (ret == OK) {
|
||||||
|
strcpy(cmd, "sync");
|
||||||
|
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
snprintf(mess, MAX_STR_LENGTH,
|
||||||
|
"Could not copy detector server (sync). %s\n",
|
||||||
|
retvals);
|
||||||
|
// LOG(logERROR, (mess)); already printed in executecommand
|
||||||
|
} else {
|
||||||
|
LOG(logINFO, ("\tsync\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
|
||||||
|
}
|
@ -1744,6 +1744,14 @@ class Detector {
|
|||||||
void copyDetectorServer(const std::string &fname,
|
void copyDetectorServer(const std::string &fname,
|
||||||
const std::string &hostname, Positions pos = {});
|
const std::string &hostname, Positions pos = {});
|
||||||
|
|
||||||
|
/** [Jungfrau][Ctb][Moench][Mythen3][Gotthard2] \n
|
||||||
|
* Advanced Command!! You could damage the detector. Please use with
|
||||||
|
* caution.\nUpdates the kernel image. Then, detector controller reboots
|
||||||
|
* with new kernel
|
||||||
|
*/
|
||||||
|
void updateKernel(const std::string &fname, Positions pos = {});
|
||||||
|
|
||||||
|
|
||||||
/** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] Advanced user
|
/** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] Advanced user
|
||||||
* Function! */
|
* Function! */
|
||||||
void rebootController(Positions pos = {});
|
void rebootController(Positions pos = {});
|
||||||
|
@ -2853,7 +2853,7 @@ std::string CmdProxy::CopyDetectorServer(int action) {
|
|||||||
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
||||||
"Gotthard2] Copies detector server via tftp from pc. Ensure that "
|
"Gotthard2] Copies detector server via tftp from pc. Ensure that "
|
||||||
"server is in the pc's tftp folder. Makes a symbolic link with a "
|
"server is in the pc's tftp folder. Makes a symbolic link with a "
|
||||||
"shorter name (without vx.x.x). Then, detector reboots (except "
|
"shorter name (without vx.x.x). Then, detector controller reboots (except "
|
||||||
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
||||||
"to the link, which is effective after a reboot."
|
"to the link, which is effective after a reboot."
|
||||||
<< '\n';
|
<< '\n';
|
||||||
@ -2871,6 +2871,27 @@ std::string CmdProxy::CopyDetectorServer(int action) {
|
|||||||
return os.str();
|
return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CmdProxy::UpdateKernel(int action) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << cmd << ' ';
|
||||||
|
if (action == defs::HELP_ACTION) {
|
||||||
|
os << "[kernel_name with full path]\n\t[Jungfrau][Ctb][Moench][Mythen3]["
|
||||||
|
"Gotthard2] Advanced Command!! You could damage the detector. Please use" "with caution.\n\tUpdates the kernel image. Then, detector controller " "reboots with new kernel."
|
||||||
|
<< '\n';
|
||||||
|
} else if (action == defs::GET_ACTION) {
|
||||||
|
throw sls::RuntimeError("Cannot get");
|
||||||
|
} else if (action == defs::PUT_ACTION) {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
WrongNumberOfParameters(1);
|
||||||
|
}
|
||||||
|
det->updateKernel(args[0], std::vector<int>{det_id});
|
||||||
|
os << "successful\n";
|
||||||
|
} else {
|
||||||
|
throw sls::RuntimeError("Unknown action");
|
||||||
|
}
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << cmd << ' ';
|
os << cmd << ' ';
|
||||||
|
@ -1059,6 +1059,7 @@ class CmdProxy {
|
|||||||
{"programfpga", &CmdProxy::ProgramFpga},
|
{"programfpga", &CmdProxy::ProgramFpga},
|
||||||
{"resetfpga", &CmdProxy::resetfpga},
|
{"resetfpga", &CmdProxy::resetfpga},
|
||||||
{"copydetectorserver", &CmdProxy::CopyDetectorServer},
|
{"copydetectorserver", &CmdProxy::CopyDetectorServer},
|
||||||
|
{"updatekernel", &CmdProxy::UpdateKernel},
|
||||||
{"rebootcontroller", &CmdProxy::rebootcontroller},
|
{"rebootcontroller", &CmdProxy::rebootcontroller},
|
||||||
{"update", &CmdProxy::UpdateFirmwareAndDetectorServer},
|
{"update", &CmdProxy::UpdateFirmwareAndDetectorServer},
|
||||||
{"reg", &CmdProxy::Register},
|
{"reg", &CmdProxy::Register},
|
||||||
@ -1183,6 +1184,7 @@ class CmdProxy {
|
|||||||
/* Advanced */
|
/* Advanced */
|
||||||
std::string ProgramFpga(int action);
|
std::string ProgramFpga(int action);
|
||||||
std::string CopyDetectorServer(int action);
|
std::string CopyDetectorServer(int action);
|
||||||
|
std::string UpdateKernel(int action);
|
||||||
std::string UpdateFirmwareAndDetectorServer(int action);
|
std::string UpdateFirmwareAndDetectorServer(int action);
|
||||||
std::string Register(int action);
|
std::string Register(int action);
|
||||||
std::string AdcRegister(int action);
|
std::string AdcRegister(int action);
|
||||||
|
@ -2150,6 +2150,12 @@ void Detector::copyDetectorServer(const std::string &fname,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Detector::updateKernel(const std::string &fname, Positions pos) {
|
||||||
|
std::vector<char> buffer = pimpl->readKernelFile(fname);
|
||||||
|
pimpl->Parallel(&Module::updateKernel, pos, buffer);
|
||||||
|
rebootController(pos);
|
||||||
|
}
|
||||||
|
|
||||||
void Detector::rebootController(Positions pos) {
|
void Detector::rebootController(Positions pos) {
|
||||||
pimpl->Parallel(&Module::rebootController, pos);
|
pimpl->Parallel(&Module::rebootController, pos);
|
||||||
}
|
}
|
||||||
@ -2240,7 +2246,7 @@ Result<sls::IpAddr> Detector::getLastClientIP(Positions pos) const {
|
|||||||
|
|
||||||
Result<std::string> Detector::executeCommand(const std::string &value,
|
Result<std::string> Detector::executeCommand(const std::string &value,
|
||||||
Positions pos) {
|
Positions pos) {
|
||||||
return pimpl->Parallel(&Module::execCommand, pos, value);
|
return pimpl->Parallel(&Module::executeCommand, pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<int64_t> Detector::getNumberOfFramesFromStart(Positions pos) const {
|
Result<int64_t> Detector::getNumberOfFramesFromStart(Positions pos) const {
|
||||||
|
@ -1386,8 +1386,70 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
|||||||
"Program FPGA: Could not close destination file after converting");
|
"Program FPGA: Could not close destination file after converting");
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlink(destfname); // delete temporary file
|
unlink(destfname); // delete temporary file
|
||||||
LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
|
LOG(logDEBUG1) << "Read file into memory";
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> DetectorImpl::readKernelFile(const std::string &fname) {
|
||||||
|
// validate type of file
|
||||||
|
bool isPof = false;
|
||||||
|
switch (shm()->detType) {
|
||||||
|
case JUNGFRAU:
|
||||||
|
case CHIPTESTBOARD:
|
||||||
|
case MOENCH:
|
||||||
|
if (fname.find(".lzma") == std::string::npos) {
|
||||||
|
throw RuntimeError("Kernel image file must be a lzma file.");
|
||||||
|
}
|
||||||
|
isPof = true;
|
||||||
|
break;
|
||||||
|
case MYTHEN3:
|
||||||
|
case GOTTHARD2:
|
||||||
|
if (fname.find(".bin") == std::string::npos) {
|
||||||
|
throw RuntimeError("Kernel image file must be an bin file.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw RuntimeError("Programming kernel image via the package is not implemented for this detector");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(logINFO)
|
||||||
|
<< "Updating Kernel...";
|
||||||
|
LOG(logDEBUG1) << "Programming kernel image with file name:" << fname;
|
||||||
|
|
||||||
|
// check if it exists
|
||||||
|
struct stat st;
|
||||||
|
if (stat(fname.c_str(), &st) != 0) {
|
||||||
|
throw RuntimeError("Program kernel: file does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(fname.c_str(), "rb");
|
||||||
|
if (fp == nullptr) {
|
||||||
|
throw RuntimeError(
|
||||||
|
"Program kernel: Could not open file: " +
|
||||||
|
fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get file size to print progress
|
||||||
|
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||||
|
throw RuntimeError("Program kernel: Seek error in src file");
|
||||||
|
}
|
||||||
|
size_t filesize = ftell(fp);
|
||||||
|
if (filesize <= 0) {
|
||||||
|
throw RuntimeError("Program kernel: Could not get length of file");
|
||||||
|
}
|
||||||
|
rewind(fp);
|
||||||
|
|
||||||
|
std::vector<char> buffer(filesize, 0);
|
||||||
|
if (fread(buffer.data(), sizeof(char), filesize, fp) != filesize) {
|
||||||
|
throw RuntimeError("Program kernel: Could not read file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fclose(fp) != 0) {
|
||||||
|
throw RuntimeError(
|
||||||
|
"Program kernel: Could not close file");
|
||||||
|
}
|
||||||
|
|
||||||
LOG(logDEBUG1) << "Read file into memory";
|
LOG(logDEBUG1) << "Read file into memory";
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -284,13 +284,22 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert raw file
|
* Convert raw file
|
||||||
* [Jungfrau][Ctb] from pof file
|
* [Jungfrau][Ctb][Moench] from pof file
|
||||||
* [Mythen3][Gotthard2] from rbf file
|
* [Mythen3][Gotthard2] from rbf file
|
||||||
* @param fname name of pof/rbf file
|
* @param fname name of pof/rbf file
|
||||||
* @returns binary of the program
|
* @returns binary of the program
|
||||||
*/
|
*/
|
||||||
std::vector<char> readProgrammingFile(const std::string &fname);
|
std::vector<char> readProgrammingFile(const std::string &fname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read file into memory
|
||||||
|
* [Jungfrau][Ctb][Moench] from lzma file
|
||||||
|
* [Mythen3][Gotthard2] from bin file
|
||||||
|
* @param fname name of file
|
||||||
|
* @returns binary of the program
|
||||||
|
*/
|
||||||
|
std::vector<char> readKernelFile(const std::string &fname);
|
||||||
|
|
||||||
sls::Result<int> getNumberofUDPInterfaces(Positions pos) const;
|
sls::Result<int> getNumberofUDPInterfaces(Positions pos) const;
|
||||||
void setNumberofUDPInterfaces(int n, Positions pos);
|
void setNumberofUDPInterfaces(int n, Positions pos);
|
||||||
sls::Result<int> getDefaultDac(defs::dacIndex index,
|
sls::Result<int> getDefaultDac(defs::dacIndex index,
|
||||||
|
@ -2492,7 +2492,7 @@ void Module::programFPGA(std::vector<char> buffer) {
|
|||||||
programFPGAviaNios(buffer);
|
programFPGAviaNios(buffer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw RuntimeError("Program FPGA is not implemented for this detector");
|
throw RuntimeError("Programming FPGA via the package is not implemented for this detector");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2503,7 +2503,8 @@ void Module::copyDetectorServer(const std::string &fname,
|
|||||||
char args[2][MAX_STR_LENGTH]{};
|
char args[2][MAX_STR_LENGTH]{};
|
||||||
sls::strcpy_safe(args[0], fname.c_str());
|
sls::strcpy_safe(args[0], fname.c_str());
|
||||||
sls::strcpy_safe(args[1], hostname.c_str());
|
sls::strcpy_safe(args[1], hostname.c_str());
|
||||||
LOG(logINFO) << "Sending detector server " << args[0] << " from host "
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Sending detector server " << args[0] << " from host "
|
||||||
<< args[1];
|
<< args[1];
|
||||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
client.Send(F_COPY_DET_SERVER);
|
client.Send(F_COPY_DET_SERVER);
|
||||||
@ -2519,9 +2520,26 @@ void Module::copyDetectorServer(const std::string &fname,
|
|||||||
<< "): detector server copied";
|
<< "): detector server copied";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::updateKernel(std::vector<char> buffer) {
|
||||||
|
switch (shm()->detType) {
|
||||||
|
case JUNGFRAU:
|
||||||
|
case CHIPTESTBOARD:
|
||||||
|
case MOENCH:
|
||||||
|
updateKernelviaBlackfin(buffer);
|
||||||
|
break;
|
||||||
|
case MYTHEN3:
|
||||||
|
case GOTTHARD2:
|
||||||
|
updateKernelviaNios(buffer);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw RuntimeError("Updating Kernel via the package is not implemented for this detector");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Module::rebootController() {
|
void Module::rebootController() {
|
||||||
sendToDetector(F_REBOOT_CONTROLLER);
|
sendToDetector(F_REBOOT_CONTROLLER);
|
||||||
LOG(logINFO) << "Controller rebooted successfully!";
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Controller rebooted successfully!";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Module::readRegister(uint32_t addr) const {
|
uint32_t Module::readRegister(uint32_t addr) const {
|
||||||
@ -2599,11 +2617,25 @@ sls::IpAddr Module::getLastClientIP() const {
|
|||||||
return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP);
|
return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Module::execCommand(const std::string &cmd) {
|
std::string Module::executeCommand(const std::string &cmd) {
|
||||||
char arg[MAX_STR_LENGTH]{};
|
char arg[MAX_STR_LENGTH]{};
|
||||||
char retval[MAX_STR_LENGTH]{};
|
char retval[MAX_STR_LENGTH]{};
|
||||||
sls::strcpy_safe(arg, cmd.c_str());
|
sls::strcpy_safe(arg, cmd.c_str());
|
||||||
sendToDetector(F_EXEC_COMMAND, arg, retval);
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Sending command " << cmd;
|
||||||
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
|
client.Send(F_EXEC_COMMAND);
|
||||||
|
client.Send(arg);
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::cout << '\n';
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
client.Receive(retval);
|
||||||
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): command executed";
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3409,8 +3441,8 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
|||||||
|
|
||||||
void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||||
// send program from memory to detector
|
// send program from memory to detector
|
||||||
LOG(logINFO) << "Sending programming binary (from pof) to module "
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
<< "): Sending programming binary (from pof)";
|
||||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
client.Send(F_PROGRAM_FPGA);
|
client.Send(F_PROGRAM_FPGA);
|
||||||
uint64_t filesize = buffer.size();
|
uint64_t filesize = buffer.size();
|
||||||
@ -3516,12 +3548,13 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
|||||||
<< " returned error: " << client.readErrorMessage();
|
<< " returned error: " << client.readErrorMessage();
|
||||||
throw DetectorError(os.str());
|
throw DetectorError(os.str());
|
||||||
}
|
}
|
||||||
LOG(logINFO) << "FPGA programmed successfully";
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): FPGA programmed successfully";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::programFPGAviaNios(std::vector<char> buffer) {
|
void Module::programFPGAviaNios(std::vector<char> buffer) {
|
||||||
LOG(logINFO) << "Sending programming binary (from rbf) to Module "
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
<< "): Sending programming binary (from rbf)";
|
||||||
|
|
||||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
client.Send(F_PROGRAM_FPGA);
|
client.Send(F_PROGRAM_FPGA);
|
||||||
@ -3594,6 +3627,112 @@ void Module::programFPGAviaNios(std::vector<char> buffer) {
|
|||||||
<< " returned error: " << client.readErrorMessage();
|
<< " returned error: " << client.readErrorMessage();
|
||||||
throw DetectorError(os.str());
|
throw DetectorError(os.str());
|
||||||
}
|
}
|
||||||
LOG(logINFO) << "FPGA programmed successfully";
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): FPGA programmed successfully";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::updateKernelviaBlackfin(std::vector<char> buffer) {
|
||||||
|
// send program from memory to detector
|
||||||
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Sending kernel image (.lzma)";
|
||||||
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
|
client.Send(F_PROGRAM_KERNEL);
|
||||||
|
uint64_t filesize = buffer.size();
|
||||||
|
client.Send(filesize);
|
||||||
|
|
||||||
|
// checksum
|
||||||
|
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||||
|
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||||
|
char cChecksum[MAX_STR_LENGTH];
|
||||||
|
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||||
|
strcpy(cChecksum, checksum.c_str());
|
||||||
|
client.Send(cChecksum);
|
||||||
|
|
||||||
|
// opening file fail
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::cout << '\n';
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// sending program in parts of 2mb each
|
||||||
|
uint64_t unitprogramsize = 0;
|
||||||
|
int currentPointer = 0;
|
||||||
|
while (filesize > 0) {
|
||||||
|
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||||
|
if (unitprogramsize > filesize) { // less than 2mb
|
||||||
|
unitprogramsize = filesize;
|
||||||
|
}
|
||||||
|
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
|
||||||
|
<< "\t filesize:" << filesize;
|
||||||
|
|
||||||
|
client.Send(&buffer[currentPointer], unitprogramsize);
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::cout << '\n';
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
filesize -= unitprogramsize;
|
||||||
|
currentPointer += unitprogramsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checksum
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
|
||||||
|
<< shm()->hostname << ")";
|
||||||
|
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Kernel udpated successfully";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::updateKernelviaNios(std::vector<char> buffer) {
|
||||||
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Sending kernel image (from rbf)";
|
||||||
|
|
||||||
|
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||||
|
client.Send(F_PROGRAM_FPGA);
|
||||||
|
uint64_t filesize = buffer.size();
|
||||||
|
client.Send(filesize);
|
||||||
|
|
||||||
|
// checksum
|
||||||
|
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||||
|
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||||
|
char cChecksum[MAX_STR_LENGTH];
|
||||||
|
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||||
|
strcpy(cChecksum, checksum.c_str());
|
||||||
|
client.Send(cChecksum);
|
||||||
|
|
||||||
|
// validate file size before sending program
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
client.Send(buffer);
|
||||||
|
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw DetectorError(os.str());
|
||||||
|
}
|
||||||
|
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||||
|
<< "): Kernel updated successfully";
|
||||||
}
|
}
|
||||||
} // namespace sls
|
} // namespace sls
|
||||||
|
@ -541,6 +541,7 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
void resetFPGA();
|
void resetFPGA();
|
||||||
void copyDetectorServer(const std::string &fname,
|
void copyDetectorServer(const std::string &fname,
|
||||||
const std::string &hostname);
|
const std::string &hostname);
|
||||||
|
void updateKernel(std::vector<char> buffer);
|
||||||
void rebootController();
|
void rebootController();
|
||||||
uint32_t readRegister(uint32_t addr) const;
|
uint32_t readRegister(uint32_t addr) const;
|
||||||
uint32_t writeRegister(uint32_t addr, uint32_t val);
|
uint32_t writeRegister(uint32_t addr, uint32_t val);
|
||||||
@ -565,7 +566,7 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
bool getLockDetector() const;
|
bool getLockDetector() const;
|
||||||
void setLockDetector(bool lock);
|
void setLockDetector(bool lock);
|
||||||
sls::IpAddr getLastClientIP() const;
|
sls::IpAddr getLastClientIP() const;
|
||||||
std::string execCommand(const std::string &cmd);
|
std::string executeCommand(const std::string &cmd);
|
||||||
int64_t getNumberOfFramesFromStart() const;
|
int64_t getNumberOfFramesFromStart() const;
|
||||||
int64_t getActualTime() const;
|
int64_t getActualTime() const;
|
||||||
int64_t getMeasurementTime() const;
|
int64_t getMeasurementTime() const;
|
||||||
@ -748,6 +749,8 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
bool trimbits = true);
|
bool trimbits = true);
|
||||||
void programFPGAviaBlackfin(std::vector<char> buffer);
|
void programFPGAviaBlackfin(std::vector<char> buffer);
|
||||||
void programFPGAviaNios(std::vector<char> buffer);
|
void programFPGAviaNios(std::vector<char> buffer);
|
||||||
|
void updateKernelviaBlackfin(std::vector<char> buffer);
|
||||||
|
void updateKernelviaNios(std::vector<char> buffer);
|
||||||
|
|
||||||
const int moduleIndex;
|
const int moduleIndex;
|
||||||
mutable sls::SharedMemory<sharedModule> shm{0, 0};
|
mutable sls::SharedMemory<sharedModule> shm{0, 0};
|
||||||
|
@ -2708,6 +2708,25 @@ TEST_CASE("copydetectorserver", "[.cmd]") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("updatekernel", "[.cmd]") {
|
||||||
|
Detector det;
|
||||||
|
CmdProxy proxy(&det);
|
||||||
|
auto det_type = det.getDetectorType().squash();
|
||||||
|
if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
|
||||||
|
det_type == defs::MOENCH || det_type == defs::MYTHEN3 ||
|
||||||
|
det_type == defs::GOTTHARD2) {
|
||||||
|
// TODO: send real server?
|
||||||
|
// std::ostringstream oss;
|
||||||
|
// proxy.Call("updatekernel",{"juImage_detector.lzma",
|
||||||
|
// "pc13784"}, -1, PUT, oss);
|
||||||
|
// REQUIRE(oss.str() == "updatekernel successful\n");
|
||||||
|
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, GET));
|
||||||
|
} else {
|
||||||
|
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, GET));
|
||||||
|
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, PUT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("rebootcontroller", "[.cmd]") {
|
TEST_CASE("rebootcontroller", "[.cmd]") {
|
||||||
Detector det;
|
Detector det;
|
||||||
CmdProxy proxy(&det);
|
CmdProxy proxy(&det);
|
||||||
|
@ -254,6 +254,7 @@ enum detFuncs {
|
|||||||
F_GET_READOUT_SPEED,
|
F_GET_READOUT_SPEED,
|
||||||
F_SET_READOUT_SPEED,
|
F_SET_READOUT_SPEED,
|
||||||
F_GET_KERNEL_VERSION,
|
F_GET_KERNEL_VERSION,
|
||||||
|
F_COPY_KERNEL,
|
||||||
|
|
||||||
NUM_DET_FUNCTIONS,
|
NUM_DET_FUNCTIONS,
|
||||||
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
||||||
@ -610,6 +611,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
|||||||
case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED";
|
case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED";
|
||||||
case F_SET_READOUT_SPEED: return "F_SET_READOUT_SPEED";
|
case F_SET_READOUT_SPEED: return "F_SET_READOUT_SPEED";
|
||||||
case F_GET_KERNEL_VERSION: return "F_GET_KERNEL_VERSION";
|
case F_GET_KERNEL_VERSION: return "F_GET_KERNEL_VERSION";
|
||||||
|
case F_COPY_KERNEL: return "F_COPY_KERNEL";
|
||||||
|
|
||||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user