conflict resolved, changed to using hex() instead of str() in configuremac

This commit is contained in:
2019-04-03 14:11:01 +02:00
30 changed files with 711 additions and 507 deletions

View File

@ -1,12 +1,5 @@
#ifndef MULTI_SLS_DETECTOR_H
#define MULTI_SLS_DETECTOR_H
#pragma once
/**
@libdoc The multiSlsDetector class is used to operate several slsDetectors in
parallel.
* @short This is the base class for multi detector system functionalities
* @author Anna Bergamaschi
*/
#include "SharedMemory.h"
#include "error_defs.h"
#include "gitInfoLib.h"
@ -1434,7 +1427,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
int setStoragecellStart(int pos = -1, int detPos = -1);
/**
* Programs FPGA with pof file (Jungfrau)
* Programs FPGA with pof file (Not Eiger)
* @param fname file name
* @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL
@ -1442,12 +1435,38 @@ class multiSlsDetector : public virtual slsDetectorDefs {
int programFPGA(const std::string &fname, int detPos = -1);
/**
* Resets FPGA (Jungfrau)
* Resets FPGA (Not Eiger)
* @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL
*/
int resetFPGA(int detPos = -1);
/**
* Copies detector server from tftp and changes respawn server (Not Eiger)
* @param fname name of detector server binary
* @param hostname name of pc to tftp from
* @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL
*/
int copyDetectorServer(const std::string &fname, const std::string &hostname, int detPos = -1);
/**
* Reboot detector controller (Not Eiger)
* @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL
*/
int rebootController(int detPos = -1);
/**
* Updates the firmware, detector server and then reboots detector controller blackfin. (Not Eiger)
* @param sname name of detector server binary
* @param hostname name of pc to tftp from
* @param fname programming file name
* @param detPos -1 for all detectors in list or specific detector position
* @returns OK or FAIL
*/
int update(const std::string &sname, const std::string &hostname, const std::string &fname, int detPos = -1);
/**
* Power on/off Chip (Jungfrau)
* @param ival on is 1, off is 0, -1 to get
@ -2010,11 +2029,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/
void startProcessingThread();
// /**
// * Static function to call processing thread
// */
// static void* startProcessData(void *n);
/**
* Check if processing thread is ready to join main thread
* @returns true if ready, else false
@ -2033,6 +2047,15 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/
int kbhit();
/**
* Convert raw file
* @param fname name of pof file
* @param fpgasrc pointer in memory to read pof to
* @returns file size
*/
std::vector<char> readPofFile(const std::string &fname);
/** Multi detector Id */
const int multiId;
@ -2091,4 +2114,3 @@ class multiSlsDetector : public virtual slsDetectorDefs {
void *pCallbackArg{nullptr};
};
#endif

View File

@ -1,13 +1,4 @@
#ifndef SLS_DETECTOR_H
#define SLS_DETECTOR_H
/**
*
* @short complete detector functionalities for a single module detector.
* The slsDetector class takes care of the communication with the
* detector and all kind actions related with a single detector controller
* @author Anna Bergamaschi
*/
#pragma once
#include "ClientSocket.h"
#include "SharedMemory.h"
@ -18,6 +9,7 @@
class ClientInterface;
#include <cmath>
#include <vector>
class multiSlsDetector;
class ServerInterface;
@ -796,7 +788,7 @@ class slsDetector : public virtual slsDetectorDefs{
* @param detectorMAC detector MAC address
* @returns the detector MAC address
*/
std::string setDetectorMAC(const std::string &address);
std::string setDetectorMAC(const std::string &detectorMAC);
/**
* Returns the detector MAC address\sa sharedSlsDetector
@ -809,7 +801,7 @@ class slsDetector : public virtual slsDetectorDefs{
* @param detectorMAC detector MAC address (bottom half)
* @returns the detector MAC address (bottom half)
*/
std::string setDetectorMAC2(const std::string &address);
std::string setDetectorMAC2(const std::string &detectorMAC);
/**
* Returns the detector MAC address (bottom half) Jungfrau only
@ -1283,11 +1275,11 @@ class slsDetector : public virtual slsDetectorDefs{
int setStoragecellStart(int pos = -1);
/**
* Programs FPGA with pof file (Jungfrau)
* @param fname file name
* Programs FPGA with pof file (Jungfrau, CTB, Moench)
* @param buffer programming file in memory
* @returns OK or FAIL
*/
int programFPGA(const std::string &fname);
int programFPGA(std::vector<char> buffer);
/**
* Resets FPGA (Jungfrau)
@ -1296,6 +1288,20 @@ class slsDetector : public virtual slsDetectorDefs{
int resetFPGA();
/**
* Copies detector server from tftp and changes respawn server (Not Eiger)
* @param fname name of detector server binary
* @param hostname name of pc to tftp from
* @returns OK or FAIL
*/
int copyDetectorServer(const std::string &fname, const std::string &hostname);
/**
* Reboot detector controller (blackfin/ powerpc)
* @returns OK or FAIL
*/
int rebootController();
/**
* Power on/off Chip (Jungfrau)
* @param ival on is 1, off is 0, -1 to get
* @returns OK or FAIL
@ -1823,4 +1829,3 @@ class slsDetector : public virtual slsDetectorDefs{
};
#endif

View File

@ -2624,13 +2624,17 @@ int multiSlsDetector::setStoragecellStart(int pos, int detPos) {
}
int multiSlsDetector::programFPGA(const std::string &fname, int detPos) {
FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
// read pof file
std::vector<char> buffer = readPofFile(fname);
// single
if (detPos >= 0) {
return detectors[detPos]->programFPGA(fname);
return detectors[detPos]->programFPGA(buffer);
}
// multi
auto r = serialCall(&slsDetector::programFPGA, fname);
auto r = parallelCall(&slsDetector::programFPGA, buffer);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
}
@ -2645,6 +2649,47 @@ int multiSlsDetector::resetFPGA(int detPos) {
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
}
int multiSlsDetector::copyDetectorServer(const std::string &fname, const std::string &hostname, int detPos) {
// single
if (detPos >= 0) {
detectors[detPos]->copyDetectorServer(fname, hostname);
return detectors[detPos]->rebootController(); // reboot and copy should be independant for update command
}
// multi
parallelCall(&slsDetector::copyDetectorServer,fname, hostname);
auto r = parallelCall(&slsDetector::rebootController);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
}
int multiSlsDetector::rebootController(int detPos) {
// single
if (detPos >= 0) {
return detectors[detPos]->rebootController();
}
// multi
auto r = parallelCall(&slsDetector::rebootController);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
}
int multiSlsDetector::update(const std::string &sname, const std::string &hostname, const std::string &fname, int detPos) {
FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
// read pof file
std::vector<char> buffer = readPofFile(fname);
// single
if (detPos >= 0) {
detectors[detPos]->copyDetectorServer(sname, hostname);
return detectors[detPos]->programFPGA(buffer);
}
// multi
parallelCall(&slsDetector::copyDetectorServer,sname, hostname);
auto r = parallelCall(&slsDetector::programFPGA, buffer);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
}
int multiSlsDetector::powerChip(int ival, int detPos) {
// single
if (detPos >= 0) {
@ -4013,10 +4058,6 @@ void multiSlsDetector::startProcessingThread() {
dataProcessingThread = std::thread(&multiSlsDetector::processData, this);
}
// void* multiSlsDetector::startProcessData(void *n) {
// ((multiSlsDetector*)n)->processData();
// return n;
// }
void multiSlsDetector::processData() {
if (setReceiverOnline() == OFFLINE_FLAG) {
@ -4077,3 +4118,107 @@ int multiSlsDetector::kbhit() {
select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
std::vector<char> multiSlsDetector::readPofFile(const std::string &fname) {
FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
size_t filesize = 0;
// check if it exists
struct stat st;
if (stat(fname.c_str(), &st)) {
throw RuntimeError("Program FPGA: Programming file does not exist");
}
// open src
FILE *src = fopen(fname.c_str(), "rb");
if (src == nullptr) {
throw RuntimeError("Program FPGA: Could not open source file for programming: " +
fname);
}
// create temp destination file
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
int dst = mkstemp(destfname); // create temporary file and open it in r/w
if (dst == -1) {
fclose(src);
throw RuntimeError(
std::string("Could not create destination file in /tmp for programming: ") +
destfname);
}
// convert src to dst rawbin
FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname;
{
int filepos, x, y, i;
// Remove header (0...11C)
for (filepos = 0; filepos < 0x11C; ++filepos) {
fgetc(src);
}
// Write 0x80 times 0xFF (0...7F)
{
char c = 0xFF;
for (filepos = 0; filepos < 0x80; ++filepos) {
write(dst, &c, 1);
}
}
// Swap bits and write to file
for (filepos = 0x80; filepos < 0x1000000; ++filepos) {
x = fgetc(src);
if (x < 0) {
break;
}
y = 0;
for (i = 0; i < 8; ++i) {
y = y | (((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits
}
write(dst, &y, 1);
}
if (filepos < 0x1000000) {
throw RuntimeError("Could not convert programming file. EOF before end of flash");
}
}
if (fclose(src)) {
throw RuntimeError("Program FPGA: Could not close source file");
}
if (close(dst)) {
throw RuntimeError("Program FPGA: Could not close destination file");
}
FILE_LOG(logDEBUG1) << "File has been converted to " << destfname;
// loading dst file to memory
FILE *fp = fopen(destfname, "r");
if (fp == nullptr) {
throw RuntimeError("Program FPGA: Could not open rawbin file");
}
if (fseek(fp, 0, SEEK_END)) {
throw RuntimeError("Program FPGA: Seek error in rawbin file");
}
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)) {
throw RuntimeError("Program FPGA: Could not close destination file after converting");
}
unlink(destfname); // delete temporary file
FILE_LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
FILE_LOG(logINFO) << "Read file into memory";
return buffer;
}

View File

@ -845,7 +845,9 @@ int slsDetector::execCommand(const std::string &cmd) {
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
ret = client.sendCommandThenRead(fnum, arg, sizeof(arg), retval, sizeof(retval));
FILE_LOG(logINFO) << "Detector " << detId << " returned:\n" << retval;
if (strlen(retval)) {
FILE_LOG(logINFO) << "Detector " << detId << " returned:\n" << retval;
}
}
return ret;
}
@ -1597,12 +1599,12 @@ int slsDetector::configureMAC() {
// copy to args and convert to hex
snprintf(args[0], array_size, "%x", detector_shm()->receiverUDPPort);
sls::strcpy_safe(args[1], getReceiverUDPIP().str()); //TODO! Why not hex?
sls::strcpy_safe(args[1], getReceiverUDPIP().hex());
sls::strcpy_safe(args[2], getReceiverUDPMAC().hex());
sls::strcpy_safe(args[3], getDetectorIP().hex());
sls::strcpy_safe(args[4], getDetectorMAC().hex());
snprintf(args[5], array_size, "%x", detector_shm()->receiverUDPPort2);
sls::strcpy_safe(args[6], getReceiverUDPIP2().str());
sls::strcpy_safe(args[6], getReceiverUDPIP2().hex());
sls::strcpy_safe(args[7], getReceiverUDPMAC2().hex());
sls::strcpy_safe(args[8], getDetectorIP2().hex());
sls::strcpy_safe(args[9], getDetectorMAC2().hex());
@ -2036,14 +2038,14 @@ std::string slsDetector::setDetectorMAC(const std::string &address) {
auto addr = MacAddr(address);
if (addr == 0) {
throw RuntimeError("server MAC Address should be in xx:xx:xx:xx:xx:xx format");
} else {
detector_shm()->detectorMAC = addr;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
}
detector_shm()->detectorMAC = addr;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getDetectorMAC().str();
}
@ -2053,13 +2055,12 @@ std::string slsDetector::setDetectorMAC2(const std::string &address) {
auto addr = MacAddr(address);
if (addr == 0) {
throw RuntimeError("server MAC Address 2 should be in xx:xx:xx:xx:xx:xx format");
} else {
detector_shm()->detectorMAC2 = addr;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
}
detector_shm()->detectorMAC2 = addr;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getDetectorMAC2().str();
}
@ -2068,17 +2069,16 @@ MacAddr slsDetector::getDetectorMAC2() { return detector_shm()->detectorMAC2; }
std::string slsDetector::setDetectorIP(const std::string &ip) {
auto addr = IpAddr(ip);
if (addr != 0) {
detector_shm()->detectorIP = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
} else {
if (addr == 0) {
throw RuntimeError("setDetectorIP: IP Address should be VALID and "
"in xxx.xxx.xxx.xxx format");
}
detector_shm()->detectorIP = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getDetectorIP().str();
}
@ -2086,17 +2086,16 @@ IpAddr slsDetector::getDetectorIP() const { return detector_shm()->detectorIP; }
std::string slsDetector::setDetectorIP2(const std::string &ip) {
auto addr = IpAddr(ip);
if (addr != 0) {
detector_shm()->detectorIP2 = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
} else {
if (addr == 0) {
throw RuntimeError("setDetectorIP: IP2 Address should be VALID and "
"in xxx.xxx.xxx.xxx format");
}
detector_shm()->detectorIP2 = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getDetectorIP().str();
}
@ -2233,15 +2232,14 @@ std::string slsDetector::setReceiverUDPIP(const std::string &udpip) {
if (ip == 0) {
throw ReceiverError("setReceiverUDPIP: UDP IP Address should be "
"VALID and in xxx.xxx.xxx.xxx format");
} else {
detector_shm()->receiverUDPIP = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getReceiverUDPIP().str();
}
detector_shm()->receiverUDPIP = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getReceiverUDPIP().str();
}
sls::IpAddr slsDetector::getReceiverUDPIP() const { return detector_shm()->receiverUDPIP; }
@ -2251,15 +2249,14 @@ std::string slsDetector::setReceiverUDPIP2(const std::string &udpip) {
if (ip == 0) {
throw ReceiverError("setReceiverUDPIP: UDP IP Address 2 should be "
"VALID and in xxx.xxx.xxx.xxx format");
} else {
detector_shm()->receiverUDPIP2 = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getReceiverUDPIP2().str();
}
detector_shm()->receiverUDPIP2 = ip;
if (!strcmp(detector_shm()->receiver_hostname, "none")) {
FILE_LOG(logDEBUG1) << "Receiver hostname not set yet";
} else if (setUDPConnection() == FAIL) {
FILE_LOG(logWARNING) << "UDP connection set up failed";
}
return getReceiverUDPIP2().str();
}
sls::IpAddr slsDetector::getReceiverUDPIP2() const { return detector_shm()->receiverUDPIP2; }
@ -3259,223 +3256,99 @@ int slsDetector::setStoragecellStart(int pos) {
return retval;
}
int slsDetector::programFPGA(const std::string &fname) {
// TODO! make exception safe!
// now malloced memory can leak
// only jungfrau implemented (client processing, so check now)
if (detector_shm()->myDetectorType != JUNGFRAU &&
detector_shm()->myDetectorType != CHIPTESTBOARD &&
detector_shm()->myDetectorType != MOENCH) {
throw RuntimeError("Program FPGA is not implemented for this detector");
}
FILE_LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
size_t filesize = 0;
char *fpgasrc = nullptr;
int slsDetector::programFPGA(std::vector<char> buffer) {
// validate type
switch(detector_shm()->myDetectorType) {
case JUNGFRAU:
case CHIPTESTBOARD:
case MOENCH:
break;
default:
throw RuntimeError("Program FPGA is not implemented for this detector");
}
// check if it exists
{
struct stat st;
if (stat(fname.c_str(), &st)) {
throw RuntimeError("Program FPGA: Programming file does not exist");
}
}
size_t filesize = buffer.size();
{
// open src
FILE *src = fopen(fname.c_str(), "rb");
if (src == nullptr) {
throw RuntimeError("Program FPGA: Could not open source file for programming: " +
fname);
}
// send program from memory to detector
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
FILE_LOG(logINFO) << "Sending programming binary to detector " << detId << " (" << detector_shm()->hostname << ")";
// create temp destination file
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
int dst = mkstemp(destfname); // create temporary file and open it in r/w
if (dst == -1) {
fclose(src);
throw RuntimeError(std::string("Could not create destination file "
"in /tmp for programming: ") +
destfname);
}
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
client.sendData(&fnum, sizeof(fnum));
client.sendData(&filesize, sizeof(filesize));
client.receiveData(&ret, sizeof(ret));
// error in detector at opening file pointer to flash
if (ret == FAIL) {
client.receiveData(mess, sizeof(mess));
std::ostringstream os;
os << "Detector " << detId << " (" << detector_shm()->hostname << ")" <<
" returned error: " << mess;
throw RuntimeError(os.str());
}
// convert src to dst rawbin
FILE_LOG(logDEBUG1) << "Converting " << fname << " to " << destfname;
{
int filepos, x, y, i;
// Remove header (0...11C)
for (filepos = 0; filepos < 0x11C; ++filepos) {
fgetc(src);
}
// Write 0x80 times 0xFF (0...7F)
{
char c = 0xFF;
for (filepos = 0; filepos < 0x80; ++filepos) {
write(dst, &c, 1);
}
}
// Swap bits and write to file
for (filepos = 0x80; filepos < 0x1000000; ++filepos) {
x = fgetc(src);
if (x < 0) {
break;
}
y = 0;
for (i = 0; i < 8; ++i) {
y = y | (((x & (1 << i)) >> i) << (7 - i)); // This swaps the bits
}
write(dst, &y, 1);
}
if (filepos < 0x1000000) {
throw RuntimeError("Could not convert programming file. EOF "
"before end of flash");
}
}
if (fclose(src)) {
throw RuntimeError("Program FPGA: Could not close source file");
}
if (close(dst)) {
throw RuntimeError("Program FPGA: Could not close destination file");
}
FILE_LOG(logDEBUG1) << "File has been converted to " << destfname;
// erasing flash
if (ret != FAIL) {
FILE_LOG(logINFO) << "Erasing Flash for detector " << detId << " (" << detector_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) {
usleep(1 * 1000 * 1000);
--count;
printf("%d%%\r", (int)(((double)(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
FILE_LOG(logINFO) << "Writing to Flash to detector " << detId << " (" << detector_shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush;
}
// loading dst file to memory
FILE *fp = fopen(destfname, "r");
if (fp == nullptr) {
throw RuntimeError("Program FPGA: Could not open rawbin file");
}
if (fseek(fp, 0, SEEK_END)) {
throw RuntimeError("Program FPGA: Seek error in rawbin file");
}
filesize = ftell(fp);
if (filesize <= 0) {
throw RuntimeError("Program FPGA: Could not get length of rawbin file");
}
rewind(fp);
fpgasrc = (char *)malloc(filesize + 1); //<------------------- MALLOC!
if (fpgasrc == nullptr) {
throw RuntimeError("Program FPGA: Could not allocate size of program");
}
if (fread(fpgasrc, sizeof(char), filesize, fp) != filesize) {
free(fpgasrc);
throw RuntimeError("Program FPGA: Could not read rawbin file");
}
// sending program in parts of 2mb each
size_t unitprogramsize = 0;
int currentPointer = 0;
size_t totalsize = filesize;
while (ret != FAIL && (filesize > 0)) {
if (fclose(fp)) {
free(fpgasrc);
throw RuntimeError("Program FPGA: Could not close destination file "
"after converting");
}
unlink(destfname); // delete temporary file
FILE_LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
}
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
if (unitprogramsize > filesize) { // less than 2mb
unitprogramsize = filesize;
}
FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
// send program from memory to detector
int fnum = F_PROGRAM_FPGA;
int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0};
FILE_LOG(logDEBUG1) << "Sending programming binary to detector";
client.sendData(&buffer[currentPointer], unitprogramsize);
client.receiveData(&ret, sizeof(ret));
if (ret != FAIL) {
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
client.sendData(&fnum, sizeof(fnum));
client.sendData(&filesize, sizeof(filesize));
client.receiveData(&ret, sizeof(ret));
// opening error
if (ret == FAIL) {
client.receiveData(mess, sizeof(mess));
free(fpgasrc);
throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess));
}
// erasing flash
if (ret != FAIL) {
FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
FILE_LOG(logINFO) << "Erasing Flash:";
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) {
usleep(1 * 1000 * 1000);
--count;
printf("%d%%\r", (int)(((double)(ERASE_TIME - count) / ERASE_TIME) * 100));
std::cout << std::flush;
}
printf("\n");
FILE_LOG(logINFO) << "Writing to Flash:";
printf("%d%%\r", 0);
std::cout << std::flush;
}
// sending program in parts of 2mb each
size_t unitprogramsize = 0;
int currentPointer = 0;
size_t totalsize = filesize;
while (ret != FAIL && (filesize > 0)) {
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
if (unitprogramsize > filesize) { // less than 2mb
unitprogramsize = filesize;
}
FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
client.sendData(fpgasrc + currentPointer, unitprogramsize);
client.receiveData(&ret, sizeof(ret));
if (ret != FAIL) {
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
// print progress
printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100));
std::cout << std::flush;
} else {
printf("\n");
client.receiveData(mess, sizeof(mess));
free(fpgasrc);
throw RuntimeError("Detector returned error: " + std::string(mess));
}
}
printf("\n");
// check ending error
if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) &&
(strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) {
client.receiveData(&ret, sizeof(ret));
if (ret == FAIL) {
client.receiveData(mess, sizeof(mess));
free(fpgasrc);
throw RuntimeError("Detector returned error: " + std::string(mess));
}
}
if (ret == FORCE_UPDATE) {
updateDetector();
}
// remapping stop server
if ((ret == FAIL) && (strstr(mess, "not implemented") == nullptr) &&
(strstr(mess, "locked") == nullptr) && (strstr(mess, "-update") == nullptr)) {
fnum = F_RESET_FPGA;
int stopret = FAIL;
auto stop = DetectorSocket(detector_shm()->hostname, detector_shm()->stopPort);
stop.sendData(&fnum, sizeof(fnum));
stop.receiveData(&stopret, sizeof(stopret));
if (stopret == FAIL) {
client.receiveData(mess, sizeof(mess));
free(fpgasrc);
throw RuntimeError("Detector returned error: " + std::string(mess));
}
}
}
FILE_LOG(logINFO) << "You can now restart the detector servers in normal mode.";
free(fpgasrc);
return ret;
// print progress
printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100));
std::cout << std::flush;
} else {
printf("\n");
client.receiveData(mess, sizeof(mess));
std::ostringstream os;
os << "Detector " << detId << " (" << detector_shm()->hostname << ")" <<
" returned error: " << mess;
throw RuntimeError(os.str());
}
}
printf("\n");
}
if (ret != FAIL) {
ret = rebootController();
}
return ret;
}
int slsDetector::resetFPGA() {
int fnum = F_RESET_FPGA;
int ret = FAIL;
@ -3490,6 +3363,37 @@ int slsDetector::resetFPGA() {
return ret;
}
int slsDetector::copyDetectorServer(const std::string &fname, const std::string &hostname) {
int fnum = F_COPY_DET_SERVER;
int ret = FAIL;
char args[2][MAX_STR_LENGTH] = {};
sls::strcpy_safe(args[0], fname.c_str());
sls::strcpy_safe(args[1], hostname.c_str());
FILE_LOG(logINFO) << "Sending detector server " << args[0] << " from host " << args[1];
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
ret = client.sendCommandThenRead(fnum, args, sizeof(args), nullptr, 0);
}
return ret;
}
int slsDetector::rebootController() {
if (detector_shm()->myDetectorType == EIGER) {
throw RuntimeError("Reboot controller not implemented for this detector");
}
int fnum = F_REBOOT_CONTROLLER;
int ret = FAIL;
FILE_LOG(logINFO) << "Sending reboot controller to detector " << detId << " (" << detector_shm()->hostname << ")";
if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
client.sendData(&fnum, sizeof(fnum));
ret = OK;
}
return ret;
}
int slsDetector::powerChip(int ival) {
int fnum = F_POWER_CHIP;
int ret = FAIL;

View File

@ -405,6 +405,27 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>copydetectorserver [sname] [phost]</b> copies the detector server sname via tftp from pc with hostname phost and changes respawn server for all detector. Not for Eiger. Only put! \c Returns \c ("successful", "failed")
*/
descrToFuncMap[i].m_pFuncName = "copydetectorserver";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>rebootdetpc </b> reboot detector controller blackfin. Only put! Not for Eiger. \c Returns \c ("successful", "failed")
*/
descrToFuncMap[i].m_pFuncName = "rebootcontroller";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>update [sname] [phost] [file] </b> updates the firmware to file and detector server to sname from phost via tftp and then reboots controller (blackfin). Only put! Not for Eiger. \c Returns \c ("successful", "failed")
*/
descrToFuncMap[i].m_pFuncName = "update";
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
++i;
/* chip */
/*! \page config
\section configchip Chip
@ -4753,9 +4774,6 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action,
if (strstr(args[1], ".pof") == nullptr)
return std::string("wrong usage: programming file should have .pof extension");
std::string sval = std::string(args[1]);
#ifdef VERBOSE
std::cout << " programming file " << sval << std::endl;
#endif
myDet->setOnline(ONLINE_FLAG, detPos);
if (myDet->programFPGA(sval, detPos) == OK)
return std::string("successful");
@ -4765,15 +4783,51 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action,
else if (cmd == "resetfpga") {
if (action == GET_ACTION)
return std::string("cannot get");
#ifdef VERBOSE
std::cout << " resetting fpga " << std::endl;
#endif
myDet->setOnline(ONLINE_FLAG, detPos);
if (myDet->resetFPGA(detPos) == OK)
return std::string("successful");
return std::string("failed");
}
else if (cmd == "copydetectorserver") {
if (action == GET_ACTION)
return std::string("cannot get");
if (narg < 3)
return ("wrong usage." + helpAdvanced(PUT_ACTION));
std::string sval = std::string(args[1]);
std::string pval = std::string(args[2]);
myDet->setOnline(ONLINE_FLAG, detPos);
if (myDet->copyDetectorServer(sval, pval, detPos) == OK)
return std::string("successful");
return std::string("failed");
}
else if (cmd == "rebootcontroller") {
if (action == GET_ACTION)
return std::string("cannot get");
myDet->setOnline(ONLINE_FLAG, detPos);
if (myDet->rebootController(detPos) == OK)
return std::string("successful");
return std::string("failed");
}
else if (cmd == "update") {
if (action == GET_ACTION)
return std::string("cannot get");
if (narg < 4)
return ("wrong usage." + helpAdvanced(PUT_ACTION));
// pof
if (strstr(args[3], ".pof") == nullptr)
return std::string("wrong usage: programming file should have .pof extension");
std::string sval = std::string(args[1]);
std::string pval = std::string(args[2]);
std::string fval = std::string(args[3]);
myDet->setOnline(ONLINE_FLAG, detPos);
if (myDet->update(sval, pval, fval, detPos) == OK)
return std::string("successful");
return std::string("failed");
}
else if (cmd == "powerchip") {
char ans[100];
myDet->setOnline(ONLINE_FLAG, detPos);
@ -4842,7 +4896,9 @@ std::string slsDetectorCommand::helpAdvanced(int action) {
os << "programfpga f \t programs the fpga with file f (with .pof extension)." << std::endl;
os << "resetfpga f \t resets fpga, f can be any value" << std::endl;
os << "copydetectorserver s p \t copies the detector server s via tftp from pc with hostname p and changes respawn server. Not for Eiger. " << std::endl;
os << "rebootcontroller \t reboot controler blackfin of the detector. Not for Eiger." << std::endl;
os << "update s p f \t updates the firmware to f and detector server to f from host p via tftp and then reboots controller (blackfin). Not for Eiger. " << std::endl;
os << "led s \t sets led status (0 off, 1 on)" << std::endl;
os << "diodelay m v \tsets the delay for the digital IO pins selected by mask m and delay set by v. mask is upto 64 bits in hex, delay max is 775ps, and set in steps of 25 ps. Used for MOENCH/CTB only." << std::endl;
os << "powerchip i \t powers on or off the chip. i = 1 for on, i = 0 for off" << std::endl;