From 0f4bcf3a9dedc6f0231a306c70e3f648f06c97ed Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 22 Mar 2022 16:44:12 +0100 Subject: [PATCH] test if special file when updating kernel(solution: reboot only), --force-delete-normal-file used to force delete bfin fpga drive if normal file and create proper device tree --- python/src/detector.cpp | 5 +- .../include/programViaBlackfin.h | 6 +- .../include/slsDetectorServer_funcs.h | 3 +- .../src/programViaBlackfin.c | 119 ++++++++++++++---- .../slsDetectorServer/src/programViaNios.c | 24 ++++ .../src/slsDetectorServer_funcs.c | 30 +++-- slsDetectorSoftware/include/sls/Detector.h | 9 +- slsDetectorSoftware/src/CmdProxy.cpp | 26 ++-- slsDetectorSoftware/src/Detector.cpp | 9 +- slsDetectorSoftware/src/Module.cpp | 14 ++- slsDetectorSoftware/src/Module.h | 6 +- 11 files changed, 194 insertions(+), 57 deletions(-) diff --git a/python/src/detector.cpp b/python/src/detector.cpp index c6cd4927b..1bde76025 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1527,9 +1527,10 @@ void init_det(py::module &m) { Detector::setAdditionalJsonParameter, py::arg(), py::arg(), py::arg() = Positions{}) .def("programFPGA", - (void (Detector::*)(const std::string &, sls::Positions)) & + (void (Detector::*)(const std::string &, const bool, + sls::Positions)) & Detector::programFPGA, - py::arg(), py::arg() = Positions{}) + py::arg(), py::arg(), py::arg() = Positions{}) .def("resetFPGA", (void (Detector::*)(sls::Positions)) & Detector::resetFPGA, py::arg() = Positions{}) diff --git a/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h b/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h index 0c644f27b..c71265ea7 100644 --- a/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/programViaBlackfin.h @@ -26,10 +26,12 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd, uint64_t fsize); int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, char *functionType, char *clientChecksum, - ssize_t fsize); + ssize_t fsize, int forceDeleteNormalFile); int getDrive(char *mess, enum PROGRAM_INDEX index); /** Notify fpga not to touch flash, open src and flash drive to write */ -int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd); +int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd, + int forceDeleteNormalFile); +int checkNormalFile(char *mess, int forceDeleteNormalFile); int eraseFlash(char *mess); /* write from tmp file to flash */ int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index e68720305..385b45ae7 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -285,7 +285,8 @@ int update_detector_server(int); int receive_program(int file_des, enum PROGRAM_INDEX index); void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, - char *checksum, char *serverName); + char *checksum, char *serverName, + int forceDeleteNormalFile); void receive_program_default(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, char *checksum, char *serverName); diff --git a/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c b/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c index c8ae014f7..925f4d0de 100644 --- a/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c +++ b/slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c @@ -39,6 +39,9 @@ #define CMD_GET_AMD_FLASH "dmesg | grep Amd" +#define CMD_CREATE_DEVICE_FILE_PART1 "mknod" +#define CMD_CREATE_DEVICE_FILE_PART2 "c 90 6" + #define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB // clang-format on @@ -321,7 +324,7 @@ int preparetoCopyProgram(char *mess, char *functionType, FILE **fd, int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, char *functionType, char *clientChecksum, - ssize_t fsize) { + ssize_t fsize, int forceDeleteNormalFile) { memset(messageType, 0, sizeof(messageType)); strcpy(messageType, functionType); @@ -332,7 +335,8 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, FILE *flashfd = NULL; FILE *srcfd = NULL; - if (openFileForFlash(mess, &flashfd, &srcfd) == FAIL) { + if (openFileForFlash(mess, &flashfd, &srcfd, forceDeleteNormalFile) == + FAIL) { return FAIL; } @@ -436,7 +440,8 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) { return OK; } -int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { +int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd, + int forceDeleteNormalFile) { // open src file *srcfd = fopen(TEMP_PROG_FILE_NAME, "r"); if (*srcfd == NULL) { @@ -449,29 +454,8 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { } LOG(logDEBUG1, ("Temp file ready for reading\n")); -#ifndef VIRTUAL - // check if its a normal file or special file - struct stat buf; - if (stat(flashDriveName, &buf) == -1) { - sprintf(mess, - "Could not %s. Unable to validate if flash drive found is a " - "special file\n", - messageType); - LOG(logERROR, (mess)); + if (checkNormalFile(mess, forceDeleteNormalFile) == FAIL) return FAIL; - } - // non zero = block special file - if (S_ISBLK(buf.st_mode)) { - sprintf(mess, - "Could not %s. The flash drive found is a normal file. To " - "delete this file, create the flash drive and proceed with " - "programming, re-run the programming command with parameter " - "'--force-delete-normal-file'\n", - messageType); - LOG(logERROR, (mess)); - return FAIL; - } -#endif // open flash drive for writing *flashfd = fopen(flashDriveName, "w"); @@ -488,6 +472,91 @@ int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) { return OK; } +int checkNormalFile(char *mess, int forceDeleteNormalFile) { +#ifndef VIRTUAL + // check if its a normal file or special file + struct stat buf; + if (stat(flashDriveName, &buf) == -1) { + sprintf(mess, + "Could not %s. Unable to validate if flash drive found is a " + "special file\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } + // non zero = block special file + if (S_ISBLK(buf.st_mode)) { + // kernel memory is not permanent + if (index != PROGRAM_FPGA) { + sprintf(mess, + "Could not %s. The flash drive found is a normal file. " + "Reboot board using 'rebootcontroller' command to load " + "proper device tree\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } + // fpga memory stays after a reboot, so fix it if user allows + sprintf(mess, + "Could not %s. The flash drive found is a normal file. To " + "delete this file, create the flash drive and proceed with " + "programming, re-run the programming command with parameter " + "'--force-delete-normal-file'\n", + messageType); + LOG(logERROR, (mess)); + // user does not allow (default) + if (!forceDeleteNormalFile) { + return FAIL; + } + + // user allows to fix it, so force delete normal file + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + + if (snprintf(cmd, MAX_STR_LENGTH, "rm %s", flashDriveName) >= + MAX_STR_LENGTH) { + sprintf(mess, + "Could not update %s. Command to delete normal file %s is " + "too long\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + snprintf( + mess, MAX_STR_LENGTH, + "Could not update %s. (could not delete normal file %s: %s)\n", + messageType, flashDriveName, retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tDeleted Normal File(%s)\n", flashDriveName)); + + // create special drive + if (snprintf(cmd, MAX_STR_LENGTH, "%s %s %s", + CMD_CREATE_DEVICE_FILE_PART1, flashDriveName, + CMD_CREATE_DEVICE_FILE_PART2) >= MAX_STR_LENGTH) { + sprintf(mess, + "Could not update %s. Command to create special file %s is " + "too long\n", + messageType, flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { + snprintf( + mess, MAX_STR_LENGTH, + "Could not update %s. (could not create special file %s: %s)\n", + messageType, flashDriveName, retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("\tSpecial File created (%s)\n", flashDriveName)); + } +#endif + return OK; +} + int eraseFlash(char *mess) { LOG(logINFO, ("\tErasing Flash...\n")); diff --git a/slsDetectorServers/slsDetectorServer/src/programViaNios.c b/slsDetectorServers/slsDetectorServer/src/programViaNios.c index c81598650..2c98ac6bc 100644 --- a/slsDetectorServers/slsDetectorServer/src/programViaNios.c +++ b/slsDetectorServers/slsDetectorServer/src/programViaNios.c @@ -146,6 +146,30 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) { } int openFileForFlash(char *mess, FILE **flashfd) { +#ifndef VIRTUAL + // check if its a normal file or special file + struct stat buf; + if (stat(flashDriveName, &buf) == -1) { + sprintf(mess, + "Could not %s. Unable to validate if flash drive found is a " + "special file\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } + // non zero = block special file + if (S_ISBLK(buf.st_mode)) { + // memory is not permanent + sprintf(mess, + "Could not %s. The flash drive found is a normal file. " + "Reboot board using 'rebootcontroller' command to load " + "proper device tree\n", + messageType); + LOG(logERROR, (mess)); + return FAIL; + } +#endif + *flashfd = fopen(flashDriveName, "w"); if (*flashfd == NULL) { sprintf(mess, diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 796dd4f3f..a732e143f 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4003,7 +4003,8 @@ int check_version(int file_des) { usleep(3 * 1000 * 1000); if (!isInitCheckDone()) { ret = FAIL; - strcpy(mess, "Server Initialization still not done done in server. Unexpected.\n"); + strcpy(mess, "Server Initialization still not done done in server. " + "Unexpected.\n"); LOG(logERROR, (mess)); } } @@ -9443,6 +9444,15 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { LOG(logINFO, ("\tServer Name: %s\n", serverName)); } +#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) && !defined(EIGERD) + int forceDeleteNormalFile = 0; + if (receiveData(file_des, &forceDeleteNormalFile, + sizeof(forceDeleteNormalFile), INT32) < 0) + return printSocketReadError(); + LOG(logINFO, + ("\tForce Delete Normal File: %d\n", forceDeleteNormalFile)); +#endif + // in same folder as current process (will also work for virtual then // with write permissions) { @@ -9467,7 +9477,7 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { checksum, serverName); #else receive_program_via_blackfin(file_des, index, functionType, - filesize, checksum, serverName); + filesize, checksum, serverName, forceDeleteNormalFile); #endif } @@ -9483,7 +9493,7 @@ int receive_program(int file_des, enum PROGRAM_INDEX index) { void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, - char *checksum, char *serverName) { + char *checksum, char *serverName, int forceDeleteNormalFile) { #if !defined(JUNGFRAUD) && !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && \ !defined(GOTTHARDD) @@ -9582,7 +9592,7 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index, case PROGRAM_FPGA: case PROGRAM_KERNEL: ret = eraseAndWriteToFlash(mess, index, functionType, checksum, - totalsize); + totalsize, forceDeleteNormalFile); break; case PROGRAM_SERVER: ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME, @@ -9785,20 +9795,24 @@ int set_top(int file_des) { if (Server_VerifyLock() == OK) { if (arg != 0 && arg != 1) { ret = FAIL; - sprintf(mess, "Could not set top mode. Invalid value: %d. Must be 0 or 1\n", arg); + sprintf( + mess, + "Could not set top mode. Invalid value: %d. Must be 0 or 1\n", + arg); LOG(logERROR, (mess)); } else { ret = setTop(arg == 1 ? OW_TOP : OW_BOTTOM); if (ret == FAIL) { - sprintf(mess, "Could not set %s\n", (arg == 1 ? "Top" : "Bottom")); + sprintf(mess, "Could not set %s\n", + (arg == 1 ? "Top" : "Bottom")); LOG(logERROR, (mess)); - } else { + } else { int retval = -1; ret = isTop(&retval); if (ret == FAIL) { strcpy(mess, "Could not get Top mode\n"); LOG(logERROR, (mess)); - } else { + } else { LOG(logDEBUG1, ("retval top: %d\n", retval)); validate(&ret, mess, arg, retval, "set top mode", DEC); } diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index b0bf69d71..41d9109be 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1742,10 +1742,13 @@ class Detector { /** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] * Advanced user Function! * Program firmware from command line, after which detector controller is - * rebooted. [Jungfrau][CTB][Moench] fname is a pof file (full path) \n - * [Mythen3][Gotthard2] fname is an rbf file (full path) + * rebooted. forceDeleteNormalFile is true, if normal file found + * in device tree, it must be deleted, a new device drive created and + * programming continued.[Jungfrau][CTB][Moench] fname is a pof file (full + * path) \n [Mythen3][Gotthard2] fname is an rbf file (full path) */ - void programFPGA(const std::string &fname, Positions pos = {}); + void programFPGA(const std::string &fname, const bool forceDeleteNormalFile, + Positions pos = {}); /** [Jungfrau][CTB][Moench] Advanced user Function! */ void resetFPGA(Positions pos = {}); diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index a4c08c50c..7967a2d04 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -2866,19 +2866,31 @@ std::string CmdProxy::ProgramFpga(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[fname.pof | fname.rbf (full path)]\n\t[Jungfrau][Ctb][Moench] " - "Programs FPGA from pof file (full path). Then, detector " - "controller is rebooted \n\t[Mythen3][Gotthard2] Programs FPGA " - "from rbf file (full path). Then, detector controller is " - "rebooted." + os << "[fname.pof | fname.rbf (full " + "path)][(opitonal)--force-delete-normal-file]\n\t[Jungfrau][Ctb][" + "Moench] Programs FPGA from pof file (full path). Then, detector " + "controller is rebooted. \n\t\tUse --force-delete-normal-file " + "argument, if normal file found in device tree, it must be " + "deleted, a new device drive created and programming " + "continued.\n\t[Mythen3][Gotthard2] Programs FPGA from rbf file " + "(full path). Then, detector controller is rebooted." << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); } else if (action == defs::PUT_ACTION) { - if (args.size() != 1) { + bool forceDeteleNormalFile = false; + if (args.size() == 2) { + if (args[1] != "--force-delete-normal-file") { + throw sls::RuntimeError( + "Could not scan second argument. Did you " + "mean --force-delete-normal-file?"); + } + forceDeteleNormalFile = true; + } else if (args.size() != 1) { WrongNumberOfParameters(1); } - det->programFPGA(args[0], std::vector{det_id}); + det->programFPGA(args[0], forceDeteleNormalFile, + std::vector{det_id}); os << "successful\n"; } else { throw sls::RuntimeError("Unknown action"); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 6342d7745..1d1fd9a7f 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -2182,10 +2182,11 @@ void Detector::setAdditionalJsonParameter(const std::string &key, // Advanced -void Detector::programFPGA(const std::string &fname, Positions pos) { +void Detector::programFPGA(const std::string &fname, + const bool forceDeleteNormalFile, Positions pos) { LOG(logINFO) << "Updating Firmware..."; std::vector buffer = pimpl->readProgrammingFile(fname); - pimpl->Parallel(&Module::programFPGA, pos, buffer); + pimpl->Parallel(&Module::programFPGA, pos, buffer, forceDeleteNormalFile); rebootController(pos); } @@ -2230,7 +2231,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname, LOG(logINFO) << "Updating Firmware and Detector Server (with tftp)..."; LOG(logINFO) << "Updating Detector Server (via tftp)..."; pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname); - programFPGA(fname, pos); + programFPGA(fname, false, pos); } void Detector::updateFirmwareAndServer(const std::string &sname, @@ -2241,7 +2242,7 @@ void Detector::updateFirmwareAndServer(const std::string &sname, std::vector buffer = readBinaryFile(sname, "Update Detector Server"); std::string filename = sls::getFileNameFromFilePath(sname); pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename); - programFPGA(fname, pos); + programFPGA(fname, false, pos); } Result Detector::getUpdateMode(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 1fcfdb3fb..fb188ecb5 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -2551,12 +2551,14 @@ void Module::setAdditionalJsonParameter(const std::string &key, } // Advanced -void Module::programFPGA(std::vector buffer) { +void Module::programFPGA(std::vector buffer, + const bool forceDeleteNormalFile) { switch (shm()->detType) { case JUNGFRAU: case CHIPTESTBOARD: case MOENCH: - sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware"); + sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware", "", + forceDeleteNormalFile); break; case MYTHEN3: case GOTTHARD2: @@ -3547,7 +3549,8 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, void Module::sendProgram(bool blackfin, std::vector buffer, const int functionEnum, const std::string &functionType, - const std::string serverName) { + const std::string serverName, + const bool forceDeleteNormalFile) { LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname << "): Sending " << functionType; @@ -3571,6 +3574,11 @@ void Module::sendProgram(bool blackfin, std::vector buffer, client.Send(sname); } + // send forceDeleteNormalFile flag + if (blackfin) { + client.Send(static_cast(forceDeleteNormalFile)); + } + // validate memory allocation etc in detector if (client.Receive() == FAIL) { std::ostringstream os; diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 375911ceb..2c92d00b7 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -544,7 +544,8 @@ class Module : public virtual slsDetectorDefs { * Advanced * * * * ************************************************/ - void programFPGA(std::vector buffer); + void programFPGA(std::vector buffer, + const bool forceDeleteNormalFile); void resetFPGA(); void copyDetectorServer(const std::string &fname, const std::string &hostname); @@ -760,7 +761,8 @@ class Module : public virtual slsDetectorDefs { bool trimbits = true); void sendProgram(bool blackfin, std::vector buffer, const int functionEnum, const std::string &functionType, - const std::string serverName = ""); + const std::string serverName = "", + const bool forceDeleteNormalFile = false); void simulatingActivityinDetector(const std::string &functionType, const int timeRequired);