diff --git a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h index f23b28cd6..8a3a9cc65 100644 --- a/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/programFpgaBlackfin.h @@ -2,49 +2,28 @@ #include #include -/** - * Define GPIO pins if not defined - */ + +#define TEMP_PROG_FILE_NAME "/var/tmp/tmp.pof" + + void defineGPIOpins(); - -/** - * Notify FPGA to not touch flash - */ void FPGAdontTouchFlash(); - -/** - * Notify FPGA to program from flash - */ void FPGATouchFlash(); - -/** - * Reset FPGA - */ void resetFPGA(); /** - * Erasing flash + * deletes old file + * verify memory available to copy + * open file to copy */ -void eraseFlash(); - -/** - * Open the drive to copy program and - * notify FPGA not to touch the program - * @param filefp pointer to flash - * @return 0 for success, 1 for fail (cannot open file for writing program) +int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess); +int copyToFlash(char *clientChecksum, char *mess); +int getDrive(char *mess); +/** Notify fpga not to touch flash, open src and flash drive to write */ +int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess); +int eraseFlash(char *mess); +/* write from tmp file to flash */ +int writeToFlash(FILE *flashfd, FILE *srcfd, char *mess); +/** Notify fpga to pick up firmware from flash and wait for status confirmation */ -int startWritingFPGAprogram(FILE **filefp); - -/** - * When done writing the program, close file pointer and - * notify FPGA to pick up the program from flash - * @param filefp pointer to flash - * @return 0 for success, 1 for fail (time taken for fpga to touch flash - * exceeded) - */ -int stopWritingFPGAprogram(FILE *filefp); - -int startCopyingFPGAProgram(FILE **fd, uint64_t fsize, char *mess); -int writeFPGAProgram(FILE *fd, char *src, uint64_t fsize, char *msg, - char *mess); -int verifyCheckSumofProgram(char* clientChecksum, char* mess); +int waitForFPGAtoTouchFlash(char *mess); diff --git a/slsDetectorServers/slsDetectorServer/src/common.c b/slsDetectorServers/slsDetectorServer/src/common.c index 052485be9..222341474 100644 --- a/slsDetectorServers/slsDetectorServer/src/common.c +++ b/slsDetectorServers/slsDetectorServer/src/common.c @@ -206,6 +206,7 @@ int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) { MD5_CTX c; if (!MD5_Init(&c)) { + fclose(fp); strcpy(mess, "Unable to calculate checksum (MD5_Init)\n"); LOG(logERROR, (mess)); return FAIL; @@ -214,6 +215,7 @@ int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) { ssize_t bytes = fread(buf, 1, 512, fp); while (bytes > 0) { if (!MD5_Update(&c, buf, bytes)) { + fclose(fp); strcpy(mess, "Unable to calculate checksum (MD5_Update)\n"); LOG(logERROR, (mess)); return FAIL; diff --git a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c index f0f96bc02..944983a58 100644 --- a/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c +++ b/slsDetectorServers/slsDetectorServer/src/programFpgaBlackfin.c @@ -9,17 +9,21 @@ #include /* global variables */ -#define MTDSIZE 10 #define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s -#define TEMP_PROG_FILE_NAME "/var/tmp/tmp.pof" - +#define CMD_GET_FLASH \ + "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd" +#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value" +#define FLASH_DRIVE_NAME_SIZE 16 +char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0}; int gpioDefined = 0; -char mtdvalue[MTDSIZE] = {0}; extern int executeCommand(char *command, char *result, enum TLogLevel level); void defineGPIOpins() { +#ifdef VIRTUAL + return; +#endif if (!gpioDefined) { // define the gpio pins system("echo 7 > /sys/class/gpio/export"); @@ -34,139 +38,61 @@ void defineGPIOpins() { } void FPGAdontTouchFlash() { +#ifdef VIRTUAL + return; +#endif // tell FPGA to not touch flash system("echo 0 > /sys/class/gpio/gpio9/value"); // usleep(100*1000); } void FPGATouchFlash() { +#ifdef VIRTUAL + return; +#endif // tell FPGA to touch flash to program itself system("echo 1 > /sys/class/gpio/gpio9/value"); } void resetFPGA() { LOG(logINFOBLUE, ("Reseting FPGA\n")); +#ifdef VIRTUAL + return; +#endif FPGAdontTouchFlash(); FPGATouchFlash(); usleep(CTRL_SRVR_INIT_TIME_US); } -void eraseFlash() { - LOG(logDEBUG1, ("Erasing Flash\n")); - char command[255]; - memset(command, 0, 255); - sprintf(command, "flash_eraseall %s", mtdvalue); - system(command); - LOG(logINFO, ("Flash erased\n")); -} - -int startWritingFPGAprogram(FILE **filefp) { - LOG(logDEBUG1, ("Start Writing of FPGA program\n")); - - // getting the drive - // root:/> cat /proc/mtd - // dev: size erasesize name - // mtd0: 00040000 00020000 "bootloader(nor)" - // mtd1: 00100000 00020000 "linux kernel(nor)" - // mtd2: 002c0000 00020000 "file system(nor)" - // mtd3: 01000000 00010000 "bitfile(spi)" - char output[255]; - memset(output, 0, 255); - FILE *fp = popen( - "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r"); - if (fp == NULL) { - LOG(logERROR, ("popen returned NULL. Need that to get mtd drive.\n")); - return FAIL; - } - if (fgets(output, sizeof(output), fp) == NULL) { - LOG(logERROR, ("fgets returned NULL. Need that to get mtd drive.\n")); - return FAIL; - } - pclose(fp); - memset(mtdvalue, 0, MTDSIZE); - strcpy(mtdvalue, "/dev/"); - char *pch = strtok(output, ":"); - if (pch == NULL) { - LOG(logERROR, ("Could not get mtd value\n")); - return FAIL; - } - strcat(mtdvalue, pch); - LOG(logINFO, ("Flash drive found: %s\n", mtdvalue)); - - FPGAdontTouchFlash(); - - // writing the program to flash - *filefp = fopen(mtdvalue, "w"); - if (*filefp == NULL) { - LOG(logERROR, ("Unable to open %s in write mode\n", mtdvalue)); - return FAIL; - } - LOG(logINFO, ("Flash ready for writing\n")); - - return OK; -} - -int stopWritingFPGAprogram(FILE *filefp) { - LOG(logDEBUG1, ("Stopping of writing FPGA program\n")); - - if (filefp != NULL) { - fclose(filefp); - } - - // touch and program - FPGATouchFlash(); - - LOG(logINFO, ("Waiting for FPGA to program from flash\n")); - // waiting for success or done - char output[255]; - int res = 0; - int timeSpent = 0; - while (res == 0) { - // time taken for fpga to pick up from flash - usleep(1000); - timeSpent += 1000; - if (timeSpent >= MAX_TIME_FPGA_TOUCH_FLASH_US) { - return FAIL; - } - FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r"); - fgets(output, sizeof(output), sysFile); - pclose(sysFile); - sscanf(output, "%d", &res); - LOG(logDEBUG1, ("gpi07 returned %d\n", res)); - } - LOG(logINFO, ("FPGA has picked up the program from flash\n")); - return OK; -} - - - -int startCopyingFPGAProgram(FILE **fd, uint64_t fsize, char *mess) { +int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess) { // delete old /var/tmp/file { char cmd[MAX_STR_LENGTH] = {0}; - memset(cmd, 0, MAX_STR_LENGTH); - sprintf(cmd, "rm -fr %s", TEMP_PROG_FILE_NAME); char retvals[MAX_STR_LENGTH] = {0}; - memset(retvals, 0, MAX_STR_LENGTH); + sprintf(cmd, "rm -fr %s", TEMP_PROG_FILE_NAME); if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { - strcpy(mess, retvals); - // LOG(logERROR, (mess)); already printed in executecommand + sprintf(mess, + "Could not program fpga. (could not delete old file: %s)", + retvals); + LOG(logERROR, (mess)); return FAIL; } } // check available memory to copy program - struct sysinfo info; - sysinfo(&info); - if (fsize >= info.freeram) { - sprintf(mess, - "Could not program fpga. Not enough memory to copy " - "program. [File size:%ldMB, free RAM: %ldMB]\n", - (long int)(fsize / (1024 * 1024)), - (long int)(info.freeram / (1024 * 1024))); - LOG(logERROR, (mess)); - return FAIL; + { + struct sysinfo info; + sysinfo(&info); + if (fsize >= info.freeram) { + sprintf(mess, + "Could not program fpga. Not enough memory to copy " + "program. [File size:%ldMB, free RAM: %ldMB]\n", + (long int)(fsize / (1024 * 1024)), + (long int)(info.freeram / (1024 * 1024))); + LOG(logERROR, (mess)); + return FAIL; + } } // open file to copy program @@ -180,19 +106,208 @@ int startCopyingFPGAProgram(FILE **fd, uint64_t fsize, char *mess) { return OK; } -int writeFPGAProgram(FILE *fd, char *src, uint64_t fsize, char* msg, char* mess) { - LOG(logDEBUG1, - ("%s [fsize:%lu,fd:%p,src:%p\n", msg, (long long unsigned int)fsize, (void *)fd, (void *)src)); +int copyToFlash(char *clientChecksum, char *mess) { - if (fwrite((void *)src, sizeof(char), fsize, fd) != fsize) { - sprintf(mess, "Could not %s (size:%ld)\n", msg, (long int)fsize); - LOG(logERROR, (mess)); + if (getDrive(mess) == FAIL) { return FAIL; } - LOG(logDEBUG1, ("%s\n", msg)); + + FILE *flashfd = NULL; + FILE *srcfd = NULL; + if (openFileForFlash(&flashfd, &srcfd, mess) == FAIL) { + return FAIL; + } + + if (eraseFlash(mess) == FAIL) { + return FAIL; + } + + if (writeToFlash(flashfd, srcfd, mess) == FAIL) { + return FAIL; + } + + if (verifyChecksumFromFile(mess, clientChecksum, flashDriveName) == FAIL) { + return FAIL; + } + LOG(logINFO, ("Checksum in Flash verified\n")); + + if (waitForFPGAtoTouchFlash(mess) == FAIL) { + return FAIL; + } + return OK; } -int verifyCheckSumofProgram(char* clientChecksum, char* mess) { - return verifyChecksumFromFile(mess, clientChecksum, TEMP_PROG_FILE_NAME); -} \ No newline at end of file +int getDrive(char *mess) { +#ifdef VIRTUAL + strcpy(flashDriveName, "/tmp/SLS_mtd3"); + return OK; +#endif + // getting the drive + // root:/> cat /proc/mtd + // dev: size erasesize name + // mtd0: 00040000 00020000 "bootloader(nor)" + // mtd1: 00100000 00020000 "linux kernel(nor)" + // mtd2: 002c0000 00020000 "file system(nor)" + // mtd3: 01000000 00010000 "bitfile(spi)" + + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + sprintf(cmd, "rm -fr %s", TEMP_PROG_FILE_NAME); + if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { + sprintf(mess, "Could not program fpga. (could not delete old file: %s)", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + + memset(retvals, 0, MAX_STR_LENGTH); + if (executeCommand(CMD_GET_FLASH, retvals, logDEBUG1) == FAIL) { + sprintf(mess, "Could not program fpga. (could not get flash drive: %s)", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + + char *pch = strtok(retvals, ":"); + if (pch == NULL) { + strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n"); + LOG(logERROR, (mess)); + return FAIL; + } + + strcpy(flashDriveName, "/dev/"); + strcat(flashDriveName, pch); + LOG(logINFO, ("Flash drive found: %s\n", flashDriveName)); + return OK; +} + +int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess) { + FPGAdontTouchFlash(); + + // open src file + *srcfd = fopen(TEMP_PROG_FILE_NAME, "r"); + if (*srcfd == NULL) { + sprintf(mess, + "Could not flash. Unable to open temp program file %s in read " + "mode\n", + TEMP_PROG_FILE_NAME); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logDEBUG1, ("Temp file ready for reading\n")); + + // open flash drive for writing + *flashfd = fopen(flashDriveName, "w"); + if (*flashfd == NULL) { + fclose(*srcfd); + sprintf(mess, "Unable to open flash drive %s in write mode\n", + flashDriveName); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logINFO, ("Flash ready for writing\n")); + return OK; +} + +int eraseFlash(char *mess) { + LOG(logDEBUG1, ("Erasing Flash\n")); + +#ifdef VIRTUAL + return OK; +#endif + char cmd[MAX_STR_LENGTH] = {0}; + char retvals[MAX_STR_LENGTH] = {0}; + sprintf(cmd, "flash_eraseall %s", flashDriveName); + if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) { + sprintf(mess, "Could not program fpga. (could not erase flash: %s)", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + + LOG(logINFO, ("Flash erased\n")); + return OK; +} + +int writeToFlash(FILE *flashfd, FILE *srcfd, char *mess) { + LOG(logDEBUG1, ("writing to flash\n")); + + char* buffer = malloc(MAX_FPGAPROGRAMSIZE); + if (buffer == NULL) { + fclose(flashfd); + fclose(srcfd); + strcpy(mess, "Could not program foga. Memory allocation to write to " + "flash failed.\n"); + LOG(logERROR, (mess)); + return FAIL; + } + + ssize_t totalBytes = 0; + ssize_t bytes = fread(buffer, sizeof(char), MAX_FPGAPROGRAMSIZE, srcfd); + while (bytes > 0) { + ssize_t bytesWritten = + fwrite((void *)buffer, sizeof(char), bytes, flashfd); + totalBytes += bytesWritten; + if (bytesWritten != bytes) { + fclose(flashfd); + fclose(srcfd); + sprintf(mess, + "Could not write to flash (bytes written:%ld, expected: " + "%ld, total written:%ld)\n", + (long int)bytesWritten, (long int)bytes, + (long int)totalBytes); + LOG(logERROR, (mess)); + return FAIL; + } + bytes = fread(buffer, sizeof(char), bytes, srcfd); + } + fclose(flashfd); + fclose(srcfd); + LOG(logINFO, ("Wrote %ld bytes to flash\n", totalBytes)); + return OK; +} + +int waitForFPGAtoTouchFlash(char* mess) { + // touch and program + FPGATouchFlash(); + +#ifdef VIRTUAL + return OK; +#endif + LOG(logINFO, ("Waiting for FPGA to program from flash\n")); + int timeSpent = 0; + + int result = 0; + while (result == 0) { + // time taken for fpga to pick up from flash + usleep(1000); + timeSpent += 1000; + if (timeSpent >= MAX_TIME_FPGA_TOUCH_FLASH_US) { + sprintf(mess, "Could not program fpga. (exceeded max time allowed: %ds)\n", + MAX_TIME_FPGA_TOUCH_FLASH_US/(1000 * 1000)); + LOG(logERROR, (mess)); + return FAIL; + } + + // read gpio status + char retvals[MAX_STR_LENGTH] = {0}; + if (FAIL == executeCommand(CMD_FPGA_PICKED_STATUS, retvals, logDEBUG1)) { + sprintf(mess, "Could not program fpga. (could not read gpio status: %s)\n", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + + // convert to int + if (sscanf(retvals, "%d", &result) != 1) { + sprintf(mess, "Could not program fpga. (could not scan int for gpio status: %s)\n", + retvals); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logDEBUG1, ("gpi07 returned %d\n", result)); + } + LOG(logINFO, ("FPGA has picked up the program from flash\n")); + return OK; +} diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index c8d63ac6f..efcb2436b 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -3727,11 +3727,12 @@ int program_fpga(int file_des) { // open file and allocate memory for part program FILE *fd = NULL; - ret = startCopyingFPGAProgram(&fd, filesize, mess); + ret = preparetoCopyFPGAProgram(&fd, filesize, mess); char *src = NULL; if (ret == OK) { src = malloc(MAX_FPGAPROGRAMSIZE); - if (src == NULL) { + if (src == NULL) { + fclose(fd); strcpy(mess, "Could not allocate memory to get fpga program\n"); LOG(logERROR, (mess)); ret = FAIL; @@ -3739,17 +3740,10 @@ int program_fpga(int file_des) { } Server_SendResult(file_des, INT32, NULL, 0); if (ret == FAIL) { - if (src != NULL) { - free(src); - } - if (fd != NULL) { - fclose(fd); - } LOG(logERROR, ("Program FPGA FAIL1!\n")); return FAIL; } - // copying program part by part uint64_t totalsize = filesize; while (ret == OK && filesize) { @@ -3774,7 +3768,13 @@ int program_fpga(int file_des) { filesize -= unitprogramsize; // copy program - ret = writeFPGAProgram(fd, src, unitprogramsize, "copy program to /var/tmp", mess); + if (fwrite((void *)src, sizeof(char), unitprogramsize, fd) != + unitprogramsize) { + ret = FAIL; + sprintf(mess, "Could not copy program to /var/tmp (size:%ld)\n", + (long int)unitprogramsize); + LOG(logERROR, (mess)); + } Server_SendResult(file_des, INT32, NULL, 0); if (ret == FAIL) { break; @@ -3785,59 +3785,27 @@ int program_fpga(int file_des) { (int)(((double)(totalsize - filesize) / totalsize) * 100))); fflush(stdout); } - if (src != NULL) { - free(src); - } - if (fd != NULL) { - fclose(fd); - } + free(src); + fclose(fd); // checksum of copied program if (ret == OK) { - ret = verifyCheckSumofProgram(checksum, mess); + ret = verifyChecksumFromFile(mess, checksum, TEMP_PROG_FILE_NAME); } Server_SendResult(file_des, INT32, NULL, 0); + if (ret == FAIL) { + LOG(logERROR, ("Program FPGA FAIL!\n")); + return FAIL; + } + // copy to flash + ret = copyToFlash(checksum, mess); + Server_SendResult(file_des, INT32, NULL, 0); if (ret == FAIL) { LOG(logERROR, ("Program FPGA FAIL!\n")); return FAIL; } - /* if (ret != FAIL) { - fpgasrc[totalsize] = '\0'; - }*/ - - /* - - // opening file pointer to flash and telling FPGA to not touch - flash if (startWritingFPGAprogram(&fp) != OK) { ret = FAIL; - sprintf(mess, "Could not write to flash. Error at - startup.\n"); LOG(logERROR, (mess)); - } - Server_SendResult(file_des, INT32, NULL, 0); - - - - - // erasing flash - if (ret != FAIL) { - eraseFlash(); - } - - - if (ret == OK) { - LOG(logINFO, ("Done copying program\n")); - // closing file pointer to flash and informing FPGA - ret = stopWritingFPGAprogram(fp); - if (ret == FAIL) { - strcpy(mess, "Failed to program fpga. FPGA is taking too - long " "to pick up program from flash! Try to flash " "again without - rebooting!\n"); LOG(logERROR, (mess)); - } - } - */ - - #endif // end of Blackfin programming LOG(logINFOGREEN, ("Programming FPGA completed successfully\n")); } @@ -4349,11 +4317,19 @@ int reboot_controller(int file_des) { Server_SendResult(file_des, INT32, NULL, 0); return GOODBYE; } +#ifdef VIRTUAL + ret = GOODBYE; +#else ret = REBOOT; +#endif #elif EIGERD functionNotImplemented(); +#else +#ifdef VIRTUAL + ret = GOODBYE; #else ret = REBOOT; +#endif #endif Server_SendResult(file_des, INT32, NULL, 0); return ret; @@ -4810,7 +4786,7 @@ int set_read_n_rows(int file_des) { LOG(logERROR, (mess)); } else #elif JUNGFRAUD - if ((check_detector_idle("set nmber of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) { + if ((check_detector_idle("set number of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) { ret = FAIL; sprintf(mess, "Could not set number of rows. %d must be a multiple " diff --git a/slsDetectorSoftware/src/DetectorImpl.cpp b/slsDetectorSoftware/src/DetectorImpl.cpp index 8d7249ca9..7ffda2fa0 100644 --- a/slsDetectorSoftware/src/DetectorImpl.cpp +++ b/slsDetectorSoftware/src/DetectorImpl.cpp @@ -1391,7 +1391,7 @@ std::vector DetectorImpl::readProgrammingFile(const std::string &fname) { unlink(destfname); // delete temporary file LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory"; - LOG(logINFO) << "Read file into memory"; + LOG(logDEBUG1) << "Read file into memory"; return buffer; } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index ab1a409dd..ef1bfbd49 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -3479,55 +3479,23 @@ void Module::programFPGAviaBlackfin(std::vector buffer) { << " returned error: " << client.readErrorMessage(); throw RuntimeError(os.str()); } -/* - // error in detector at opening file pointer to flash + if (moduleId == 0) { + LOG(logINFO) << "Checksum verified"; + } + + // copied to flash if (client.Receive() == FAIL) { std::ostringstream os; os << "Detector " << moduleId << " (" << shm()->hostname << ")" << " returned error: " << client.readErrorMessage(); throw RuntimeError(os.str()); } - - - - // erasing flash - LOG(logINFO) << "Erasing Flash for detector " << moduleId << " (" - << shm()->hostname << ")"; - printf("%d%%\r", 0); - std::cout << std::flush; - // erasing takes 65 seconds, printing here (otherwise need threads - // in server-unnecessary) - const int ERASE_TIME = 65; - int count = ERASE_TIME + 1; - while (count > 0) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - --count; - printf( - "%d%%\r", - static_cast( - (static_cast(ERASE_TIME - count) / ERASE_TIME) * 100)); - std::cout << std::flush; + if (moduleId == 0) { + LOG(logINFO) << "Copied to flash and checksum verified"; } - // fpga has written to flash successfully - if (client.Receive() == FAIL) { - std::ostringstream os; - os << "Detector " << moduleId << " (" << shm()->hostname << ")" - << " returned error: " << client.readErrorMessage(); - throw RuntimeError(os.str()); - } - - - // fpga has picked up from flash successfully - if (client.Receive() == FAIL) { - std::ostringstream os; - os << "Detector " << moduleId << " (" << shm()->hostname << ")" - << " returned error: " << client.readErrorMessage(); - throw RuntimeError(os.str()); - } -*/ LOG(logINFO) << "FPGA programmed successfully"; - //rebootController(); + rebootController(); } void Module::programFPGAviaNios(std::vector buffer) {