program fpga made parallel

This commit is contained in:
2019-03-29 17:59:06 +01:00
parent ed9dc3b386
commit 969551ae37
6 changed files with 242 additions and 247 deletions

View File

@ -1,9 +1,9 @@
Path: slsDetectorPackage/slsDetectorServers/jungfrauDetectorServer Path: slsDetectorPackage/slsDetectorServers/jungfrauDetectorServer
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 5a4122ae7c8dae1572e9db336de70183956e58c7 Repsitory UUID: ed9dc3b386898603d74a489528292139d47aac1a
Revision: 31 Revision: 32
Branch: refactor Branch: program
Last Changed Author: Dhanya_Thattil Last Changed Author: Erik_Frojdh
Last Changed Rev: 4481 Last Changed Rev: 4488
Last Changed Date: 2019-03-28 08:18:03.000000002 +0100 ../slsDetectorServer/slsDetectorFunctionList.h Last Changed Date: 2019-03-29 14:42:42.000000002 +0100 ../slsDetectorServer/slsDetectorServer_funcs.c

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git" #define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "5a4122ae7c8dae1572e9db336de70183956e58c7" #define GITREPUUID "ed9dc3b386898603d74a489528292139d47aac1a"
#define GITAUTH "Dhanya_Thattil" #define GITAUTH "Erik_Frojdh"
#define GITREV 0x4481 #define GITREV 0x4488
#define GITDATE 0x20190328 #define GITDATE 0x20190329
#define GITBRANCH "refactor" #define GITBRANCH "program"

View File

@ -1,12 +1,5 @@
#ifndef MULTI_SLS_DETECTOR_H #pragma once
#define MULTI_SLS_DETECTOR_H
/**
@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 "SharedMemory.h"
#include "error_defs.h" #include "error_defs.h"
#include "gitInfoLib.h" #include "gitInfoLib.h"
@ -2002,11 +1995,6 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/ */
void startProcessingThread(); void startProcessingThread();
// /**
// * Static function to call processing thread
// */
// static void* startProcessData(void *n);
/** /**
* Check if processing thread is ready to join main thread * Check if processing thread is ready to join main thread
* @returns true if ready, else false * @returns true if ready, else false
@ -2025,6 +2013,15 @@ class multiSlsDetector : public virtual slsDetectorDefs {
*/ */
int kbhit(); 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 */ /** Multi detector Id */
const int multiId; const int multiId;
@ -2083,4 +2080,3 @@ class multiSlsDetector : public virtual slsDetectorDefs {
void *pCallbackArg{nullptr}; void *pCallbackArg{nullptr};
}; };
#endif

View File

@ -1,13 +1,4 @@
#ifndef SLS_DETECTOR_H #pragma once
#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
*/
#include "ClientSocket.h" #include "ClientSocket.h"
#include "SharedMemory.h" #include "SharedMemory.h"
@ -17,6 +8,7 @@
class ClientInterface; class ClientInterface;
#include <cmath> #include <cmath>
#include <vector>
class multiSlsDetector; class multiSlsDetector;
class ServerInterface; class ServerInterface;
@ -1286,11 +1278,11 @@ class slsDetector : public virtual slsDetectorDefs{
int setStoragecellStart(int pos = -1); int setStoragecellStart(int pos = -1);
/** /**
* Programs FPGA with pof file (Jungfrau) * Programs FPGA with pof file (Jungfrau, CTB, Moench)
* @param fname file name * @param buffer programming file in memory
* @returns OK or FAIL * @returns OK or FAIL
*/ */
int programFPGA(const std::string &fname); int programFPGA(std::vector<char> buffer);
/** /**
* Resets FPGA (Jungfrau) * Resets FPGA (Jungfrau)
@ -1826,4 +1818,3 @@ class slsDetector : public virtual slsDetectorDefs{
}; };
#endif

View File

@ -2597,13 +2597,16 @@ int multiSlsDetector::setStoragecellStart(int pos, int detPos) {
} }
int multiSlsDetector::programFPGA(const std::string &fname, int detPos) { int multiSlsDetector::programFPGA(const std::string &fname, int detPos) {
// read pof file
std::vector<char> buffer = readPofFile(fname);
// single // single
if (detPos >= 0) { if (detPos >= 0) {
return detectors[detPos]->programFPGA(fname); return detectors[detPos]->programFPGA(buffer);
} }
// multi // multi
auto r = serialCall(&slsDetector::programFPGA, fname); auto r = parallelCall(&slsDetector::programFPGA, buffer);
return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL; return sls::allEqualTo(r, static_cast<int>(OK)) ? OK : FAIL;
} }
@ -3986,10 +3989,6 @@ void multiSlsDetector::startProcessingThread() {
dataProcessingThread = std::thread(&multiSlsDetector::processData, this); dataProcessingThread = std::thread(&multiSlsDetector::processData, this);
} }
// void* multiSlsDetector::startProcessData(void *n) {
// ((multiSlsDetector*)n)->processData();
// return n;
// }
void multiSlsDetector::processData() { void multiSlsDetector::processData() {
if (setReceiverOnline() == OFFLINE_FLAG) { if (setReceiverOnline() == OFFLINE_FLAG) {
@ -4050,3 +4049,107 @@ int multiSlsDetector::kbhit() {
select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &tv); select(STDIN_FILENO + 1, &fds, nullptr, nullptr, &tv);
return FD_ISSET(STDIN_FILENO, &fds); 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

@ -3386,119 +3386,24 @@ int slsDetector::setStoragecellStart(int pos) {
return retval; return retval;
} }
int slsDetector::programFPGA(const std::string &fname) { int slsDetector::programFPGA(std::vector<char> buffer) {
// TODO! make exception safe! // validate type
// now malloced memory can leak switch(detector_shm()->myDetectorType) {
// only jungfrau implemented (client processing, so check now) case JUNGFRAU:
if (detector_shm()->myDetectorType != JUNGFRAU && case CHIPTESTBOARD:
detector_shm()->myDetectorType != CHIPTESTBOARD && case MOENCH:
detector_shm()->myDetectorType != MOENCH) { break;
default:
throw RuntimeError("Program FPGA is not implemented for this detector"); 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;
// check if it exists size_t filesize = buffer.size();
{
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);
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");
}
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";
}
// send program from memory to detector // send program from memory to detector
int fnum = F_PROGRAM_FPGA; int fnum = F_PROGRAM_FPGA;
int ret = FAIL; int ret = FAIL;
char mess[MAX_STR_LENGTH] = {0}; char mess[MAX_STR_LENGTH] = {0};
FILE_LOG(logDEBUG1) << "Sending programming binary to detector"; FILE_LOG(logINFO) << "Sending programming binary to detector " << detector_shm()->hostname;
if (detector_shm()->onlineFlag == ONLINE_FLAG) { if (detector_shm()->onlineFlag == ONLINE_FLAG) {
auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort); auto client = DetectorSocket(detector_shm()->hostname, detector_shm()->controlPort);
@ -3508,7 +3413,6 @@ int slsDetector::programFPGA(const std::string &fname) {
// opening error // opening error
if (ret == FAIL) { if (ret == FAIL) {
client.receiveData(mess, sizeof(mess)); client.receiveData(mess, sizeof(mess));
free(fpgasrc);
throw RuntimeError("Detector " + std::to_string(detId) + throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
@ -3516,7 +3420,7 @@ int slsDetector::programFPGA(const std::string &fname) {
// erasing flash // erasing flash
if (ret != FAIL) { if (ret != FAIL) {
FILE_LOG(logINFO) << "This can take awhile. Please be patient..."; FILE_LOG(logINFO) << "This can take awhile. Please be patient...";
FILE_LOG(logINFO) << "Erasing Flash:"; FILE_LOG(logINFO) << detId << "Erasing Flash:";
printf("%d%%\r", 0); printf("%d%%\r", 0);
std::cout << std::flush; std::cout << std::flush;
// erasing takes 65 seconds, printing here (otherwise need threads // erasing takes 65 seconds, printing here (otherwise need threads
@ -3530,7 +3434,7 @@ int slsDetector::programFPGA(const std::string &fname) {
std::cout << std::flush; std::cout << std::flush;
} }
printf("\n"); printf("\n");
FILE_LOG(logINFO) << "Writing to Flash:"; FILE_LOG(logINFO) << detId << "Writing to Flash:";
printf("%d%%\r", 0); printf("%d%%\r", 0);
std::cout << std::flush; std::cout << std::flush;
} }
@ -3548,7 +3452,7 @@ int slsDetector::programFPGA(const std::string &fname) {
FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize FILE_LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize; << "\t filesize:" << filesize;
client.sendData(fpgasrc + currentPointer, unitprogramsize); client.sendData(&buffer[currentPointer], unitprogramsize);
client.receiveData(&ret, sizeof(ret)); client.receiveData(&ret, sizeof(ret));
if (ret != FAIL) { if (ret != FAIL) {
filesize -= unitprogramsize; filesize -= unitprogramsize;
@ -3560,8 +3464,8 @@ int slsDetector::programFPGA(const std::string &fname) {
} else { } else {
printf("\n"); printf("\n");
client.receiveData(mess, sizeof(mess)); client.receiveData(mess, sizeof(mess));
free(fpgasrc); throw RuntimeError("Detector " + std::to_string(detId) +
throw RuntimeError("Detector returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
} }
printf("\n"); printf("\n");
@ -3572,8 +3476,8 @@ int slsDetector::programFPGA(const std::string &fname) {
client.receiveData(&ret, sizeof(ret)); client.receiveData(&ret, sizeof(ret));
if (ret == FAIL) { if (ret == FAIL) {
client.receiveData(mess, sizeof(mess)); client.receiveData(mess, sizeof(mess));
free(fpgasrc); throw RuntimeError("Detector " + std::to_string(detId) +
throw RuntimeError("Detector returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
} }
@ -3591,16 +3495,17 @@ int slsDetector::programFPGA(const std::string &fname) {
stop.receiveData(&stopret, sizeof(stopret)); stop.receiveData(&stopret, sizeof(stopret));
if (stopret == FAIL) { if (stopret == FAIL) {
client.receiveData(mess, sizeof(mess)); client.receiveData(mess, sizeof(mess));
free(fpgasrc); throw RuntimeError("Detector " + std::to_string(detId) +
throw RuntimeError("Detector returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} }
} }
} }
FILE_LOG(logINFO) << "You can now restart the detector servers in normal mode."; FILE_LOG(logINFO) << "You can now restart the detector " + std::to_string(detId) +
free(fpgasrc); " in normal mode.";
return ret; return ret;
} }
int slsDetector::resetFPGA() { int slsDetector::resetFPGA() {
int fnum = F_RESET_FPGA; int fnum = F_RESET_FPGA;
int ret = FAIL; int ret = FAIL;