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
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 5a4122ae7c8dae1572e9db336de70183956e58c7
Revision: 31
Branch: refactor
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4481
Last Changed Date: 2019-03-28 08:18:03.000000002 +0100 ../slsDetectorServer/slsDetectorFunctionList.h
Repsitory UUID: ed9dc3b386898603d74a489528292139d47aac1a
Revision: 32
Branch: program
Last Changed Author: Erik_Frojdh
Last Changed Rev: 4488
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 GITREPUUID "5a4122ae7c8dae1572e9db336de70183956e58c7"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4481
#define GITDATE 0x20190328
#define GITBRANCH "refactor"
#define GITREPUUID "ed9dc3b386898603d74a489528292139d47aac1a"
#define GITAUTH "Erik_Frojdh"
#define GITREV 0x4488
#define GITDATE 0x20190329
#define GITBRANCH "program"

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"
@ -2002,11 +1995,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
@ -2025,6 +2013,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;
@ -2083,4 +2080,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"
@ -17,6 +8,7 @@
class ClientInterface;
#include <cmath>
#include <vector>
class multiSlsDetector;
class ServerInterface;
@ -1286,11 +1278,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)
@ -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) {
// 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;
}
@ -3986,10 +3989,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) {
@ -4050,3 +4049,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

@ -3386,221 +3386,126 @@ 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 " << 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));
// opening error
if (ret == FAIL) {
client.receiveData(mess, sizeof(mess));
throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess));
}
// 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) << "This can take awhile. Please be patient...";
FILE_LOG(logINFO) << detId << "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) << detId << "Writing to Flash:";
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));
}
// print progress
printf("%d%%\r", (int)(((double)(totalsize - filesize) / totalsize) * 100));
std::cout << std::flush;
} else {
printf("\n");
client.receiveData(mess, sizeof(mess));
throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess));
}
}
printf("\n");
// 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;
}
// 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));
throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess));
}
}
// sending program in parts of 2mb each
size_t unitprogramsize = 0;
int currentPointer = 0;
size_t totalsize = filesize;
while (ret != FAIL && (filesize > 0)) {
if (ret == FORCE_UPDATE) {
updateDetector();
}
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;
// 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));
throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess));
}
}
}
FILE_LOG(logINFO) << "You can now restart the detector " + std::to_string(detId) +
" in normal mode.";
return ret;
}
int slsDetector::resetFPGA() {
int fnum = F_RESET_FPGA;
int ret = FAIL;