client done

This commit is contained in:
maliakal_d 2021-11-08 14:26:53 +01:00
parent 54ee4ec653
commit 7b4f8c118b
14 changed files with 253 additions and 387 deletions

View File

@ -1520,6 +1520,9 @@ 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,
.def("updateDetectorServer",
(void (Detector::*)(const std::string &, sls::Positions)) &
Detector::updateDetectorServer,
.def("updateKernel", .def("updateKernel",
(void (Detector::*)(const std::string &, sls::Positions)) & (void (Detector::*)(const std::string &, sls::Positions)) &
Detector::updateKernel, Detector::updateKernel,

View File

@ -38,10 +38,6 @@ void rebootControllerAndFPGA() {
int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc, int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
uint64_t fsize) { uint64_t fsize) {
if (verifyChecksumFromBuffer(mess, checksum, fpgasrc, fsize) == FAIL) {
return FAIL;
}
if (getDrive(mess) == FAIL) { if (getDrive(mess) == FAIL) {
return FAIL; return FAIL;
} }

View File

@ -3778,12 +3778,12 @@ void program_fpga_via_blackfin(int file_des, enum PROGRAMINDEX index,
return; return;
} }
// copy to flash // erase and copy to flash
ret = copyToFlash(index, messageType, totalsize, checksum, mess); ret = copyToFlash(index, messageType, totalsize, checksum, mess);
Server_SendResult(file_des, INT32, NULL, 0); Server_SendResult(file_des, INT32, NULL, 0);
} }
int program_fpga_via_nios(int file_des, uint64_t filesize, char *checksum) { void program_fpga_via_nios(int file_des, uint64_t filesize, char *checksum) {
// validate file size // validate file size
if (filesize > NIOS_MAX_APP_IMAGE_SIZE) { if (filesize > NIOS_MAX_APP_IMAGE_SIZE) {
ret = FAIL; ret = FAIL;
@ -3794,18 +3794,43 @@ int program_fpga_via_nios(int file_des, uint64_t filesize, char *checksum) {
(long long unsigned int)NIOS_MAX_APP_IMAGE_SIZE); (long long unsigned int)NIOS_MAX_APP_IMAGE_SIZE);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} }
// memory allocation
char *src = NULL;
if (ret == OK) {
src = malloc(filesize);
if (src == NULL) {
fclose(fd);
struct sysinfo info;
sysinfo(&info);
sprintf(mess,
"Could not allocate memory to get %s. Free "
"space: %d MB\n",
messageType, (int)(info.freeram / (1024 * 1024)));
LOG(logERROR, (mess));
ret = FAIL;
}
}
Server_SendResult(file_des, INT32, NULL, 0); Server_SendResult(file_des, INT32, NULL, 0);
if (ret == FAIL) { if (ret == FAIL) {
return; return;
} }
// receive program // receive program
char *src = malloc(filesize);
if (receiveData(file_des, src, filesize, OTHER) < 0) { if (receiveData(file_des, src, filesize, OTHER) < 0) {
free(src); free(src);
ret = printSocketReadError(); ret = printSocketReadError();
return; return;
} }
// checksum of copied program
if (ret == OK) {
ret = verifyChecksumFromBuffer(mess, checksum, src, fsize);
}
Server_SendResult(file_des, INT32, NULL, 0);
if (ret == FAIL) {
return;
}
// erase and program // erase and program
ret = eraseAndWriteToFlash(mess, checksum, src, filesize); ret = eraseAndWriteToFlash(mess, checksum, src, filesize);
Server_SendResult(file_des, INT32, NULL, 0); Server_SendResult(file_des, INT32, NULL, 0);

View File

@ -1744,14 +1744,21 @@ 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][Eiger][Ctb][Moench][Mythen3][Gotthard2] Copies detector
* server via TCP (without tftp).\nMakes a symbolic link with a shorter
* name (without vx.x.x).\nThen, detector controller reboots (except
* Eiger).\n[Jungfrau][Ctb][Moench]Also changes respawn server to the
* link, which is effective after a reboot.
*/
void updateDetectorServer(const std::string &fname, Positions pos = {});
/** [Jungfrau][Ctb][Moench][Mythen3][Gotthard2] \n /** [Jungfrau][Ctb][Moench][Mythen3][Gotthard2] \n
* Advanced Command!! You could damage the detector. Please use with * Advanced Command!! You could damage the detector. Please use with
* caution.\nUpdates the kernel image. Then, detector controller reboots * caution.\nUpdates the kernel image. Then, detector controller reboots
* with new kernel * with new kernel
*/ */
void updateKernel(const std::string &fname, Positions pos = {}); 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 = {});

View File

@ -285,12 +285,14 @@ std::string CmdProxy::Versions(int action) {
os << "\nFirmware Version: " << OutStringHex(t); os << "\nFirmware Version: " << OutStringHex(t);
} }
os << "\nDetector Server Version: " os << "\nDetector Server Version: "
<< OutStringHex(det->getDetectorServerVersion(std::vector<int>{det_id})); << OutStringHex(
det->getDetectorServerVersion(std::vector<int>{det_id}));
os << "\nDetector Server Version: " os << "\nDetector Server Version: "
<< OutString(det->getKernelVersion({std::vector<int>{det_id}})); << OutString(det->getKernelVersion({std::vector<int>{det_id}}));
if (det->getUseReceiverFlag().squash(true)) { if (det->getUseReceiverFlag().squash(true)) {
os << "\nReceiver Version: " os << "\nReceiver Version: "
<< OutStringHex(det->getReceiverVersion(std::vector<int>{det_id})); << OutStringHex(
det->getReceiverVersion(std::vector<int>{det_id}));
} }
os << std::dec << '\n'; os << std::dec << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
@ -1432,7 +1434,9 @@ std::string CmdProxy::UDPDestinationList(int action) {
throw sls::RuntimeError("udp_dstlist must be at module level."); throw sls::RuntimeError("udp_dstlist must be at module level.");
} }
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) { if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
throw sls::RuntimeError(std::string("Invalid receiver index ") + std::to_string(rx_id) + std::string(" to set round robin entry.")); throw sls::RuntimeError(std::string("Invalid receiver index ") +
std::to_string(rx_id) +
std::string(" to set round robin entry."));
} }
auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id}); auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
@ -2851,9 +2855,10 @@ std::string CmdProxy::CopyDetectorServer(int action) {
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[server_name (in tftp folder)] " os << "[server_name (in tftp folder)] "
"[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 controller 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,12 +2876,43 @@ std::string CmdProxy::CopyDetectorServer(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::UpdateDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[server_name with full "
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
"Gotthard2] Copies detector server via TCP (without tftp). Makes "
"a symbolic link with a shorter name (without vx.x.x). Then, "
"detector controller reboots (except "
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
"to the link, which is effective after a reboot."
<< '\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->updateDetectorServer(args[0], std::vector<int>{det_id});
os << "successful\n";
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::UpdateKernel(int action) { std::string CmdProxy::UpdateKernel(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[kernel_name with full path]\n\t[Jungfrau][Ctb][Moench][Mythen3][" os << "[kernel_name with full "
"Gotthard2] Advanced Command!! You could damage the detector. Please use" "with caution.\n\tUpdates the kernel image. Then, detector controller " "reboots with new kernel." "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'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get"); throw sls::RuntimeError("Cannot get");

View File

@ -1059,6 +1059,7 @@ class CmdProxy {
{"programfpga", &CmdProxy::ProgramFpga}, {"programfpga", &CmdProxy::ProgramFpga},
{"resetfpga", &CmdProxy::resetfpga}, {"resetfpga", &CmdProxy::resetfpga},
{"copydetectorserver", &CmdProxy::CopyDetectorServer}, {"copydetectorserver", &CmdProxy::CopyDetectorServer},
{"updatedetectorserver", &CmdProxy::UpdateDetectorServer},
{"updatekernel", &CmdProxy::UpdateKernel}, {"updatekernel", &CmdProxy::UpdateKernel},
{"rebootcontroller", &CmdProxy::rebootcontroller}, {"rebootcontroller", &CmdProxy::rebootcontroller},
{"update", &CmdProxy::UpdateFirmwareAndDetectorServer}, {"update", &CmdProxy::UpdateFirmwareAndDetectorServer},
@ -1184,6 +1185,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 UpdateDetectorServer(int action);
std::string UpdateKernel(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);

View File

@ -9,6 +9,7 @@
#include "Module.h" #include "Module.h"
#include "sls/Pattern.h" #include "sls/Pattern.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
@ -2133,6 +2134,7 @@ void Detector::setAdditionalJsonParameter(const std::string &key,
// Advanced // Advanced
void Detector::programFPGA(const std::string &fname, Positions pos) { void Detector::programFPGA(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Firmware...";
std::vector<char> buffer = pimpl->readProgrammingFile(fname); std::vector<char> buffer = pimpl->readProgrammingFile(fname);
pimpl->Parallel(&Module::programFPGA, pos, buffer); pimpl->Parallel(&Module::programFPGA, pos, buffer);
rebootController(pos); rebootController(pos);
@ -2144,14 +2146,25 @@ void Detector::resetFPGA(Positions pos) {
void Detector::copyDetectorServer(const std::string &fname, void Detector::copyDetectorServer(const std::string &fname,
const std::string &hostname, Positions pos) { const std::string &hostname, Positions pos) {
LOG(logINFO) << "Updating Detector Server (via tftp)...";
pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname); pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname);
if (getDetectorType().squash() != defs::EIGER) { if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos); rebootController(pos);
} }
} }
void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Detector Server...";
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer);
if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos);
}
}
void Detector::updateKernel(const std::string &fname, Positions pos) { void Detector::updateKernel(const std::string &fname, Positions pos) {
std::vector<char> buffer = pimpl->readKernelFile(fname); LOG(logINFO) << "Updating Kernel...";
std::vector<char> buffer = readBinaryFile(fname, "Update Kernel");
pimpl->Parallel(&Module::updateKernel, pos, buffer); pimpl->Parallel(&Module::updateKernel, pos, buffer);
rebootController(pos); rebootController(pos);
} }
@ -2164,6 +2177,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname,
const std::string &hostname, const std::string &hostname,
const std::string &fname, const std::string &fname,
Positions pos) { Positions pos) {
LOG(logINFO) << "Updating Firmware and Detector Server...";
pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname); pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname);
programFPGA(fname, pos); programFPGA(fname, pos);
} }

View File

@ -12,6 +12,7 @@
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
#include "sls/string_utils.h" #include "sls/string_utils.h"
@ -1361,91 +1362,10 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
} }
LOG(logINFOBLUE) << "File has been converted to " << destfname; LOG(logINFOBLUE) << "File has been converted to " << destfname;
// loading dst file to memory // load converted file to memory
// FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r"); std::vector<char> buffer = readBinaryFile(destfname, "Program FPGA");
FILE *fp = fopen(destfname, "r"); // delete temporary
if (fp == nullptr) { unlink(destfname);
throw RuntimeError("Program FPGA: Could not open rawbin file");
}
if (fseek(fp, 0, SEEK_END) != 0) {
throw RuntimeError("Program FPGA: Seek error in rawbin file");
}
size_t filesize = ftell(fp);
if (filesize <= 0) {
throw RuntimeError("Program FPGA: Could not get length of rawbin file");
}
rewind(fp);
std::vector<char> buffer(filesize, 0);
if (fread(buffer.data(), sizeof(char), filesize, fp) != filesize) {
throw RuntimeError("Program FPGA: Could not read rawbin file");
}
if (fclose(fp) != 0) {
throw RuntimeError(
"Program FPGA: Could not close destination file after converting");
}
unlink(destfname); // delete temporary file
LOG(logDEBUG1) << "Read file into memory";
return buffer;
}
std::vector<char> DetectorImpl::readKernelFile(const std::string &fname) {
// validate type of file
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.");
}
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";
return buffer; return buffer;
} }

View File

@ -291,15 +291,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/ */
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,

View File

@ -2487,14 +2487,14 @@ void Module::programFPGA(std::vector<char> buffer) {
case JUNGFRAU: case JUNGFRAU:
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
programFPGAviaBlackfin(buffer); sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware");
break; break;
case MYTHEN3: case MYTHEN3:
case GOTTHARD2: case GOTTHARD2:
programFPGAviaNios(buffer); sendProgram(false, buffer, F_PROGRAM_FPGA, "Update Firmware");
break; break;
default: default:
throw RuntimeError("Programming FPGA via the package is not " throw RuntimeError("Updating Firmware via the package is not "
"implemented for this detector"); "implemented for this detector");
} }
} }
@ -2523,16 +2523,35 @@ void Module::copyDetectorServer(const std::string &fname,
<< "): detector server copied"; << "): detector server copied";
} }
void Module::updateDetectorServer(std::vector<char> buffer) {
switch (shm()->detType) {
case JUNGFRAU:
case CHIPTESTBOARD:
case MOENCH:
sendProgram(true, buffer, F_UPDATE_DETECTOR_SERVER,
"Update Detector Server (no tftp)");
break;
case MYTHEN3:
case GOTTHARD2:
sendProgram(false, buffer, F_UPDATE_DETECTOR_SERVER,
"Update Detector Server (no tftp)");
break;
default:
throw RuntimeError("Updating Kernel via the package is not implemented "
"for this detector");
}
}
void Module::updateKernel(std::vector<char> buffer) { void Module::updateKernel(std::vector<char> buffer) {
switch (shm()->detType) { switch (shm()->detType) {
case JUNGFRAU: case JUNGFRAU:
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
updateKernelviaBlackfin(buffer); sendProgram(true, buffer, F_UPDATE_KERNEL, "Update Kernel");
break; break;
case MYTHEN3: case MYTHEN3:
case GOTTHARD2: case GOTTHARD2:
updateKernelviaNios(buffer); sendProgram(false, buffer, F_UPDATE_KERNEL, "Update Kernel");
break; break;
default: default:
throw RuntimeError("Updating Kernel via the package is not implemented " throw RuntimeError("Updating Kernel via the package is not implemented "
@ -3443,16 +3462,19 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
return myMod; return myMod;
} }
void Module::programFPGAviaBlackfin(std::vector<char> buffer) { void Module::sendProgram(bool blackfin, std::vector<char> buffer,
// send program from memory to detector const int functionEnum,
const std::string &functionType) {
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Sending programming binary (from pof)"; << "): Sending " << functionType;
// send fnum and filesize
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_PROGRAM_FPGA); client.Send(functionEnum);
uint64_t filesize = buffer.size(); uint64_t filesize = buffer.size();
client.Send(filesize); client.Send(filesize);
// checksum // send checksum
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
LOG(logDEBUG1) << "Checksum:" << checksum; LOG(logDEBUG1) << "Checksum:" << checksum;
char cChecksum[MAX_STR_LENGTH]; char cChecksum[MAX_STR_LENGTH];
@ -3460,39 +3482,42 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
strcpy(cChecksum, checksum.c_str()); strcpy(cChecksum, checksum.c_str());
client.Send(cChecksum); client.Send(cChecksum);
// opening file fail // validate memory allocation etc in detector
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw DetectorError(os.str());
} }
// sending program in parts // send program
uint64_t unitprogramsize = 0; if (blackfin) {
int currentPointer = 0; uint64_t unitprogramsize = 0;
while (filesize > 0) { int currentPointer = 0;
unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE; while (filesize > 0) {
if (unitprogramsize > filesize) { unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE;
unitprogramsize = filesize; if (unitprogramsize > filesize) {
} unitprogramsize = filesize;
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize }
<< "\t filesize:" << filesize; LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
client.Send(&buffer[currentPointer], unitprogramsize); client.Send(&buffer[currentPointer], unitprogramsize);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
std::cout << '\n'; std::cout << '\n';
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw DetectorError(os.str());
}
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
} }
filesize -= unitprogramsize; } else {
currentPointer += unitprogramsize; client.Send(buffer);
} }
// checksum // tmp checksum verified in detector
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
@ -3502,50 +3527,22 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " (" LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
<< shm()->hostname << ")"; << shm()->hostname << ")";
// simulating erasing flash // simulating erasing and writing to
{ if (functionEnum == F_PROGRAM_FPGA) {
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex if (blackfin) {
<< " (" << shm()->hostname << ")"; simulatingActivityinDetector("Erasing Flash",
printf("%d%%\r", 0); BLACKFIN_ERASE_FLASH_TIME);
std::cout << std::flush; simulatingActivityinDetector("Writing to Flash",
// erasing takes 65 seconds, printing here (otherwise need threads BLACKFIN_WRITE_TO_FLASH_TIME);
// in server-unnecessary) } else {
const int ERASE_TIME = 65; simulatingActivityinDetector("Erasing Flash",
int count = ERASE_TIME + 1; NIOS_ERASE_FLASH_TIME);
while (count > 0) { simulatingActivityinDetector("Writing to Flash",
std::this_thread::sleep_for(std::chrono::seconds(1)); NIOS_WRITE_TO_FLASH_TIME);
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
} }
printf("\n");
}
// simulating writing to flash
{
LOG(logINFO) << "(Simulating) Writing to Flash for module "
<< moduleIndex << " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// writing takes 30 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 30;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
}
printf("\n");
} }
// update verified
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
@ -3553,190 +3550,26 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
throw DetectorError(os.str()); throw DetectorError(os.str());
} }
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): FPGA programmed successfully"; << "): " << functionType << " udpated successfully";
} }
void Module::programFPGAviaNios(std::vector<char> buffer) { void Module::simulatingActivityinDetector(const std::string &functionType,
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname const int timeRequired) {
<< "): Sending programming binary (from rbf)"; LOG(logINFO) << "(Simulating) " << functionType << " for module "
<< moduleIndex << " (" << shm()->hostname << ")";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); printf("%d%%\r", 0);
client.Send(F_PROGRAM_FPGA); std::cout << std::flush;
uint64_t filesize = buffer.size(); const int ERASE_TIME = timeRequired;
client.Send(filesize); int count = ERASE_TIME + 1;
while (count > 0) {
// checksum std::this_thread::sleep_for(std::chrono::seconds(1));
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); --count;
LOG(logDEBUG1) << "Checksum:" << checksum; printf(
char cChecksum[MAX_STR_LENGTH]; "%d%%\r",
memset(cChecksum, 0, MAX_STR_LENGTH); static_cast<int>(
strcpy(cChecksum, checksum.c_str()); (static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
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);
// simulating erasing flash
{
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex
<< " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush; std::cout << std::flush;
// erasing takes 10 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 10;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
}
printf("\n");
} }
printf("\n");
// simulating writing to flash
{
LOG(logINFO) << "(Simulating) Writing to Flash for module "
<< moduleIndex << " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
// writing takes 45 seconds, printing here (otherwise need threads
// in server-unnecessary)
const int ERASE_TIME = 45;
int count = ERASE_TIME + 1;
while (count > 0) {
std::this_thread::sleep_for(std::chrono::seconds(1));
--count;
printf("%d%%\r",
static_cast<int>(
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
100));
std::cout << std::flush;
}
printf("\n");
}
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
<< "): 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
uint64_t unitprogramsize = 0;
int currentPointer = 0;
while (filesize > 0) {
unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE;
if (unitprogramsize > filesize) {
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

View File

@ -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 updateDetectorServer(std::vector<char> buffer);
void updateKernel(std::vector<char> buffer); void updateKernel(std::vector<char> buffer);
void rebootController(); void rebootController();
uint32_t readRegister(uint32_t addr) const; uint32_t readRegister(uint32_t addr) const;
@ -747,13 +748,17 @@ class Module : public virtual slsDetectorDefs {
std::string getTrimbitFilename(detectorSettings settings, int e_eV); std::string getTrimbitFilename(detectorSettings settings, int e_eV);
sls_detector_module readSettingsFile(const std::string &fname, sls_detector_module readSettingsFile(const std::string &fname,
bool trimbits = true); bool trimbits = true);
void programFPGAviaBlackfin(std::vector<char> buffer); void sendProgram(bool blackfin, std::vector<char> buffer,
void programFPGAviaNios(std::vector<char> buffer); const int functionEnum, const std::string &functionType);
void updateKernelviaBlackfin(std::vector<char> buffer); void simulatingActivityinDetector(const std::string &functionType,
void updateKernelviaNios(std::vector<char> buffer); const int timeRequired);
const int moduleIndex; const int moduleIndex;
mutable sls::SharedMemory<sharedModule> shm{0, 0}; mutable sls::SharedMemory<sharedModule> shm{0, 0};
static const int BLACKFIN_ERASE_FLASH_TIME = 65;
static const int BLACKFIN_WRITE_TO_FLASH_TIME = 30;
static const int NIOS_ERASE_FLASH_TIME = 10;
static const int NIOS_WRITE_TO_FLASH_TIME = 45;
}; };
} // namespace sls } // namespace sls

View File

@ -8,43 +8,34 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
/** (used by multi and sls) /**
* reads a short int raw data file
* @param infile input file stream
* @param data array of data values * @param data array of data values
* @param nch number of channels * @param nch number of channels
* @param offset start channel value * @param offset start channel value
* @returns OK or FAIL if it could not read the file or data=NULL
*/ */
int readDataFile(std::ifstream &infile, short int *data, int nch, int readDataFile(std::ifstream &infile, short int *data, int nch,
int offset = 0); int offset = 0);
/** (used by multi and sls) /**
* reads a short int rawdata file
* @param fname name of the file to be read
* @param data array of data value * @param data array of data value
* @param nch number of channels * @param nch number of channels
* @returns OK or FAIL if it could not read the file or data=NULL
*/ */
int readDataFile(std::string fname, short int *data, int nch); int readDataFile(std::string fname, short int *data, int nch);
/** (used by multi and sls) std::vector<char> readBinaryFile(const std::string &fname,
* writes a short int raw data file const std::string &errorPrefix);
* @param outfile output file stream
/**
* @param nch number of channels * @param nch number of channels
* @param data array of data values * @param data array of data values
* @param offset start channel number * @param offset start channel number
* @returns OK or FAIL if it could not write the file or data=NULL
*/ */
int writeDataFile(std::ofstream &outfile, int nch, short int *data, int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset = 0); int offset = 0);
/** (used by multi and sls) /**
* writes a short int raw data file
* @param fname of the file to be written
* @param nch number of channels * @param nch number of channels
* @param data array of data values * @param data array of data values
* @returns OK or FAIL if it could not write the file or data=NULL
*/ */
int writeDataFile(std::string fname, int nch, short int *data); int writeDataFile(std::string fname, int nch, short int *data);

View File

@ -254,7 +254,8 @@ 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_PROGRAM_KERNEL, F_UPDATE_KERNEL,
F_UPDATE_DETECTOR_SERVER,
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
@ -611,7 +612,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_PROGRAM_KERNEL: return "F_PROGRAM_KERNEL"; case F_UPDATE_DETECTOR_SERVER: return "F_UPDATE_DETECTOR_SERVER";
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";

View File

@ -53,6 +53,48 @@ int readDataFile(std::string fname, short int *data, int nch) {
return iline; return iline;
} }
std::vector<char> readBinaryFile(const std::string &fname,
const std::string &errorPrefix) {
// check if it exists
struct stat st;
if (stat(fname.c_str(), &st) != 0) {
throw sls::RuntimeError(errorPrefix +
std::string(": file does not exist"));
}
FILE *fp = fopen(fname.c_str(), "rb");
if (fp == nullptr) {
throw sls::RuntimeError(errorPrefix +
std::string(": Could not open file: ") + fname);
}
// get file size to print progress
if (fseek(fp, 0, SEEK_END) != 0) {
throw sls::RuntimeError(errorPrefix +
std::string(": Seek error in src file"));
}
size_t filesize = ftell(fp);
if (filesize <= 0) {
throw sls::RuntimeError(errorPrefix +
std::string(": Could not get length of file"));
}
rewind(fp);
std::vector<char> buffer(filesize, 0);
if (fread(buffer.data(), sizeof(char), filesize, fp) != filesize) {
throw sls::RuntimeError(errorPrefix +
std::string(": Could not read file"));
}
if (fclose(fp) != 0) {
throw sls::RuntimeError(errorPrefix +
std::string(": Could not close file"));
}
LOG(logDEBUG1) << "Read file into memory";
return buffer;
}
int writeDataFile(std::ofstream &outfile, int nch, short int *data, int writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset) { int offset) {
if (data == nullptr) if (data == nullptr)