mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-16 07:01:33 +01:00
Merge pull request #333 from slsdetectorgroup/3kernelupdate
3kernelupdate
This commit is contained in:
@@ -137,7 +137,6 @@ sls_enable_cxx_warning("-Wnull-dereference")
|
||||
sls_enable_cxx_warning("-Wduplicated-cond")
|
||||
sls_disable_cxx_warning("-Wclass-memaccess")
|
||||
sls_disable_c_warning("-Wstringop-truncation")
|
||||
sls_disable_c_warning("-Wformat-nonliteral")
|
||||
|
||||
|
||||
if(SLS_USE_SANITIZER)
|
||||
|
||||
@@ -20,7 +20,9 @@ This document describes the differences between vx.x.x and v6.0.0.
|
||||
1. New or Changed Features
|
||||
==========================
|
||||
- kernelversion
|
||||
|
||||
- updatekernel
|
||||
- updatedetectorserver
|
||||
- update (without pcname)
|
||||
|
||||
|
||||
2. Resolved Issues
|
||||
@@ -30,6 +32,8 @@ This document describes the differences between vx.x.x and v6.0.0.
|
||||
- rx id in config file was not taken into account. fixed.
|
||||
- programming firmware failure for blackfin, fixed but requires new kernel.
|
||||
- nios kernel check updated (ensuring right kernel)
|
||||
- executecommand now says which module failed
|
||||
- programming firmware did not delete temporary file created. fixed.
|
||||
|
||||
3. Known Issues
|
||||
===============
|
||||
|
||||
@@ -1521,6 +1521,14 @@ void init_det(py::module &m) {
|
||||
sls::Positions)) &
|
||||
Detector::copyDetectorServer,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("updateDetectorServer",
|
||||
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||
Detector::updateDetectorServer,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("updateKernel",
|
||||
(void (Detector::*)(const std::string &, sls::Positions)) &
|
||||
Detector::updateKernel,
|
||||
py::arg(), py::arg() = Positions{})
|
||||
.def("rebootController",
|
||||
(void (Detector::*)(sls::Positions)) & Detector::rebootController,
|
||||
py::arg() = Positions{})
|
||||
@@ -1529,6 +1537,11 @@ void init_det(py::module &m) {
|
||||
const std::string &, sls::Positions)) &
|
||||
Detector::updateFirmwareAndServer,
|
||||
py::arg(), py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("updateFirmwareAndServer",
|
||||
(void (Detector::*)(const std::string &, const std::string &,
|
||||
sls::Positions)) &
|
||||
Detector::updateFirmwareAndServer,
|
||||
py::arg(), py::arg(), py::arg() = Positions{})
|
||||
.def("readRegister",
|
||||
(Result<uint32_t>(Detector::*)(uint32_t, sls::Positions) const) &
|
||||
Detector::readRegister,
|
||||
|
||||
@@ -17,7 +17,7 @@ add_executable(ctbDetectorServer_virtual
|
||||
../slsDetectorServer/src/INA226.c
|
||||
../slsDetectorServer/src/LTC2620.c
|
||||
../slsDetectorServer/src/MAX1932.c
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/programViaBlackfin.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
|
||||
@@ -16,7 +16,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programViaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -97,8 +97,14 @@ void basictests() {
|
||||
return;
|
||||
#else
|
||||
|
||||
defineGPIOpins();
|
||||
resetFPGA();
|
||||
initError = defineGPIOpins(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
initError = resetFPGA(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
if (mapCSP0() == FAIL) {
|
||||
strcpy(initErrorMessage,
|
||||
"Could not map to memory. Dangerous to continue.\n");
|
||||
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#define LINKED_SERVER_NAME "eigerDetectorServer"
|
||||
#define LINKED_SERVER_NAME "/home/root/executables/eigerDetectorServer"
|
||||
|
||||
#define REQUIRED_FIRMWARE_VERSION (29)
|
||||
// virtual ones renamed for consistency
|
||||
|
||||
@@ -12,7 +12,7 @@ add_executable(gotthard2DetectorServer_virtual
|
||||
../slsDetectorServer/src/LTC2620_Driver.c
|
||||
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
|
||||
../slsDetectorServer/src/ASIC_Driver.c
|
||||
../slsDetectorServer/src/programFpgaNios.c
|
||||
../slsDetectorServer/src/programViaNios.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programViaNios.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -11,6 +11,7 @@ add_executable(gotthardDetectorServer_virtual
|
||||
../slsDetectorServer/src/LTC2620.c
|
||||
../slsDetectorServer/src/common.c
|
||||
../slsDetectorServer/src/commonServerFunctions.c
|
||||
../slsDetectorServer/src/programViaBlackfin.c
|
||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
|
||||
@@ -15,7 +15,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)programViaBlackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
all: clean $(PROGS)
|
||||
|
||||
Binary file not shown.
@@ -6,6 +6,8 @@
|
||||
|
||||
#define LINKED_SERVER_NAME "gotthardDetectorServer"
|
||||
|
||||
#define CTRL_SRVR_INIT_TIME_US (300 * 1000)
|
||||
|
||||
/* Enums */
|
||||
enum ADCINDEX { TEMP_FPGA, TEMP_ADC };
|
||||
enum DACINDEX {
|
||||
|
||||
@@ -12,7 +12,7 @@ add_executable(jungfrauDetectorServer_virtual
|
||||
../slsDetectorServer/src/ALTERA_PLL.c
|
||||
../slsDetectorServer/src/LTC2620.c
|
||||
../slsDetectorServer/src/MAX1932.c
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/programViaBlackfin.c
|
||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
|
||||
@@ -15,7 +15,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programViaBlackfin.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -74,8 +74,14 @@ void basictests() {
|
||||
}
|
||||
return;
|
||||
#else
|
||||
defineGPIOpins();
|
||||
resetFPGA();
|
||||
initError = defineGPIOpins(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
initError = resetFPGA(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
if (mapCSP0() == FAIL) {
|
||||
strcpy(initErrorMessage,
|
||||
"Could not map to memory. Dangerous to continue.\n");
|
||||
|
||||
@@ -14,7 +14,7 @@ add_executable(moenchDetectorServer_virtual
|
||||
../slsDetectorServer/src/ALTERA_PLL.c
|
||||
../slsDetectorServer/src/LTC2620.c
|
||||
../slsDetectorServer/src/MAX1932.c
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/programViaBlackfin.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
|
||||
@@ -16,7 +16,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programViaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -94,8 +94,14 @@ void basictests() {
|
||||
return;
|
||||
#else
|
||||
|
||||
defineGPIOpins();
|
||||
resetFPGA();
|
||||
initError = defineGPIOpins(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
initError = resetFPGA(initErrorMessage);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
if (mapCSP0() == FAIL) {
|
||||
strcpy(initErrorMessage,
|
||||
"Could not map to memory. Dangerous to continue.\n");
|
||||
|
||||
@@ -12,7 +12,7 @@ add_executable(mythen3DetectorServer_virtual
|
||||
../slsDetectorServer/src/common.c
|
||||
../slsDetectorServer/src/LTC2620_Driver.c
|
||||
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
|
||||
../slsDetectorServer/src/programFpgaNios.c
|
||||
../slsDetectorServer/src/programViaNios.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
|
||||
@@ -16,7 +16,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c $(md5_dir)md5.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programViaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -8,7 +8,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#define TEMP_PROG_FOLDER_NAME "/var/tmp/"
|
||||
#define TEMP_PROG_FOLDER_NAME_ALL_FILES "/var/tmp/*"
|
||||
#define TEMP_PROG_FILE_NAME TEMP_PROG_FOLDER_NAME "tmp.rawbin"
|
||||
|
||||
enum numberMode { DEC, HEX };
|
||||
enum PROGRAM_INDEX { PROGRAM_FPGA, PROGRAM_KERNEL, PROGRAM_SERVER };
|
||||
|
||||
/**
|
||||
* Convert a value from a range to a different range (eg voltage to dac or vice
|
||||
@@ -38,9 +43,17 @@ void validate64(int *ret, char *mess, int64_t arg, int64_t retval,
|
||||
char *modename, enum numberMode nummode);
|
||||
|
||||
int getModuleIdInFile(int *ret, char *mess, char *fileName);
|
||||
int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
|
||||
ssize_t bytes);
|
||||
int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname);
|
||||
int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
ssize_t fsize);
|
||||
int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg);
|
||||
int verifyChecksumFromBuffer(char *mess, char *functionType,
|
||||
char *clientChecksum, char *buffer, ssize_t bytes);
|
||||
int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum,
|
||||
char *fname);
|
||||
int verifyChecksumFromFlash(char *mess, char *functionType,
|
||||
char *clientChecksum, char *fname, ssize_t fsize);
|
||||
int verifyChecksum(char *mess, char *functionType, char *clientChecksum,
|
||||
MD5_CTX *c, char *msg);
|
||||
int setupDetectorServer(char *mess, char *sname);
|
||||
|
||||
int writeBinaryFile(char *mess, char *fname, char *buffer,
|
||||
const uint64_t filesize, char *errorPrefix);
|
||||
|
||||
int moveBinaryFile(char *mess, char *dest, char *src, char *errorPrefix);
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define TEMP_PROG_FILE_NAME "/var/tmp/tmp.rawbin"
|
||||
|
||||
void defineGPIOpins();
|
||||
void FPGAdontTouchFlash();
|
||||
void FPGATouchFlash();
|
||||
void resetFPGA();
|
||||
|
||||
int deleteOldFile(char *mess);
|
||||
/**
|
||||
* deletes old file
|
||||
* verify memory available to copy
|
||||
* open file to copy
|
||||
*/
|
||||
int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess);
|
||||
int copyToFlash(ssize_t fsize, 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(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess);
|
||||
/** Notify fpga to pick up firmware from flash and wait for status confirmation
|
||||
*/
|
||||
int waitForFPGAtoTouchFlash(char *mess);
|
||||
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
int defineGPIOpins(char *mess);
|
||||
int FPGAdontTouchFlash(char *mess);
|
||||
int FPGATouchFlash(char *mess);
|
||||
int resetFPGA(char *mess);
|
||||
|
||||
int emptyTempFolder(char *mess);
|
||||
/**
|
||||
* deletes old file
|
||||
* verify memory available to copy
|
||||
* open file to copy
|
||||
*/
|
||||
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);
|
||||
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 eraseFlash(char *mess);
|
||||
/* write from tmp file to flash */
|
||||
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd);
|
||||
/** Notify fpga to pick up firmware from flash and wait for status confirmation
|
||||
*/
|
||||
int waitForFPGAtoTouchFlash(char *mess);
|
||||
@@ -2,6 +2,8 @@
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -13,9 +15,10 @@ void NotifyServerStartSuccess();
|
||||
/** reset fpga and controller(only implemented for >= v1.1 boards) */
|
||||
void rebootControllerAndFPGA();
|
||||
|
||||
int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
|
||||
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
char *functionType, char *checksum, char *fpgasrc,
|
||||
uint64_t fsize);
|
||||
int getDrive(char *mess);
|
||||
int openFileForFlash(FILE **flashfd, char *mess);
|
||||
int getDrive(char *mess, enum PROGRAM_INDEX index);
|
||||
int openFileForFlash(char *mess, FILE **flashfd);
|
||||
int eraseFlash(char *mess);
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess);
|
||||
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, char *buffer);
|
||||
@@ -12,9 +12,10 @@
|
||||
#endif
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
#include "programFpgaNios.h"
|
||||
#elif defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) || defined(MOENCHD)
|
||||
#include "programFpgaBlackfin.h"
|
||||
#include "programViaNios.h"
|
||||
#elif defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) || defined(MOENCHD) || \
|
||||
defined(GOTTHARDD)
|
||||
#include "programViaBlackfin.h"
|
||||
#endif
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
@@ -60,7 +61,6 @@ typedef struct udpStruct_s {
|
||||
int isInitCheckDone();
|
||||
int getInitResult(char **mess);
|
||||
void basictests();
|
||||
int getKernelVersion(char* retvals);
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || \
|
||||
defined(MOENCHD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
int checkType();
|
||||
|
||||
@@ -278,3 +278,12 @@ int set_udp_first_dest(int);
|
||||
int get_readout_speed(int);
|
||||
int set_readout_speed(int);
|
||||
int get_kernel_version(int);
|
||||
int update_kernel(int);
|
||||
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);
|
||||
void receive_program_default(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName);
|
||||
@@ -4,12 +4,15 @@
|
||||
#include "common.h"
|
||||
#include "clogger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
#include <libgen.h> // dirname
|
||||
#include <string.h>
|
||||
#include <sys/utsname.h> // uname
|
||||
#include <unistd.h> // readlink
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
|
||||
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
|
||||
int outputMax, int inputValue, int *outputValue) {
|
||||
LOG(logDEBUG1, (" Input Value: %d (Input:(%d - %d), Output:(%d - %d))\n",
|
||||
@@ -92,14 +95,17 @@ int getTimeFromString(char *buf, time_t *result) {
|
||||
}
|
||||
|
||||
// print time structure
|
||||
LOG(logDEBUG, ("%d %d %d %d:%d:%d %d (day date month H:M:S year)\n", t.tm_wday, t.tm_mday, t.tm_mon, t.tm_year +1900, t.tm_hour, t.tm_min, t.tm_sec));
|
||||
LOG(logDEBUG,
|
||||
("%d %d %d %d:%d:%d %d (day date month H:M:S year)\n", t.tm_wday,
|
||||
t.tm_mday, t.tm_mon, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec));
|
||||
|
||||
*result = mktime(&t);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getKernelVersion(char *retvals) {
|
||||
struct utsname buf = {0};
|
||||
struct utsname buf;
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (uname(&buf) == -1) {
|
||||
strcpy(retvals, "Failed to get utsname structure from uname\n");
|
||||
LOG(logERROR, (retvals));
|
||||
@@ -135,7 +141,8 @@ int validateKernelVersion(char *expectedVersion) {
|
||||
// convert kernel date string into time
|
||||
time_t kernelDate;
|
||||
if (getTimeFromString(currentVersion, &kernelDate) == FAIL) {
|
||||
LOG(logERROR, ("Could not parse retrieved kernel date, %s\n", currentVersion));
|
||||
LOG(logERROR,
|
||||
("Could not parse retrieved kernel date, %s\n", currentVersion));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -155,8 +162,8 @@ int validateKernelVersion(char *expectedVersion) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("Kernel Version Compatible: %s [min.: %s]\n", currentVersion,
|
||||
expectedVersion));
|
||||
LOG(logINFOBLUE, ("Kernel Version Compatible: %s [min.: %s]\n",
|
||||
currentVersion, expectedVersion));
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -235,30 +242,39 @@ int getModuleIdInFile(int *ret, char *mess, char *fileName) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
|
||||
int verifyChecksumFromBuffer(char *mess, char *functionType,
|
||||
char *clientChecksum, char *buffer,
|
||||
ssize_t bytes) {
|
||||
LOG(logINFO, ("\tVerifying Checksum...\n"));
|
||||
LOG(logINFO, ("\tVerifying Checksum from memory...\n"));
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (!MD5_Update_SLS(&c, buffer, bytes)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return verifyChecksum(mess, clientChecksum, &c, "copied program");
|
||||
return verifyChecksum(mess, functionType, clientChecksum, &c,
|
||||
"copied program (buffer)");
|
||||
}
|
||||
|
||||
int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
|
||||
LOG(logINFO, ("\tVerifying Checksum...\n"));
|
||||
int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum,
|
||||
char *fname) {
|
||||
LOG(logINFO, ("\tVerifying Checksum of file...\n"));
|
||||
|
||||
FILE *fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
sprintf(mess, "Unable to open %s in read mode to get checksum\n",
|
||||
fname);
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Unable to open %s in read mode to get checksum\n",
|
||||
functionType, fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -266,7 +282,9 @@ int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -277,7 +295,10 @@ int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
|
||||
while (bytes > 0) {
|
||||
if (!MD5_Update_SLS(&c, buf, bytes)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -286,17 +307,20 @@ int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
|
||||
}
|
||||
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
|
||||
fclose(fp);
|
||||
return verifyChecksum(mess, clientChecksum, &c, "copied program");
|
||||
return verifyChecksum(mess, functionType, clientChecksum, &c,
|
||||
"copied program (file)");
|
||||
}
|
||||
|
||||
int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
ssize_t fsize) {
|
||||
LOG(logINFO, ("\tVerifying FlashChecksum...\n"));
|
||||
int verifyChecksumFromFlash(char *mess, char *functionType,
|
||||
char *clientChecksum, char *fname, ssize_t fsize) {
|
||||
LOG(logINFO, ("\tVerifying Checksum from flash...\n"));
|
||||
|
||||
FILE *fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
sprintf(mess, "Unable to open %s in read mode to get checksum\n",
|
||||
fname);
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Unable to open %s in read mode to get checksum\n",
|
||||
functionType, fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -304,7 +328,9 @@ int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -324,33 +350,39 @@ int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
|
||||
if (!MD5_Update_SLS(&c, buf, bytes)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// read only until a particular size (drive)
|
||||
if (fsize != 0 && totalBytesRead >= fsize) {
|
||||
LOG(logINFO,
|
||||
("\tReached %lu bytes. Not reading more\n", totalBytesRead));
|
||||
break;
|
||||
}
|
||||
bytes = fread(buf, 1, readUnitSize, fp);
|
||||
// for less than 128 bytes
|
||||
ssize_t bytesToRead = readUnitSize;
|
||||
if ((readUnitSize + totalBytesRead) > fsize) {
|
||||
bytesToRead = fsize - totalBytesRead;
|
||||
}
|
||||
bytes = fread(buf, 1, bytesToRead, fp);
|
||||
totalBytesRead += bytes;
|
||||
}
|
||||
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
|
||||
fclose(fp);
|
||||
int ret = verifyChecksum(mess, clientChecksum, &c, "flash");
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("Checksum in Flash verified\n"));
|
||||
}
|
||||
return ret;
|
||||
return verifyChecksum(mess, functionType, clientChecksum, &c, "flash");
|
||||
}
|
||||
|
||||
int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg) {
|
||||
int verifyChecksum(char *mess, char *functionType, char *clientChecksum,
|
||||
MD5_CTX *c, char *msg) {
|
||||
unsigned char out[MD5_DIGEST_LENGTH];
|
||||
if (!MD5_Final_SLS(out, c)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Final_SLS)\n");
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to calculate checksum (MD5_Final_SLS)\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -370,12 +402,177 @@ int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg) {
|
||||
// compare checksum
|
||||
if (strcmp(clientChecksum, checksum)) {
|
||||
sprintf(mess,
|
||||
"Checksum of %s does not match. Client "
|
||||
"Could not %s. Checksum of %s does not match. Client "
|
||||
"checksum:%s, copied checksum:%s\n",
|
||||
msg, clientChecksum, checksum);
|
||||
functionType, msg, clientChecksum, checksum);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tChecksum verified\n"));
|
||||
LOG(logINFO, ("\tChecksum of %s verified\n", msg));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int setupDetectorServer(char *mess, char *sname) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
// give permissions
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "chmod 777 %s", sname) >=
|
||||
MAX_STR_LENGTH) {
|
||||
strcpy(mess, "Could not copy detector server. Command to give "
|
||||
"permissions to server is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (permissions). %s\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tPermissions modified\n"));
|
||||
|
||||
// symbolic link
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "ln -sf %s %s", sname,
|
||||
LINKED_SERVER_NAME) >= MAX_STR_LENGTH) {
|
||||
strcpy(mess, "Could not copy detector server. Command to "
|
||||
"create symbolic link too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (symbolic link). %s\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tSymbolic link created\n"));
|
||||
|
||||
// blackfin boards (respawn) (only kept for backwards compatibility)
|
||||
#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || \
|
||||
defined(GOTTHARDD)
|
||||
// delete every line with DetectorServer in /etc/inittab
|
||||
strcpy(cmd, "sed -i '/DetectorServer/d' /etc/inittab");
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (del respawning). %s\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tinittab: DetectoServer line deleted\n"));
|
||||
|
||||
// add new link name to /etc/inittab
|
||||
if (snprintf(cmd, MAX_STR_LENGTH,
|
||||
"echo 'ttyS0::respawn:/./%s' >> /etc/inittab",
|
||||
LINKED_SERVER_NAME) >= MAX_STR_LENGTH) {
|
||||
strcpy(mess, "Could not copy detector server. Command "
|
||||
"to add new server for spawning is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (respawning). %s\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tinittab: updated for respawning\n"));
|
||||
|
||||
#endif
|
||||
|
||||
// sync
|
||||
strcpy(cmd, "sync");
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (sync). %s\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tsync\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeBinaryFile(char *mess, char *fname, char *buffer,
|
||||
const uint64_t filesize, char *errorPrefix) {
|
||||
LOG(logINFO, ("\tWriting Detector Server Binary...\n"));
|
||||
|
||||
FILE *fp = fopen(fname, "wb");
|
||||
if (fp == NULL) {
|
||||
sprintf(mess,
|
||||
"Could not %s. (opening file to write(%s). "
|
||||
"Maybe it is being used? Try another name?\n",
|
||||
errorPrefix, fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
size_t bytesWritten = 0;
|
||||
size_t unitSize = 128;
|
||||
int oldProgress = 0;
|
||||
|
||||
while (bytesWritten < filesize) {
|
||||
// print progress
|
||||
int progress = (int)(((double)(bytesWritten) / filesize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
|
||||
// for less than 128 bytes
|
||||
ssize_t writeSize = unitSize;
|
||||
if ((unitSize + bytesWritten) > filesize) {
|
||||
writeSize = filesize - bytesWritten;
|
||||
}
|
||||
size_t bytes = fwrite((char *)buffer + bytesWritten, 1, writeSize, fp);
|
||||
|
||||
// write
|
||||
if (bytes != (size_t)writeSize) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Expected to write %lu "
|
||||
"bytes, wrote %lu bytes). No space left? \n",
|
||||
errorPrefix, (long unsigned int)filesize,
|
||||
(long unsigned int)bytesWritten);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
bytesWritten += bytes;
|
||||
LOG(logDEBUG1,
|
||||
("bytesWritten:%lu filesize:%lu\n", bytesWritten, filesize));
|
||||
}
|
||||
if (fclose(fp) != 0) {
|
||||
sprintf(mess, "Could not %s. (closing file pointer)\n", errorPrefix);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWritten binary to %s (%lu bytes)\n", fname,
|
||||
(long unsigned int)bytesWritten));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int moveBinaryFile(char *mess, char *dest, char *src, char *errorPrefix) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
// one can move into the current process binary (will not interfere in
|
||||
// kernel mode)
|
||||
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "mv %s %s", src, dest) >=
|
||||
MAX_STR_LENGTH) {
|
||||
sprintf(mess, "Could not %s. Command to move binary is too long\n",
|
||||
errorPrefix);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH, "Could not %s. (moving). %s\n",
|
||||
errorPrefix, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tMoved file from %s to %s\n", src, dest));
|
||||
return OK;
|
||||
}
|
||||
@@ -1,418 +0,0 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "programFpgaBlackfin.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
#include "sls/ansi.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
/* global variables */
|
||||
// clang-format off
|
||||
#define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s
|
||||
#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_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB
|
||||
// clang-format on
|
||||
|
||||
#define FLASH_DRIVE_NAME_SIZE 16
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
|
||||
int gpioDefined = 0;
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
|
||||
int latestKernelVerified = -1;
|
||||
#define KERNEL_DATE_VRSN_3GPIO "Fri Oct 29 00:00:00 2021"
|
||||
|
||||
void defineGPIOpins() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
if (latestKernelVerified == -1) {
|
||||
if (FAIL == validateKernelVersion(KERNEL_DATE_VRSN_3GPIO)) {
|
||||
latestKernelVerified = 0;
|
||||
LOG(logWARNING,
|
||||
("Kernel too old to use gpio 3 pins. Not the end "
|
||||
"of the world. Continuing with current kernel.\n"));
|
||||
} else {
|
||||
latestKernelVerified = 1;
|
||||
}
|
||||
}
|
||||
if (!gpioDefined) {
|
||||
// define the gpio pins
|
||||
system("echo 7 > /sys/class/gpio/export");
|
||||
LOG(logINFO, ("\tgpio7: defined\n"));
|
||||
system("echo in > /sys/class/gpio/gpio7/direction");
|
||||
LOG(logINFO, ("\tgpio7: setting intput\n"));
|
||||
system("echo 9 > /sys/class/gpio/export");
|
||||
LOG(logINFO, ("\tgpio9: defined\n"));
|
||||
|
||||
if (latestKernelVerified == 1) {
|
||||
// gpio 3 = not chip enable
|
||||
system("echo 3 > /sys/class/gpio/export");
|
||||
LOG(logINFO, ("\tgpio3: defined\n"));
|
||||
}
|
||||
gpioDefined = 1;
|
||||
} else
|
||||
LOG(logDEBUG1, ("gpio pins already defined earlier\n"));
|
||||
}
|
||||
|
||||
void FPGAdontTouchFlash() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
// define as output pins
|
||||
system("echo out > /sys/class/gpio/gpio9/direction");
|
||||
LOG(logINFO, ("\tgpio9: setting output\n"));
|
||||
if (latestKernelVerified == 1) {
|
||||
// gpio 3 = not chip enable
|
||||
system("echo out > /sys/class/gpio/gpio3/direction");
|
||||
LOG(logINFO, ("\tgpio3: setting output\n"));
|
||||
}
|
||||
|
||||
// tell FPGA to not touch flash
|
||||
system("echo 0 > /sys/class/gpio/gpio9/value");
|
||||
LOG(logINFO, ("\tgpio9: fpga dont touch flash\n"));
|
||||
if (latestKernelVerified == 1) {
|
||||
system("echo 1 > /sys/class/gpio/gpio3/value");
|
||||
LOG(logINFO, ("\tgpio3: fpga dont touch flash\n"));
|
||||
}
|
||||
// usleep(100*1000);
|
||||
}
|
||||
|
||||
void FPGATouchFlash() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
// tell FPGA to touch flash to program itself
|
||||
system("echo in > /sys/class/gpio/gpio9/direction");
|
||||
LOG(logINFO, ("\tgpio9: setting input\n"));
|
||||
if (latestKernelVerified == 1) {
|
||||
system("echo in > /sys/class/gpio/gpio3/direction");
|
||||
LOG(logINFO, ("\tgpio3: setting input\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void resetFPGA() {
|
||||
LOG(logINFOBLUE, ("Reseting FPGA\n"));
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
FPGAdontTouchFlash();
|
||||
FPGATouchFlash();
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
}
|
||||
|
||||
int deleteOldFile(char *mess) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
char *format = "rm -fr %s";
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, format, TEMP_PROG_FILE_NAME) >=
|
||||
MAX_STR_LENGTH) {
|
||||
strcpy(
|
||||
mess,
|
||||
"Could not program fpga. Command to delete old file is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not delete old file: %s)\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO,
|
||||
("\tDeleted old programming file (%s)\n", TEMP_PROG_FILE_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess) {
|
||||
|
||||
if (deleteOldFile(mess) == FAIL) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// open file to copy program
|
||||
*fd = fopen(TEMP_PROG_FILE_NAME, "w");
|
||||
if (*fd == NULL) {
|
||||
sprintf(mess, "Unable to open %s in write mode\n", TEMP_PROG_FILE_NAME);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tGoing to copy program to %s\n", TEMP_PROG_FILE_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int copyToFlash(ssize_t fsize, char *clientChecksum, char *mess) {
|
||||
|
||||
if (getDrive(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
FILE *srcfd = NULL;
|
||||
if (openFileForFlash(&flashfd, &srcfd, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (eraseFlash(mess) == FAIL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (writeToFlash(fsize, flashfd, srcfd, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (deleteOldFile(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* ignoring this until flash fixed
|
||||
if (verifyChecksumFromFlash(mess, clientChecksum, flashDriveName, fsize) == FAIL) { return FAIL;
|
||||
}
|
||||
*/
|
||||
if (waitForFPGAtoTouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDrive(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
strcpy(flashDriveName, "/tmp/SLS_mtd3");
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logDEBUG1, ("Finding flash drive...\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 cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
strcpy(cmd, CMD_GET_FLASH);
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not get flash drive: %s)\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
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;
|
||||
}
|
||||
|
||||
memset(flashDriveName, 0, sizeof(flashDriveName));
|
||||
strcpy(flashDriveName, "/dev/");
|
||||
strcat(flashDriveName, pch);
|
||||
LOG(logINFO, ("\tFlash 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, ("\tFlash ready for writing\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int eraseFlash(char *mess) {
|
||||
LOG(logINFO, ("\tErasing Flash...\n"));
|
||||
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
char *format = "flash_eraseall %s";
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, format, flashDriveName) >=
|
||||
MAX_STR_LENGTH) {
|
||||
strcpy(mess,
|
||||
"Could not program fpga. Command to erase flash is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not erase flash: %s)\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tFlash erased\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess) {
|
||||
LOG(logDEBUG1, ("writing to flash\n"));
|
||||
|
||||
char *buffer = malloc(FLASH_BUFFER_MEMORY_SIZE);
|
||||
if (buffer == NULL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
strcpy(mess, "Could not program fpga. Memory allocation to write to "
|
||||
"flash failed.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWriting to Flash...\n"));
|
||||
|
||||
int oldProgress = 0;
|
||||
ssize_t totalBytes = 0;
|
||||
ssize_t bytes =
|
||||
fread((void *)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd);
|
||||
|
||||
while (bytes > 0) {
|
||||
|
||||
ssize_t bytesWritten =
|
||||
fwrite((void *)buffer, sizeof(char), bytes, flashfd);
|
||||
totalBytes += bytesWritten;
|
||||
|
||||
if (bytesWritten != bytes) {
|
||||
free(buffer);
|
||||
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;
|
||||
}
|
||||
|
||||
// print progress
|
||||
if (fsize > 0) {
|
||||
int progress = (int)(((double)(totalBytes) / fsize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
} else
|
||||
printf(".");
|
||||
|
||||
bytes = fread((void *)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE,
|
||||
srcfd);
|
||||
}
|
||||
if (fsize <= 0) {
|
||||
printf("\n");
|
||||
}
|
||||
free(buffer);
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
LOG(logINFO, ("\tWrote %ld bytes to flash\n", totalBytes));
|
||||
|
||||
if (totalBytes != fsize) {
|
||||
sprintf(mess,
|
||||
"Could not program fpga. Incorrect bytes written to flash %lu "
|
||||
"[expected: %lu]\n",
|
||||
totalBytes, fsize);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int waitForFPGAtoTouchFlash(char *mess) {
|
||||
// touch and program
|
||||
FPGATouchFlash();
|
||||
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logINFO, ("\tWaiting 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)) {
|
||||
snprintf(
|
||||
mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not read gpio status: %s)\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// convert to int
|
||||
if (sscanf(retvals, "%d\n", &result) != 1) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"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, ("\tFPGA has picked up the program from flash\n"));
|
||||
return OK;
|
||||
}
|
||||
574
slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c
Normal file
574
slsDetectorServers/slsDetectorServer/src/programViaBlackfin.c
Normal file
@@ -0,0 +1,574 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "programViaBlackfin.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
#include "sls/ansi.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
/* global variables */
|
||||
// clang-format off
|
||||
#define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s
|
||||
|
||||
#define CMD_GPIO7_DEFINE "echo 7 > /sys/class/gpio/export"
|
||||
#define CMD_GPIO9_DEFINE "echo 9 > /sys/class/gpio/export"
|
||||
#define CMD_GPIO3_DEFINE "echo 3 > /sys/class/gpio/export"
|
||||
|
||||
#define CMD_GPIO7_EXIST "/sys/class/gpio/gpio7"
|
||||
#define CMD_GPIO9_EXIST "/sys/class/gpio/gpio9"
|
||||
#define CMD_GPIO3_EXIST "/sys/class/gpio/gpio3"
|
||||
|
||||
#define CMD_GPIO9_DEFINE_OUT "echo out > /sys/class/gpio/gpio9/direction"
|
||||
#define CMD_GPIO3_DEFINE_OUT "echo out > /sys/class/gpio/gpio3/direction"
|
||||
#define CMD_GPIO7_DEFINE_IN "echo in > /sys/class/gpio/gpio7/direction"
|
||||
#define CMD_GPIO9_DEFINE_IN "echo in > /sys/class/gpio/gpio9/direction"
|
||||
#define CMD_GPIO3_DEFINE_IN "echo in > /sys/class/gpio/gpio3/direction"
|
||||
|
||||
#define CMD_GPIO9_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio9/value"
|
||||
#define CMD_GPIO3_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio3/value"
|
||||
#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value"
|
||||
|
||||
#define CMD_GET_FPGA_FLASH_DRIVE "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd"
|
||||
#define CMD_GET_KERNEL_FLASH_DRIVE "awk \'$4== \"\\\"linux\" {print $1}\' /proc/mtd"
|
||||
|
||||
#define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB
|
||||
// clang-format on
|
||||
|
||||
#define FLASH_DRIVE_NAME_SIZE 16
|
||||
|
||||
#ifdef VIRTUAL
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = "/tmp/SLS_mtd3";
|
||||
#else
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
|
||||
#endif
|
||||
|
||||
char messageType[SHORT_STR_LENGTH] = {0};
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
|
||||
int latestKernelVerified = -1;
|
||||
#define KERNEL_DATE_VRSN_3GPIO "Fri Oct 29 00:00:00 2021"
|
||||
|
||||
int defineGPIOpins(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
// only latest kernel can use gpio3 pins
|
||||
if (latestKernelVerified == -1) {
|
||||
if (FAIL == validateKernelVersion(KERNEL_DATE_VRSN_3GPIO)) {
|
||||
latestKernelVerified = 0;
|
||||
LOG(logWARNING,
|
||||
("Kernel too old to use gpio 3 pins. Update kernel to "
|
||||
"guarantee error-free fpga programming. \n\tNot the end "
|
||||
"of the world. Continuing with current kernel...\n"));
|
||||
} else {
|
||||
latestKernelVerified = 1;
|
||||
}
|
||||
}
|
||||
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
// define gpio7
|
||||
if (access(CMD_GPIO7_EXIST, F_OK) != 0) {
|
||||
if (executeCommand(CMD_GPIO7_DEFINE, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not define gpio7 pins for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio7: defined\n"));
|
||||
} else {
|
||||
LOG(logINFO, ("\tgpio7: already defined\n"));
|
||||
}
|
||||
|
||||
// define gpio7 direction
|
||||
if (executeCommand(CMD_GPIO7_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio7 as input for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio7: setting intput\n"));
|
||||
|
||||
// define gpio9
|
||||
if (access(CMD_GPIO9_EXIST, F_OK) != 0) {
|
||||
if (executeCommand(CMD_GPIO9_DEFINE, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not define gpio9 pins for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio9: defined\n"));
|
||||
} else {
|
||||
LOG(logINFO, ("\tgpio9: already defined\n"));
|
||||
}
|
||||
|
||||
// define gpio3 (not chip enable)
|
||||
if (latestKernelVerified == 1) {
|
||||
if (access(CMD_GPIO3_EXIST, F_OK) != 0) {
|
||||
if (executeCommand(CMD_GPIO3_DEFINE, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not define gpio3 pins for fpga (%s)\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio3: defined\n"));
|
||||
} else {
|
||||
LOG(logINFO, ("\tgpio3: already defined\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int FPGAdontTouchFlash(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
// define gpio9 as output
|
||||
if (executeCommand(CMD_GPIO9_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio9 as output for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio9: setting output\n"));
|
||||
|
||||
// define gpio3 as output
|
||||
if (latestKernelVerified == 1) {
|
||||
if (executeCommand(CMD_GPIO3_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio3 as output for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio3: setting output\n"));
|
||||
}
|
||||
|
||||
// tell FPGA to not: gpio9
|
||||
if (executeCommand(CMD_GPIO9_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
|
||||
FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio9 to not touch flash for fpga (%s)\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio9: fpga dont touch flash\n"));
|
||||
|
||||
// tell FPGA to not: gpio3
|
||||
if (latestKernelVerified == 1) {
|
||||
if (executeCommand(CMD_GPIO3_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
|
||||
FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio3 to not touch flash for fpga (%s)\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio3: fpga dont touch flash\n"));
|
||||
}
|
||||
// usleep(100*1000);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int FPGATouchFlash(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
// tell FPGA to touch flash to program itself
|
||||
if (executeCommand(CMD_GPIO9_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio9 as input for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio9: setting input\n"));
|
||||
|
||||
if (latestKernelVerified == 1) {
|
||||
if (executeCommand(CMD_GPIO3_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set gpio3 as input for fpga (%s)\n", retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tgpio3: setting input\n"));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int resetFPGA(char *mess) {
|
||||
LOG(logINFOBLUE, ("Reseting FPGA\n"));
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
if (FPGAdontTouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
if (FPGATouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int emptyTempFolder(char *mess) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "rm -fr %s",
|
||||
TEMP_PROG_FOLDER_NAME_ALL_FILES) >= MAX_STR_LENGTH) {
|
||||
sprintf(mess,
|
||||
"Could not update %s. Command to empty %s folder is too long\n",
|
||||
messageType, TEMP_PROG_FOLDER_NAME);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not empty %s folder: %s)\n",
|
||||
messageType, TEMP_PROG_FOLDER_NAME, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tEmptied temp folder(%s)\n", TEMP_PROG_FOLDER_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
|
||||
uint64_t fsize) {
|
||||
|
||||
if (emptyTempFolder(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// check available memory to copy program
|
||||
{
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
if (fsize >= info.freeram) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Not enough memory to copy "
|
||||
"program. [File size:%ldMB, free RAM: %ldMB]\n",
|
||||
functionType, (long int)(fsize / (1024 * 1024)),
|
||||
(long int)(info.freeram / (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// open file to copy program
|
||||
*fd = fopen(TEMP_PROG_FILE_NAME, "w");
|
||||
if (*fd == NULL) {
|
||||
sprintf(mess, "Could not %s. Unable to open %s in write mode\n",
|
||||
functionType, TEMP_PROG_FILE_NAME);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tGoing to copy program to %s\n", TEMP_PROG_FILE_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
char *functionType, char *clientChecksum,
|
||||
ssize_t fsize) {
|
||||
|
||||
memset(messageType, 0, sizeof(messageType));
|
||||
strcpy(messageType, functionType);
|
||||
|
||||
if (getDrive(mess, index) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
FILE *srcfd = NULL;
|
||||
if (openFileForFlash(mess, &flashfd, &srcfd) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (index == PROGRAM_FPGA) {
|
||||
if (FPGAdontTouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (eraseFlash(mess) == FAIL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (writeToFlash(mess, fsize, flashfd, srcfd) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (emptyTempFolder(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* remove condition when flash fpga fixed */
|
||||
if (index == PROGRAM_KERNEL) {
|
||||
if (verifyChecksumFromFlash(mess, messageType, clientChecksum,
|
||||
flashDriveName, fsize) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == PROGRAM_FPGA) {
|
||||
if (waitForFPGAtoTouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// kernel
|
||||
else {
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
if (executeCommand("sync", retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not sync)\n", messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDrive(char *mess, enum PROGRAM_INDEX index) {
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logDEBUG1, ("Finding flash drive...\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 cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
if (index == PROGRAM_FPGA) {
|
||||
strcpy(cmd, CMD_GET_FPGA_FLASH_DRIVE);
|
||||
} else {
|
||||
strcpy(cmd, CMD_GET_KERNEL_FLASH_DRIVE);
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not %s. (could not get flash drive: %s)\n", messageType,
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (strlen(retvals) == 0) {
|
||||
LOG(logERROR, ("Could not %s. Could not get mtd drive, script returned "
|
||||
"empty string\n",
|
||||
messageType));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
char *pch = strtok(retvals, ":");
|
||||
if (pch == NULL) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Could not get mtd drive to flash (strtok "
|
||||
"fail).\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
memset(flashDriveName, 0, sizeof(flashDriveName));
|
||||
sprintf(flashDriveName, "/dev/%s", pch);
|
||||
LOG(logINFO, ("\tFlash drive found: %s\n", flashDriveName));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int openFileForFlash(char *mess, FILE **flashfd, FILE **srcfd) {
|
||||
// open src file
|
||||
*srcfd = fopen(TEMP_PROG_FILE_NAME, "r");
|
||||
if (*srcfd == NULL) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to open temp program file %s in read "
|
||||
"mode\n",
|
||||
messageType, 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,
|
||||
"Could not %s. Unable to open flash drive %s in write "
|
||||
"mode\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tFlash ready for writing\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int eraseFlash(char *mess) {
|
||||
LOG(logINFO, ("\tErasing Flash...\n"));
|
||||
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "flash_eraseall %s", flashDriveName) >=
|
||||
MAX_STR_LENGTH) {
|
||||
sprintf(mess, "Could not %s. Command to erase flash is too long\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not erase flash: %s)\n",
|
||||
messageType, retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tFlash erased\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd) {
|
||||
LOG(logDEBUG1, ("writing to flash\n"));
|
||||
|
||||
char *buffer = malloc(FLASH_BUFFER_MEMORY_SIZE);
|
||||
if (buffer == NULL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
sprintf(mess,
|
||||
"Could not %s. Memory allocation to write to "
|
||||
"flash failed.\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWriting to Flash...\n"));
|
||||
|
||||
int oldProgress = 0;
|
||||
ssize_t totalBytes = 0;
|
||||
ssize_t bytes =
|
||||
fread((void *)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd);
|
||||
|
||||
while (bytes > 0) {
|
||||
|
||||
ssize_t bytesWritten =
|
||||
fwrite((void *)buffer, sizeof(char), bytes, flashfd);
|
||||
totalBytes += bytesWritten;
|
||||
|
||||
if (bytesWritten != bytes) {
|
||||
free(buffer);
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
sprintf(mess,
|
||||
"Could not %s. Could not write to flash (bytes "
|
||||
"written:%ld, expected: "
|
||||
"%ld, total written:%ld)\n",
|
||||
messageType, (long int)bytesWritten, (long int)bytes,
|
||||
(long int)totalBytes);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// print progress
|
||||
if (fsize > 0) {
|
||||
int progress = (int)(((double)(totalBytes) / fsize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
} else
|
||||
printf(".");
|
||||
|
||||
bytes = fread((void *)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE,
|
||||
srcfd);
|
||||
}
|
||||
if (fsize <= 0) {
|
||||
printf("\n");
|
||||
}
|
||||
free(buffer);
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
LOG(logINFO, ("\tWrote %ld bytes to flash\n", totalBytes));
|
||||
|
||||
if (totalBytes != fsize) {
|
||||
sprintf(mess,
|
||||
"Could not %s. Incorrect bytes written to flash %lu "
|
||||
"[expected: %lu]\n",
|
||||
messageType, totalBytes, fsize);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int waitForFPGAtoTouchFlash(char *mess) {
|
||||
// touch and program
|
||||
if (FPGATouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logINFO, ("\tWaiting 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)) {
|
||||
snprintf(
|
||||
mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not read gpio status: %s)\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// convert to int
|
||||
if (sscanf(retvals, "%d\n", &result) != 1) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"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, ("\tFPGA has picked up the program from flash\n"));
|
||||
return OK;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "programFpgaNios.h"
|
||||
#include "programViaNios.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
#include "sls/ansi.h"
|
||||
@@ -11,10 +11,19 @@
|
||||
|
||||
/* global variables */
|
||||
|
||||
#define CMD_GET_FLASH "awk \'$5== \"Application\" {print $1}\' /proc/mtd"
|
||||
|
||||
#define CMD_GET_FPGA_FLASH_DRIVE \
|
||||
"awk \'$5== \"Application\" {print $1}\' /proc/mtd"
|
||||
#define CMD_GET_KERNEL_FLASH_DRIVE \
|
||||
"awk \'$5== \"Linux\" && $9 != \"Backup\\\"\" {print $1}\' /proc/mtd"
|
||||
#define FLASH_DRIVE_NAME_SIZE 16
|
||||
|
||||
#ifdef VIRTUAL
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = "/tmp/SLS_mtd3";
|
||||
#else
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
|
||||
#endif
|
||||
|
||||
char messageType[SHORT_STR_LENGTH] = {0};
|
||||
#define MICROCONTROLLER_FILE "/dev/ttyAL0"
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
@@ -35,19 +44,19 @@ void rebootControllerAndFPGA() {
|
||||
system(command);
|
||||
}
|
||||
|
||||
int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
|
||||
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
|
||||
char *functionType, char *checksum, char *fpgasrc,
|
||||
uint64_t fsize) {
|
||||
|
||||
if (verifyChecksumFromBuffer(mess, checksum, fpgasrc, fsize) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
memset(messageType, 0, sizeof(messageType));
|
||||
strcpy(messageType, functionType);
|
||||
|
||||
if (getDrive(mess) == FAIL) {
|
||||
if (getDrive(mess, index) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
if (openFileForFlash(&flashfd, mess) == FAIL) {
|
||||
if (openFileForFlash(mess, &flashfd) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@@ -56,21 +65,33 @@ int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (writeToFlash(fsize, flashfd, fpgasrc, mess) == FAIL) {
|
||||
if (writeToFlash(mess, fsize, flashfd, fpgasrc) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
/* ignoring this until a consistent way to read from nios flash
|
||||
if (verifyChecksumFromFlash(mess, checksum, flashDriveName, fsize) ==
|
||||
FAIL) {
|
||||
|
||||
/* remove condition when flash fpga fixed */
|
||||
if (index == PROGRAM_KERNEL) {
|
||||
if (verifyChecksumFromFlash(mess, messageType, checksum, flashDriveName,
|
||||
fsize) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (index == PROGRAM_KERNEL) {
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
if (executeCommand("sync", retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not update %s. (could not sync)\n", messageType);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDrive(char *mess) {
|
||||
int getDrive(char *mess, enum PROGRAM_INDEX index) {
|
||||
#ifdef VIRTUAL
|
||||
strcpy(flashDriveName, "/tmp/SLS_mtd3");
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logDEBUG1, ("Finding flash drive...\n"));
|
||||
@@ -86,18 +107,33 @@ int getDrive(char *mess) {
|
||||
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
strcpy(cmd, CMD_GET_FLASH);
|
||||
|
||||
if (index == PROGRAM_FPGA) {
|
||||
strcpy(cmd, CMD_GET_FPGA_FLASH_DRIVE);
|
||||
} else {
|
||||
strcpy(cmd, CMD_GET_KERNEL_FLASH_DRIVE);
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not get flash drive: %s)\n",
|
||||
"Could not %s. (could not get flash drive: %s)\n", messageType,
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (strlen(retvals) == 0) {
|
||||
LOG(logERROR, ("Could not %s. Could not get mtd drive, script returned "
|
||||
"empty string\n",
|
||||
messageType));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
char *pch = strtok(retvals, ":");
|
||||
if (pch == NULL) {
|
||||
strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n");
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Could not get mtd drive to flash (strtok fail).\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -109,11 +145,12 @@ int getDrive(char *mess) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int openFileForFlash(FILE **flashfd, char *mess) {
|
||||
int openFileForFlash(char *mess, FILE **flashfd) {
|
||||
*flashfd = fopen(flashDriveName, "w");
|
||||
if (*flashfd == NULL) {
|
||||
sprintf(mess, "Unable to open flash drive %s in write mode\n",
|
||||
flashDriveName);
|
||||
sprintf(mess,
|
||||
"Could not %s. Unable to open flash drive %s in write mode\n",
|
||||
messageType, flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@@ -130,17 +167,16 @@ int eraseFlash(char *mess) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
|
||||
char *format = "flash_erase %s 0 0";
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, format, flashDriveName) >=
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "flash_erase %s 0 0", flashDriveName) >=
|
||||
MAX_STR_LENGTH) {
|
||||
strcpy(mess,
|
||||
"Could not program fpga. Command to erase flash is too long\n");
|
||||
sprintf(mess, "Could not %s. Command to erase flash is too long\n",
|
||||
messageType);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not program fpga. (could not erase flash: %s)\n",
|
||||
"Could not %s. (could not erase flash: %s)\n", messageType,
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
return FAIL;
|
||||
@@ -150,19 +186,20 @@ int eraseFlash(char *mess) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess) {
|
||||
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, char *buffer) {
|
||||
LOG(logINFO, ("\tWriting to Flash...\n"));
|
||||
|
||||
ssize_t bytesWritten = fwrite((void *)buffer, sizeof(char), fsize, flashfd);
|
||||
if (bytesWritten != fsize) {
|
||||
fclose(flashfd);
|
||||
sprintf(mess,
|
||||
"Could not program fpga. Incorrect bytes written to flash %lu "
|
||||
"Could not %s. Incorrect bytes written to flash %lu "
|
||||
"[expected: %lu]\n",
|
||||
(long int)bytesWritten, (long int)fsize);
|
||||
messageType, (long int)bytesWritten, (long int)fsize);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWritten to Flash\n"));
|
||||
fclose(flashfd);
|
||||
LOG(logINFO, ("\tWrote %ld bytes to flash\n", bytesWritten));
|
||||
return OK;
|
||||
}
|
||||
@@ -92,14 +92,13 @@ void init_detector() {
|
||||
#ifdef EIGERD
|
||||
udpDetails[0].dstport2 = DEFAULT_UDP_DST_PORTNO + 1;
|
||||
#endif
|
||||
|
||||
lockStatus = 0;
|
||||
if (isControlServer) {
|
||||
basictests();
|
||||
initControlServer();
|
||||
} else
|
||||
} else {
|
||||
initStopServer();
|
||||
strcpy(mess, "dummy message");
|
||||
lockStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int decode_function(int file_des) {
|
||||
@@ -415,6 +414,8 @@ void function_table() {
|
||||
flist[F_GET_READOUT_SPEED] = &get_readout_speed;
|
||||
flist[F_SET_READOUT_SPEED] = &set_readout_speed;
|
||||
flist[F_GET_KERNEL_VERSION] = &get_kernel_version;
|
||||
flist[F_UPDATE_KERNEL] = &update_kernel;
|
||||
flist[F_UPDATE_DETECTOR_SERVER] = &update_detector_server;
|
||||
|
||||
// check
|
||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||
@@ -472,7 +473,7 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
|
||||
if (strlen(result)) {
|
||||
if (success) {
|
||||
success = FAIL;
|
||||
LOG(logERROR, ("%s\n", result));
|
||||
LOG(logERROR, ("Executing cmd[%s]:%s\n", cmd, result));
|
||||
} else {
|
||||
LOG(level, ("Result:\n[%s]\n", result));
|
||||
}
|
||||
@@ -486,11 +487,6 @@ int M_nofunc(int file_des) {
|
||||
ret = FAIL;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
|
||||
// to receive any arguments
|
||||
int n = 1;
|
||||
while (n > 0)
|
||||
n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER);
|
||||
|
||||
sprintf(mess, "Unrecognized Function enum %d. Please do not proceed.\n",
|
||||
fnum);
|
||||
LOG(logERROR, (mess));
|
||||
@@ -1561,15 +1557,8 @@ int set_module(int file_des) {
|
||||
}
|
||||
}
|
||||
|
||||
// receive all arguments
|
||||
if (ret == FAIL) {
|
||||
int n = 1;
|
||||
while (n > 0)
|
||||
n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER);
|
||||
}
|
||||
|
||||
// only set
|
||||
else if (Server_VerifyLock() == OK) {
|
||||
if (ret == OK && Server_VerifyLock() == OK) {
|
||||
// check index
|
||||
|
||||
// setsettings
|
||||
@@ -3641,149 +3630,10 @@ int program_fpga(int file_des) {
|
||||
memset(mess, 0, sizeof(mess));
|
||||
|
||||
#if defined(EIGERD) || defined(GOTTHARDD)
|
||||
// to receive any arguments
|
||||
int n = 1;
|
||||
while (n > 0)
|
||||
n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER);
|
||||
functionNotImplemented();
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
|
||||
LOG(logINFOBLUE, ("Programming FPGA...\n"));
|
||||
|
||||
// filesize
|
||||
uint64_t filesize = 0;
|
||||
if (receiveData(file_des, &filesize, sizeof(filesize), INT64) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Program size is: %lld\n", (long long int)filesize));
|
||||
|
||||
// checksum
|
||||
char checksum[MAX_STR_LENGTH];
|
||||
memset(checksum, 0, MAX_STR_LENGTH);
|
||||
if (receiveData(file_des, checksum, MAX_STR_LENGTH, OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("checksum is: %s\n\n", checksum));
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
if (filesize > NIOS_MAX_APP_IMAGE_SIZE) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not start programming FPGA. File size 0x%llx "
|
||||
"exceeds max size 0x%llx. Forgot Compression?\n",
|
||||
(long long unsigned int)filesize,
|
||||
(long long unsigned int)NIOS_MAX_APP_IMAGE_SIZE);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
|
||||
// receive program
|
||||
if (ret == OK) {
|
||||
char *fpgasrc = malloc(filesize);
|
||||
if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0) {
|
||||
free(fpgasrc);
|
||||
return printSocketReadError();
|
||||
}
|
||||
ret = eraseAndWriteToFlash(mess, checksum, fpgasrc, filesize);
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
free(fpgasrc);
|
||||
}
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#else // jungfrau, ctb, moench
|
||||
|
||||
// open file and allocate memory for part program
|
||||
FILE *fd = NULL;
|
||||
ret = preparetoCopyFPGAProgram(&fd, filesize, mess);
|
||||
char *src = NULL;
|
||||
if (ret == OK) {
|
||||
src = malloc(MAX_FPGAPROGRAMSIZE);
|
||||
if (src == NULL) {
|
||||
fclose(fd);
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
sprintf(mess,
|
||||
"Could not allocate memory to get fpga program. Free "
|
||||
"space: %d MB\n",
|
||||
(int)(info.freeram / (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL1!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// copying program part by part
|
||||
uint64_t totalsize = filesize;
|
||||
while (ret == OK && filesize) {
|
||||
uint64_t unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) // less than 2mb
|
||||
unitprogramsize = filesize;
|
||||
LOG(logDEBUG1, ("unit size to receive is:%lld [filesize:%lld]\n",
|
||||
(long long unsigned int)unitprogramsize,
|
||||
(long long unsigned int)filesize));
|
||||
|
||||
// receive part of program
|
||||
if (receiveData(file_des, src, unitprogramsize, OTHER) < 0) {
|
||||
printSocketReadError();
|
||||
break;
|
||||
}
|
||||
|
||||
if (unitprogramsize - filesize == 0) {
|
||||
// src[unitprogramsize] = '\0';
|
||||
filesize -= unitprogramsize;
|
||||
// unitprogramsize++;
|
||||
} else
|
||||
filesize -= unitprogramsize;
|
||||
|
||||
// copy program
|
||||
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;
|
||||
}
|
||||
// print progress
|
||||
LOG(logINFO,
|
||||
("\t%d%%\r",
|
||||
(int)(((double)(totalsize - filesize) / totalsize) * 100)));
|
||||
fflush(stdout);
|
||||
}
|
||||
free(src);
|
||||
fclose(fd);
|
||||
|
||||
// checksum of copied program
|
||||
if (ret == OK) {
|
||||
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(totalsize, checksum, mess);
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#endif // end of Blackfin programming
|
||||
LOG(logINFOGREEN, ("Programming FPGA completed successfully\n"));
|
||||
}
|
||||
receive_program(file_des, PROGRAM_FPGA);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -3801,10 +3651,26 @@ int reset_fpga(int file_des) {
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if (isControlServer) {
|
||||
basictests(); // mapping of control server at least
|
||||
char *message = NULL;
|
||||
if (getInitResult(&message) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, message);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
initControlServer();
|
||||
} else
|
||||
}
|
||||
} else {
|
||||
initStopServer(); // remapping of stop server
|
||||
}
|
||||
if (ret == OK) {
|
||||
char *message = NULL;
|
||||
if (getInitResult(&message) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, message);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
@@ -4228,9 +4094,8 @@ int copy_detector_server(int file_des) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
|
||||
// tftp server
|
||||
char *format = "tftp %s -r %s -g";
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, format, hostname, sname) >=
|
||||
MAX_STR_LENGTH) {
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname,
|
||||
sname) >= MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not copy detector server. Command to copy "
|
||||
"server too long\n");
|
||||
@@ -4244,95 +4109,8 @@ int copy_detector_server(int file_des) {
|
||||
LOG(logINFO, ("\tServer copied\n"));
|
||||
}
|
||||
|
||||
// give permissions
|
||||
if (ret == OK) {
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "chmod 777 %s", sname) >=
|
||||
MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not copy detector server. Command to give "
|
||||
"permissions to server is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (permissions). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tPermissions modified\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// symbolic link
|
||||
if (ret == OK) {
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, "ln -sf %s %s", sname,
|
||||
LINKED_SERVER_NAME) >= MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not copy detector server. Command to "
|
||||
"create symbolic link too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (symbolic link). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tSymbolic link created\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// blackfin boards (respawn) (only kept for backwards compatibility)
|
||||
#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || \
|
||||
defined(GOTTHARDD)
|
||||
// delete every line with DetectorServer in /etc/inittab
|
||||
if (ret == OK) {
|
||||
strcpy(cmd, "sed -i '/DetectorServer/d' /etc/inittab");
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(
|
||||
mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (del respawning). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tinittab: DetectoServer line deleted\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// add new link name to /etc/inittab
|
||||
if (ret == OK) {
|
||||
format = "echo 'ttyS0::respawn:/./%s' >> /etc/inittab";
|
||||
if (snprintf(cmd, MAX_STR_LENGTH, format, LINKED_SERVER_NAME) >=
|
||||
MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not copy detector server. Command "
|
||||
"to add new server for spawning is too long\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (respawning). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tinittab: updated for respawning\n"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// sync
|
||||
if (ret == OK) {
|
||||
strcpy(cmd, "sync");
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
ret = FAIL;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not copy detector server (sync). %s\n",
|
||||
retvals);
|
||||
// LOG(logERROR, (mess)); already printed in executecommand
|
||||
} else {
|
||||
LOG(logINFO, ("\tsync\n"));
|
||||
}
|
||||
ret = setupDetectorServer(mess, sname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -9426,11 +9204,302 @@ int get_kernel_version(int file_des) {
|
||||
// get only
|
||||
ret = getKernelVersion(retvals);
|
||||
if (ret == FAIL) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not get kernel version. %s\n", retvals);
|
||||
if (snprintf(mess, MAX_STR_LENGTH, "Could not get kernel version. %s\n",
|
||||
retvals) >= MAX_STR_LENGTH) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not get kernel version. Reason too long to copy\n");
|
||||
}
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
LOG(logDEBUG1, ("kernel version: [%s]\n", retvals));
|
||||
}
|
||||
return Server_SendResult(file_des, OTHER, retvals, sizeof(retvals));
|
||||
}
|
||||
|
||||
int update_kernel(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
#ifdef EIGERD
|
||||
functionNotImplemented();
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
#else
|
||||
receive_program(file_des, PROGRAM_KERNEL);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int update_detector_server(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
return receive_program(file_des, PROGRAM_SERVER);
|
||||
}
|
||||
|
||||
int receive_program(int file_des, enum PROGRAM_INDEX index) {
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
char functionType[SHORT_STR_LENGTH] = {0};
|
||||
switch (index) {
|
||||
case PROGRAM_FPGA:
|
||||
strcpy(functionType, "Update Firmware");
|
||||
break;
|
||||
case PROGRAM_KERNEL:
|
||||
strcpy(functionType, "Update Kernel");
|
||||
break;
|
||||
case PROGRAM_SERVER:
|
||||
strcpy(functionType, "Update Server");
|
||||
break;
|
||||
}
|
||||
LOG(logINFOBLUE, ("%s ...\n", functionType));
|
||||
|
||||
// filesize
|
||||
uint64_t filesize = 0;
|
||||
if (receiveData(file_des, &filesize, sizeof(filesize), INT64) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("\tProgram size: %lld\n", (long long int)filesize));
|
||||
|
||||
// client checksum
|
||||
char checksum[MAX_STR_LENGTH] = {0};
|
||||
if (receiveData(file_des, checksum, MAX_STR_LENGTH, OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("\tChecksum: %s\n", checksum));
|
||||
|
||||
// server name
|
||||
char serverName[MAX_STR_LENGTH] = {0};
|
||||
if (index == PROGRAM_SERVER) {
|
||||
if (receiveData(file_des, serverName, MAX_STR_LENGTH, OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logINFO, ("\tServer Name: %s\n", serverName));
|
||||
}
|
||||
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D) || defined(EIGERD)
|
||||
receive_program_default(file_des, index, functionType, filesize,
|
||||
checksum, serverName);
|
||||
#else
|
||||
receive_program_via_blackfin(file_des, index, functionType, filesize,
|
||||
checksum, serverName);
|
||||
#endif
|
||||
|
||||
if (ret == OK) {
|
||||
LOG(logINFOGREEN, ("%s completed successfully\n", functionType));
|
||||
} else {
|
||||
LOG(logERROR, ("%s FAIL!\n", functionType));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName) {
|
||||
|
||||
#if !defined(JUNGFRAUD) && !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && \
|
||||
!defined(GOTTHARDD)
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not %s. program via blackfin not implmented for this "
|
||||
"detector.\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess));
|
||||
#else
|
||||
// open file and allocate memory for part program
|
||||
FILE *fd = NULL;
|
||||
ret = preparetoCopyProgram(mess, functionType, &fd, filesize);
|
||||
char *src = NULL;
|
||||
if (ret == OK) {
|
||||
src = malloc(MAX_BLACKFIN_PROGRAM_SIZE);
|
||||
if (src == NULL) {
|
||||
fclose(fd);
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
sprintf(mess,
|
||||
"Could not %s. Memory allocation failure. Free "
|
||||
"space: %d MB\n",
|
||||
functionType, (int)(info.freeram / (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// copying program part by part
|
||||
uint64_t totalsize = filesize;
|
||||
while (ret == OK && filesize) {
|
||||
uint64_t unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE;
|
||||
if (unitprogramsize > filesize)
|
||||
unitprogramsize = filesize;
|
||||
LOG(logDEBUG1, ("unit size to receive is:%lld [filesize:%lld]\n",
|
||||
(long long unsigned int)unitprogramsize,
|
||||
(long long unsigned int)filesize));
|
||||
|
||||
// receive part of program
|
||||
if (receiveData(file_des, src, unitprogramsize, OTHER) < 0) {
|
||||
printSocketReadError();
|
||||
break;
|
||||
}
|
||||
filesize -= unitprogramsize;
|
||||
|
||||
// copy program
|
||||
if (fwrite((void *)src, sizeof(char), unitprogramsize, fd) !=
|
||||
unitprogramsize) {
|
||||
ret = FAIL;
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not %s. Could not copy program to /var/tmp (size:%ld)\n",
|
||||
functionType, (long int)unitprogramsize);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
break;
|
||||
}
|
||||
// print progress
|
||||
LOG(logINFO,
|
||||
("\t%d%%\r",
|
||||
(int)(((double)(totalsize - filesize) / totalsize) * 100)));
|
||||
fflush(stdout);
|
||||
}
|
||||
free(src);
|
||||
fclose(fd);
|
||||
|
||||
// checksum of copied program
|
||||
if (ret == OK) {
|
||||
ret = verifyChecksumFromFile(mess, functionType, checksum,
|
||||
TEMP_PROG_FILE_NAME);
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// appropriate functions
|
||||
switch (index) {
|
||||
case PROGRAM_FPGA:
|
||||
case PROGRAM_KERNEL:
|
||||
ret = eraseAndWriteToFlash(mess, index, functionType, checksum,
|
||||
totalsize);
|
||||
break;
|
||||
case PROGRAM_SERVER:
|
||||
ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME,
|
||||
"update detector server");
|
||||
if (ret == OK) {
|
||||
ret = setupDetectorServer(mess, serverName);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
modeNotImplemented("Program index", (int)index);
|
||||
break;
|
||||
}
|
||||
|
||||
// erase and copy to flash
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void receive_program_default(int file_des, enum PROGRAM_INDEX index,
|
||||
char *functionType, uint64_t filesize,
|
||||
char *checksum, char *serverName) {
|
||||
#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) && !defined(EIGERD)
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not %s. program via blackfin not implmented for this "
|
||||
"detector.\n",
|
||||
functionType);
|
||||
LOG(logERROR, (mess))
|
||||
#else
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
|
||||
// validate file size
|
||||
if (filesize > NIOS_MAX_APP_IMAGE_SIZE) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not %s. File size 0x%llx "
|
||||
"exceeds max size 0x%llx. Forgot Compression?\n",
|
||||
functionType, (long long unsigned int)filesize,
|
||||
(long long unsigned int)NIOS_MAX_APP_IMAGE_SIZE);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
|
||||
// memory allocation
|
||||
char *src = NULL;
|
||||
if (ret == OK) {
|
||||
src = malloc(filesize);
|
||||
if (src == NULL) {
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
sprintf(mess,
|
||||
"Could not %s. Memory allocation failure. Free "
|
||||
"space: %d MB\n",
|
||||
functionType, (int)(info.freeram / (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// receive program
|
||||
if (receiveData(file_des, src, filesize, OTHER) < 0) {
|
||||
free(src);
|
||||
ret = printSocketReadError();
|
||||
return;
|
||||
}
|
||||
|
||||
// checksum of copied program
|
||||
if (ret == OK) {
|
||||
ret = verifyChecksumFromBuffer(mess, functionType, checksum, src,
|
||||
filesize);
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// appropriate functions
|
||||
switch (index) {
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
|
||||
case PROGRAM_FPGA:
|
||||
case PROGRAM_KERNEL:
|
||||
ret = eraseAndWriteToFlash(mess, index, functionType, checksum, src,
|
||||
filesize);
|
||||
break;
|
||||
#endif
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D) || defined(EIGERD)
|
||||
case PROGRAM_SERVER:
|
||||
ret = writeBinaryFile(mess, TEMP_PROG_FILE_NAME, src, filesize,
|
||||
"update detector server");
|
||||
// extra step to write to temp and move to real file as
|
||||
// fopen will give text busy if opening same name as process name
|
||||
char dest[MAX_STR_LENGTH] = {0};
|
||||
sprintf(dest, "%s%s",
|
||||
(myDetectorType == EIGER ? "/home/root/executables/" : ""),
|
||||
serverName);
|
||||
|
||||
if (ret == OK) {
|
||||
ret = moveBinaryFile(mess, dest, TEMP_PROG_FILE_NAME,
|
||||
"update detector server");
|
||||
}
|
||||
if (ret == OK) {
|
||||
ret = verifyChecksumFromFile(mess, functionType, checksum, dest);
|
||||
}
|
||||
if (ret == OK) {
|
||||
ret = setupDetectorServer(mess, dest);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
modeNotImplemented("Program index", (int)index);
|
||||
break;
|
||||
}
|
||||
// send result
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
|
||||
// free resources
|
||||
free(src);
|
||||
#endif
|
||||
}
|
||||
@@ -1733,7 +1733,8 @@ class Detector {
|
||||
/** [Jungfrau][CTB][Moench] Advanced user Function! */
|
||||
void resetFPGA(Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
|
||||
/** [[deprecated ("Replaced by updateDetectorServer, which does not require tftp")]]
|
||||
* [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
|
||||
* Advanced user Function! \n
|
||||
* Copy detector server fname from tftp folder of hostname to detector. Also
|
||||
* creates a symbolic link to a shorter name (without vx.x.x). Then the
|
||||
@@ -1744,11 +1745,26 @@ class Detector {
|
||||
void copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname, Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Eiger][Ctb][Moench][Mythen3][Gotthard2] Copies detector
|
||||
* server via TCP (without tftp).\nMakes a symbolic link with a shorter
|
||||
* name (without vx.x.x).\nThen, detector controller reboots (except
|
||||
* Eiger).\n[Jungfrau][Ctb][Moench]Also changes respawn server to the
|
||||
* link, which is effective after a reboot.
|
||||
*/
|
||||
void updateDetectorServer(const std::string &fname, Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Ctb][Moench][Mythen3][Gotthard2] \n
|
||||
* Advanced Command!! You could damage the detector. Please use with
|
||||
* caution.\nUpdates the kernel image. Then, detector controller reboots
|
||||
* with new kernel
|
||||
*/
|
||||
void updateKernel(const std::string &fname, Positions pos = {});
|
||||
|
||||
/** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] Advanced user
|
||||
* Function! */
|
||||
void rebootController(Positions pos = {});
|
||||
|
||||
/**
|
||||
/** [[deprecated ("Replaced by overloaded updateDetectorServer, which does not require tftp and has one less argument")]]
|
||||
* Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the
|
||||
* firmware, detector server, make a soft link and then reboots detector
|
||||
* controller. \n [Mythen3][Gotthard2] Will require a script to start up the
|
||||
@@ -1760,6 +1776,16 @@ class Detector {
|
||||
const std::string &hostname,
|
||||
const std::string &fname, Positions pos = {});
|
||||
|
||||
/**
|
||||
* Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the
|
||||
* firmware, detector server, make a soft link and then reboots detector
|
||||
* controller. \n [Mythen3][Gotthard2] Will require a script to start up the
|
||||
* shorter named server link at start up \n sname is full path name of detector
|
||||
* server \n fname is programming file name with full path to it
|
||||
*/
|
||||
void updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &fname, Positions pos = {});
|
||||
|
||||
/** Advanced user Function! \n
|
||||
* Goes to stop server. Hence, can be called while calling blocking
|
||||
* acquire(). \n [Eiger] Address is +0x100 for only left, +0x200 for only
|
||||
|
||||
@@ -285,12 +285,14 @@ std::string CmdProxy::Versions(int action) {
|
||||
os << "\nFirmware Version: " << OutStringHex(t);
|
||||
}
|
||||
os << "\nDetector Server Version: "
|
||||
<< OutStringHex(det->getDetectorServerVersion(std::vector<int>{det_id}));
|
||||
<< OutStringHex(
|
||||
det->getDetectorServerVersion(std::vector<int>{det_id}));
|
||||
os << "\nDetector Server Version: "
|
||||
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
|
||||
if (det->getUseReceiverFlag().squash(true)) {
|
||||
os << "\nReceiver Version: "
|
||||
<< OutStringHex(det->getReceiverVersion(std::vector<int>{det_id}));
|
||||
<< OutStringHex(
|
||||
det->getReceiverVersion(std::vector<int>{det_id}));
|
||||
}
|
||||
os << std::dec << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
@@ -1432,7 +1434,9 @@ std::string CmdProxy::UDPDestinationList(int action) {
|
||||
throw sls::RuntimeError("udp_dstlist must be at module level.");
|
||||
}
|
||||
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
|
||||
throw sls::RuntimeError(std::string("Invalid receiver index ") + std::to_string(rx_id) + std::string(" to set round robin entry."));
|
||||
throw sls::RuntimeError(std::string("Invalid receiver index ") +
|
||||
std::to_string(rx_id) +
|
||||
std::string(" to set round robin entry."));
|
||||
}
|
||||
auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
@@ -2849,11 +2853,13 @@ std::string CmdProxy::CopyDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
LOG(logWARNING) << "Deprecated! Replaced by updatedetectorserver that requires no tftp.\n";
|
||||
os << "[server_name (in tftp folder)] "
|
||||
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Copies detector server via tftp from pc. Ensure that "
|
||||
"Gotthard2] Copies detector server via TFTP from pc. Ensure that "
|
||||
"server is in the pc's tftp folder. Makes a symbolic link with a "
|
||||
"shorter name (without vx.x.x). Then, detector reboots (except "
|
||||
"shorter name (without vx.x.x). Then, detector controller "
|
||||
"reboots (except "
|
||||
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
||||
"to the link, which is effective after a reboot."
|
||||
<< '\n';
|
||||
@@ -2871,30 +2877,93 @@ std::string CmdProxy::CopyDetectorServer(int action) {
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
std::string CmdProxy::UpdateDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[server_name (in tftp folder)] [pc_host_name] [fname.pof (incl "
|
||||
"full path)]\n\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
|
||||
"firmware, detector server, creates the symbolic link and then "
|
||||
"reboots detector controller. \n\t[Mythen3][Gotthard2] will "
|
||||
"require a script to start up the shorter named server link at "
|
||||
"start up. \n\tsname is name of detector server binary found on "
|
||||
"tftp folder of host pc \n\thostname is name of pc to tftp from "
|
||||
"\n\tfname is programming file name"
|
||||
os << "[server_name with full "
|
||||
"path]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Copies detector server via TCP (without tftp). Makes "
|
||||
"a symbolic link with a shorter name (without vx.x.x). Then, "
|
||||
"detector controller reboots (except "
|
||||
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
|
||||
"to the link, which is effective after a reboot."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 3) {
|
||||
WrongNumberOfParameters(3);
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (args[2].find(".pof") == std::string::npos) {
|
||||
throw sls::RuntimeError("Programming file must be a pof file.");
|
||||
det->updateDetectorServer(args[0], std::vector<int>{det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::UpdateKernel(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "[kernel_name with full "
|
||||
"path]\n\t[Jungfrau][Ctb][Moench][Mythen3]["
|
||||
"Gotthard2] Advanced Command!! You could damage the detector. "
|
||||
"Please use"
|
||||
"with caution.\n\tUpdates the kernel image. Then, detector "
|
||||
"controller "
|
||||
"reboots with new kernel."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
det->updateKernel(args[0], std::vector<int>{det_id});
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
|
||||
std::ostringstream os;
|
||||
os << cmd << ' ';
|
||||
if (action == defs::HELP_ACTION) {
|
||||
os << "\n\tDeprecated!! Replaced without using tftp (as shown next)[server_name"
|
||||
" (in tftp folder)] [pc_host_name] [fname.pof (incl full path)]";
|
||||
os << "\n\t[server_name (incl fullpath)] [fname.pof (incl full path)] "
|
||||
"This does not use tftp."
|
||||
"\n\t\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
|
||||
"firmware, detector server, creates the symbolic link and then "
|
||||
"reboots detector controller. \n\t[Mythen3][Gotthard2] will "
|
||||
"require a script to start up the shorter named server link at "
|
||||
"start up. \n\t\tsname is full path name of detector server binary"
|
||||
"\n\t\tfname is full path of programming file"
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
throw sls::RuntimeError("Cannot get");
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.size() != 3 && args.size() != 2) {
|
||||
WrongNumberOfParameters(2);
|
||||
}
|
||||
|
||||
int fpos = args.size() - 1;
|
||||
if (args[fpos].find(".pof") == std::string::npos && args[fpos].find(".rbf") == std::string::npos) {
|
||||
throw sls::RuntimeError("Programming file must be a pof/rbf file.");
|
||||
}
|
||||
|
||||
if (args.size() == 3) {
|
||||
LOG(logWARNING) << "Deprecated! Recommend to use same command without tftp (no pc name) and using full path to the server binary";
|
||||
det->updateFirmwareAndServer(args[0], args[1], args[2],
|
||||
std::vector<int>{det_id});
|
||||
} else {
|
||||
det->updateFirmwareAndServer(args[0], args[1],
|
||||
std::vector<int>{det_id});
|
||||
}
|
||||
os << "successful\n";
|
||||
} else {
|
||||
throw sls::RuntimeError("Unknown action");
|
||||
|
||||
@@ -1059,6 +1059,8 @@ class CmdProxy {
|
||||
{"programfpga", &CmdProxy::ProgramFpga},
|
||||
{"resetfpga", &CmdProxy::resetfpga},
|
||||
{"copydetectorserver", &CmdProxy::CopyDetectorServer},
|
||||
{"updatedetectorserver", &CmdProxy::UpdateDetectorServer},
|
||||
{"updatekernel", &CmdProxy::UpdateKernel},
|
||||
{"rebootcontroller", &CmdProxy::rebootcontroller},
|
||||
{"update", &CmdProxy::UpdateFirmwareAndDetectorServer},
|
||||
{"reg", &CmdProxy::Register},
|
||||
@@ -1183,6 +1185,8 @@ class CmdProxy {
|
||||
/* Advanced */
|
||||
std::string ProgramFpga(int action);
|
||||
std::string CopyDetectorServer(int action);
|
||||
std::string UpdateDetectorServer(int action);
|
||||
std::string UpdateKernel(int action);
|
||||
std::string UpdateFirmwareAndDetectorServer(int action);
|
||||
std::string Register(int action);
|
||||
std::string AdcRegister(int action);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Module.h"
|
||||
#include "sls/Pattern.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/file_utils.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#include "sls/versionAPI.h"
|
||||
@@ -2133,6 +2134,7 @@ void Detector::setAdditionalJsonParameter(const std::string &key,
|
||||
// Advanced
|
||||
|
||||
void Detector::programFPGA(const std::string &fname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Firmware...";
|
||||
std::vector<char> buffer = pimpl->readProgrammingFile(fname);
|
||||
pimpl->Parallel(&Module::programFPGA, pos, buffer);
|
||||
rebootController(pos);
|
||||
@@ -2144,12 +2146,30 @@ void Detector::resetFPGA(Positions pos) {
|
||||
|
||||
void Detector::copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Detector Server (via tftp)...";
|
||||
pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname);
|
||||
if (getDetectorType().squash() != defs::EIGER) {
|
||||
rebootController(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void Detector::updateDetectorServer(const std::string &fname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Detector Server (no tftp)...";
|
||||
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
|
||||
std::string filename = sls::getFileNameFromFilePath(fname);
|
||||
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
|
||||
if (getDetectorType().squash() != defs::EIGER) {
|
||||
rebootController(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void Detector::updateKernel(const std::string &fname, Positions pos) {
|
||||
LOG(logINFO) << "Updating Kernel...";
|
||||
std::vector<char> buffer = sls::readBinaryFile(fname, "Update Kernel");
|
||||
pimpl->Parallel(&Module::updateKernel, pos, buffer);
|
||||
rebootController(pos);
|
||||
}
|
||||
|
||||
void Detector::rebootController(Positions pos) {
|
||||
pimpl->Parallel(&Module::rebootController, pos);
|
||||
}
|
||||
@@ -2158,10 +2178,23 @@ void Detector::updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &hostname,
|
||||
const std::string &fname,
|
||||
Positions pos) {
|
||||
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);
|
||||
}
|
||||
|
||||
void Detector::updateFirmwareAndServer(const std::string &sname,
|
||||
const std::string &fname,
|
||||
Positions pos) {
|
||||
LOG(logINFO) << "Updating Firmware and Detector Server (no tftp)...";
|
||||
LOG(logINFO) << "Updating Detector Server (no tftp)...";
|
||||
std::vector<char> buffer = readBinaryFile(fname, "Update Detector Server");
|
||||
std::string filename = sls::getFileNameFromFilePath(sname);
|
||||
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
|
||||
programFPGA(fname, pos);
|
||||
}
|
||||
|
||||
Result<uint32_t> Detector::readRegister(uint32_t addr, Positions pos) const {
|
||||
return pimpl->Parallel(&Module::readRegister, pos, addr);
|
||||
}
|
||||
@@ -2240,7 +2273,7 @@ Result<sls::IpAddr> Detector::getLastClientIP(Positions pos) const {
|
||||
|
||||
Result<std::string> Detector::executeCommand(const std::string &value,
|
||||
Positions pos) {
|
||||
return pimpl->Parallel(&Module::execCommand, pos, value);
|
||||
return pimpl->Parallel(&Module::executeCommand, pos, value);
|
||||
}
|
||||
|
||||
Result<int64_t> Detector::getNumberOfFramesFromStart(Positions pos) const {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/file_utils.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/string_utils.h"
|
||||
|
||||
@@ -1261,8 +1262,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
throw RuntimeError("programfpga not implemented for this detector");
|
||||
}
|
||||
|
||||
LOG(logINFO)
|
||||
<< "Updating Firmware. This can take awhile. Please be patient...";
|
||||
LOG(logINFO) << "This can take awhile. Please be patient.";
|
||||
LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
|
||||
|
||||
// check if it exists
|
||||
@@ -1280,14 +1280,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
}
|
||||
|
||||
// get srcSize to print progress
|
||||
if (fseek(src, 0, SEEK_END) != 0) {
|
||||
throw RuntimeError("Program FPGA: Seek error in src file");
|
||||
}
|
||||
size_t srcSize = ftell(src);
|
||||
if (srcSize <= 0) {
|
||||
throw RuntimeError("Program FPGA: Could not get length of source file");
|
||||
}
|
||||
rewind(src);
|
||||
ssize_t srcSize = sls::getFileSize(src, "Program FPGA");
|
||||
|
||||
// create temp destination file
|
||||
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
|
||||
@@ -1359,36 +1352,12 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
if (close(dst) != 0) {
|
||||
throw RuntimeError("Program FPGA: Could not close destination file");
|
||||
}
|
||||
LOG(logINFOBLUE) << "File has been converted to " << destfname;
|
||||
LOG(logINFO) << "File has been converted to " << destfname;
|
||||
|
||||
// loading dst file to memory
|
||||
// FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r");
|
||||
FILE *fp = fopen(destfname, "r");
|
||||
if (fp == nullptr) {
|
||||
throw RuntimeError("Program FPGA: Could not open rawbin file");
|
||||
}
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
throw RuntimeError("Program FPGA: Seek error in rawbin file");
|
||||
}
|
||||
size_t 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) != 0) {
|
||||
throw RuntimeError(
|
||||
"Program FPGA: Could not close destination file after converting");
|
||||
}
|
||||
|
||||
// unlink(destfname); // delete temporary file
|
||||
LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
|
||||
LOG(logDEBUG1) << "Read file into memory";
|
||||
// load converted file to memory
|
||||
std::vector<char> buffer = readBinaryFile(destfname, "Program FPGA");
|
||||
// delete temporary
|
||||
unlink(destfname);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* Convert raw file
|
||||
* [Jungfrau][Ctb] from pof file
|
||||
* [Jungfrau][Ctb][Moench] from pof file
|
||||
* [Mythen3][Gotthard2] from rbf file
|
||||
* @param fname name of pof/rbf file
|
||||
* @returns binary of the program
|
||||
|
||||
@@ -836,7 +836,8 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
|
||||
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
|
||||
client.Send(F_GET_NUM_MISSING_PACKETS);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
throw ReceiverError("Receiver " + std::to_string(moduleIndex) +
|
||||
throw ReceiverError(
|
||||
"Receiver " + std::to_string(moduleIndex) +
|
||||
" returned error: " + client.readErrorMessage());
|
||||
} else {
|
||||
auto nports = client.Receive<int>();
|
||||
@@ -1172,7 +1173,8 @@ void Module::setReceiverHostname(const std::string &receiverIP) {
|
||||
LOG(logDEBUG1) << "Setting up Receiver hostname with " << receiverIP;
|
||||
|
||||
if (getRunStatus() == RUNNING) {
|
||||
throw RuntimeError("Cannot set receiver hostname. Acquisition already running. Stop it first.");
|
||||
throw RuntimeError("Cannot set receiver hostname. Acquisition already "
|
||||
"running. Stop it first.");
|
||||
}
|
||||
|
||||
if (receiverIP == "none") {
|
||||
@@ -2485,14 +2487,15 @@ void Module::programFPGA(std::vector<char> buffer) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
programFPGAviaBlackfin(buffer);
|
||||
sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware");
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
programFPGAviaNios(buffer);
|
||||
sendProgram(false, buffer, F_PROGRAM_FPGA, "Update Firmware");
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Program FPGA is not implemented for this detector");
|
||||
throw RuntimeError("Updating Firmware via the package is not "
|
||||
"implemented for this detector");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2503,7 +2506,8 @@ void Module::copyDetectorServer(const std::string &fname,
|
||||
char args[2][MAX_STR_LENGTH]{};
|
||||
sls::strcpy_safe(args[0], fname.c_str());
|
||||
sls::strcpy_safe(args[1], hostname.c_str());
|
||||
LOG(logINFO) << "Sending detector server " << args[0] << " from host "
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Sending detector server " << args[0] << " from host "
|
||||
<< args[1];
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_COPY_DET_SERVER);
|
||||
@@ -2516,12 +2520,51 @@ void Module::copyDetectorServer(const std::string &fname,
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): detector server copied";
|
||||
<< "): Detector server copied";
|
||||
}
|
||||
|
||||
void Module::updateDetectorServer(std::vector<char> buffer,
|
||||
const std::string &serverName) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
sendProgram(true, buffer, F_UPDATE_DETECTOR_SERVER,
|
||||
"Update Detector Server (no tftp)", serverName);
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
case EIGER:
|
||||
sendProgram(false, buffer, F_UPDATE_DETECTOR_SERVER,
|
||||
"Update Detector Server (no tftp)", serverName);
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Updating DetectorServer via the package is not implemented "
|
||||
"for this detector");
|
||||
}
|
||||
}
|
||||
|
||||
void Module::updateKernel(std::vector<char> buffer) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
sendProgram(true, buffer, F_UPDATE_KERNEL, "Update Kernel");
|
||||
break;
|
||||
case MYTHEN3:
|
||||
case GOTTHARD2:
|
||||
sendProgram(false, buffer, F_UPDATE_KERNEL, "Update Kernel");
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Updating Kernel via the package is not implemented "
|
||||
"for this detector");
|
||||
}
|
||||
}
|
||||
|
||||
void Module::rebootController() {
|
||||
sendToDetector(F_REBOOT_CONTROLLER);
|
||||
LOG(logINFO) << "Controller rebooted successfully!";
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Controller rebooted successfully!";
|
||||
}
|
||||
|
||||
uint32_t Module::readRegister(uint32_t addr) const {
|
||||
@@ -2599,11 +2642,25 @@ sls::IpAddr Module::getLastClientIP() const {
|
||||
return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP);
|
||||
}
|
||||
|
||||
std::string Module::execCommand(const std::string &cmd) {
|
||||
std::string Module::executeCommand(const std::string &cmd) {
|
||||
char arg[MAX_STR_LENGTH]{};
|
||||
char retval[MAX_STR_LENGTH]{};
|
||||
sls::strcpy_safe(arg, cmd.c_str());
|
||||
sendToDetector(F_EXEC_COMMAND, arg, retval);
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Sending command " << cmd;
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_EXEC_COMMAND);
|
||||
client.Send(arg);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
client.Receive(retval);
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): command executed";
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -3407,38 +3464,48 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
return myMod;
|
||||
}
|
||||
|
||||
void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
// send program from memory to detector
|
||||
LOG(logINFO) << "Sending programming binary (from pof) to module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
void Module::sendProgram(bool blackfin, std::vector<char> buffer,
|
||||
const int functionEnum,
|
||||
const std::string &functionType,
|
||||
const std::string serverName) {
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): Sending " << functionType;
|
||||
|
||||
// send fnum and filesize
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_PROGRAM_FPGA);
|
||||
client.Send(functionEnum);
|
||||
uint64_t filesize = buffer.size();
|
||||
client.Send(filesize);
|
||||
|
||||
// checksum
|
||||
// send checksum
|
||||
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||
char cChecksum[MAX_STR_LENGTH];
|
||||
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||
char cChecksum[MAX_STR_LENGTH] = {0};
|
||||
strcpy(cChecksum, checksum.c_str());
|
||||
client.Send(cChecksum);
|
||||
|
||||
// opening file fail
|
||||
// send server name
|
||||
if (functionEnum == F_UPDATE_DETECTOR_SERVER) {
|
||||
char sname[MAX_STR_LENGTH] = {0};
|
||||
strcpy(sname, serverName.c_str());
|
||||
client.Send(sname);
|
||||
}
|
||||
|
||||
// validate memory allocation etc in detector
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
|
||||
// sending program in parts of 2mb each
|
||||
// send program
|
||||
if (blackfin) {
|
||||
uint64_t unitprogramsize = 0;
|
||||
int currentPointer = 0;
|
||||
while (filesize > 0) {
|
||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) { // less than 2mb
|
||||
unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE;
|
||||
if (unitprogramsize > filesize) {
|
||||
unitprogramsize = filesize;
|
||||
}
|
||||
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
|
||||
@@ -3455,8 +3522,11 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
filesize -= unitprogramsize;
|
||||
currentPointer += unitprogramsize;
|
||||
}
|
||||
} else {
|
||||
client.Send(buffer);
|
||||
}
|
||||
|
||||
// checksum
|
||||
// tmp checksum verified in detector
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
@@ -3466,134 +3536,56 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
|
||||
<< shm()->hostname << ")";
|
||||
|
||||
// simulating erasing flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex
|
||||
<< " (" << 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<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
// simulating erasing and writing to
|
||||
if (blackfin) {
|
||||
if (functionEnum == F_PROGRAM_FPGA) {
|
||||
simulatingActivityinDetector("Erasing Flash",
|
||||
BLACKFIN_ERASE_FLASH_TIME);
|
||||
simulatingActivityinDetector("Writing to Flash",
|
||||
BLACKFIN_WRITE_TO_FLASH_TIME);
|
||||
}
|
||||
} else {
|
||||
if (functionEnum == F_PROGRAM_FPGA) {
|
||||
simulatingActivityinDetector("Erasing Flash",
|
||||
NIOS_ERASE_FLASH_TIME_FPGA);
|
||||
simulatingActivityinDetector("Writing to Flash",
|
||||
NIOS_WRITE_TO_FLASH_TIME_FPGA);
|
||||
} else if (functionEnum == F_UPDATE_KERNEL) {
|
||||
simulatingActivityinDetector("Erasing Flash",
|
||||
NIOS_ERASE_FLASH_TIME_KERNEL);
|
||||
simulatingActivityinDetector("Writing to Flash",
|
||||
NIOS_WRITE_TO_FLASH_TIME_KERNEL);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// simulating writing to flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Writing to Flash for module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
// writing takes 30 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 30;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf("%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// update verified
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
LOG(logINFO) << "FPGA programmed successfully";
|
||||
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
|
||||
<< "): " << functionType << " udpated successfully";
|
||||
}
|
||||
|
||||
void Module::programFPGAviaNios(std::vector<char> buffer) {
|
||||
LOG(logINFO) << "Sending programming binary (from rbf) to Module "
|
||||
void Module::simulatingActivityinDetector(const std::string &functionType,
|
||||
const int timeRequired) {
|
||||
LOG(logINFO) << "(Simulating) " << functionType << " for module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_PROGRAM_FPGA);
|
||||
uint64_t filesize = buffer.size();
|
||||
client.Send(filesize);
|
||||
|
||||
// checksum
|
||||
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||
char cChecksum[MAX_STR_LENGTH];
|
||||
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||
strcpy(cChecksum, checksum.c_str());
|
||||
client.Send(cChecksum);
|
||||
|
||||
// validate file size before sending program
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
client.Send(buffer);
|
||||
|
||||
// simulating erasing flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex
|
||||
<< " (" << shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
// erasing takes 10 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 10;
|
||||
const int ERASE_TIME = timeRequired;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf("%d%%\r",
|
||||
printf(
|
||||
"%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// simulating writing to flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Writing to Flash for module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
// writing takes 45 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 45;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf("%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
|
||||
100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw DetectorError(os.str());
|
||||
}
|
||||
LOG(logINFO) << "FPGA programmed successfully";
|
||||
}
|
||||
} // namespace sls
|
||||
|
||||
@@ -541,6 +541,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
void resetFPGA();
|
||||
void copyDetectorServer(const std::string &fname,
|
||||
const std::string &hostname);
|
||||
void updateDetectorServer(std::vector<char> buffer,
|
||||
const std::string &serverName);
|
||||
void updateKernel(std::vector<char> buffer);
|
||||
void rebootController();
|
||||
uint32_t readRegister(uint32_t addr) const;
|
||||
uint32_t writeRegister(uint32_t addr, uint32_t val);
|
||||
@@ -565,7 +568,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
bool getLockDetector() const;
|
||||
void setLockDetector(bool lock);
|
||||
sls::IpAddr getLastClientIP() const;
|
||||
std::string execCommand(const std::string &cmd);
|
||||
std::string executeCommand(const std::string &cmd);
|
||||
int64_t getNumberOfFramesFromStart() const;
|
||||
int64_t getActualTime() const;
|
||||
int64_t getMeasurementTime() const;
|
||||
@@ -746,11 +749,20 @@ class Module : public virtual slsDetectorDefs {
|
||||
std::string getTrimbitFilename(detectorSettings settings, int e_eV);
|
||||
sls_detector_module readSettingsFile(const std::string &fname,
|
||||
bool trimbits = true);
|
||||
void programFPGAviaBlackfin(std::vector<char> buffer);
|
||||
void programFPGAviaNios(std::vector<char> buffer);
|
||||
void sendProgram(bool blackfin, std::vector<char> buffer,
|
||||
const int functionEnum, const std::string &functionType,
|
||||
const std::string serverName = "");
|
||||
void simulatingActivityinDetector(const std::string &functionType,
|
||||
const int timeRequired);
|
||||
|
||||
const int moduleIndex;
|
||||
mutable sls::SharedMemory<sharedModule> shm{0, 0};
|
||||
static const int BLACKFIN_ERASE_FLASH_TIME = 65;
|
||||
static const int BLACKFIN_WRITE_TO_FLASH_TIME = 30;
|
||||
static const int NIOS_ERASE_FLASH_TIME_FPGA = 10;
|
||||
static const int NIOS_WRITE_TO_FLASH_TIME_FPGA = 45;
|
||||
static const int NIOS_ERASE_FLASH_TIME_KERNEL = 9;
|
||||
static const int NIOS_WRITE_TO_FLASH_TIME_KERNEL = 40;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -2708,6 +2708,25 @@ TEST_CASE("copydetectorserver", "[.cmd]") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("updatekernel", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::MOENCH || det_type == defs::MYTHEN3 ||
|
||||
det_type == defs::GOTTHARD2) {
|
||||
// TODO: send real server?
|
||||
// std::ostringstream oss;
|
||||
// proxy.Call("updatekernel",{"juImage_detector.lzma",
|
||||
// "pc13784"}, -1, PUT, oss);
|
||||
// REQUIRE(oss.str() == "updatekernel successful\n");
|
||||
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, GET));
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, GET));
|
||||
REQUIRE_THROWS(proxy.Call("updatekernel", {}, -1, PUT));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("rebootcontroller", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
|
||||
@@ -355,7 +355,7 @@ std::string Implementation::getFilePath() const { return filePath; }
|
||||
|
||||
void Implementation::setFilePath(const std::string &c) {
|
||||
if (!c.empty()) {
|
||||
mkdir_p(c); // throws if it can't create
|
||||
sls::mkdir_p(c); // throws if it can't create
|
||||
filePath = c;
|
||||
}
|
||||
LOG(logINFO) << "File path: " << filePath;
|
||||
|
||||
@@ -8,49 +8,46 @@
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
/** (used by multi and sls)
|
||||
* reads a short int raw data file
|
||||
* @param infile input file stream
|
||||
namespace sls {
|
||||
|
||||
|
||||
/**
|
||||
* @param data array of data values
|
||||
* @param nch number of channels
|
||||
* @param offset start channel value
|
||||
* @returns OK or FAIL if it could not read the file or data=NULL
|
||||
*/
|
||||
int readDataFile(std::ifstream &infile, short int *data, int nch,
|
||||
int offset = 0);
|
||||
|
||||
/** (used by multi and sls)
|
||||
* reads a short int rawdata file
|
||||
* @param fname name of the file to be read
|
||||
/**
|
||||
* @param data array of data value
|
||||
* @param nch number of channels
|
||||
* @returns OK or FAIL if it could not read the file or data=NULL
|
||||
*/
|
||||
int readDataFile(std::string fname, short int *data, int nch);
|
||||
|
||||
/** (used by multi and sls)
|
||||
* writes a short int raw data file
|
||||
* @param outfile output file stream
|
||||
|
||||
std::vector<char> readBinaryFile(const std::string &fname,
|
||||
const std::string &errorPrefix);
|
||||
|
||||
/**
|
||||
* @param nch number of channels
|
||||
* @param data array of data values
|
||||
* @param offset start channel number
|
||||
* @returns OK or FAIL if it could not write the file or data=NULL
|
||||
*/
|
||||
int writeDataFile(std::ofstream &outfile, int nch, short int *data,
|
||||
int offset = 0);
|
||||
|
||||
/** (used by multi and sls)
|
||||
* writes a short int raw data file
|
||||
* @param fname of the file to be written
|
||||
/**
|
||||
* @param nch number of channels
|
||||
* @param data array of data values
|
||||
* @returns OK or FAIL if it could not write the file or data=NULL
|
||||
*/
|
||||
int writeDataFile(std::string fname, int nch, short int *data);
|
||||
|
||||
// mkdir -p path implemented by recursive calls
|
||||
void mkdir_p(const std::string &path, std::string dir = "");
|
||||
|
||||
namespace sls {
|
||||
int getFileSize(std::ifstream &ifs);
|
||||
ssize_t getFileSize(FILE* fd, const std::string &prependErrorString);
|
||||
|
||||
std::string getFileNameFromFilePath(const std::string &fpath);
|
||||
}
|
||||
|
||||
@@ -55,9 +55,8 @@
|
||||
/** maximum trim en */
|
||||
#define MAX_TRIMEN 100
|
||||
|
||||
/** maximum unit size of program sent to detector */
|
||||
//#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024)
|
||||
#define MAX_FPGAPROGRAMSIZE (128 * 1024)
|
||||
/** maximum unit size of program sent to blackfin */
|
||||
#define MAX_BLACKFIN_PROGRAM_SIZE (128 * 1024)
|
||||
|
||||
#define GET_FLAG -1
|
||||
|
||||
|
||||
@@ -254,6 +254,8 @@ enum detFuncs {
|
||||
F_GET_READOUT_SPEED,
|
||||
F_SET_READOUT_SPEED,
|
||||
F_GET_KERNEL_VERSION,
|
||||
F_UPDATE_KERNEL,
|
||||
F_UPDATE_DETECTOR_SERVER,
|
||||
|
||||
NUM_DET_FUNCTIONS,
|
||||
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
||||
@@ -610,6 +612,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED";
|
||||
case F_SET_READOUT_SPEED: return "F_SET_READOUT_SPEED";
|
||||
case F_GET_KERNEL_VERSION: return "F_GET_KERNEL_VERSION";
|
||||
case F_UPDATE_DETECTOR_SERVER: return "F_UPDATE_DETECTOR_SERVER";
|
||||
|
||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
#define APILIB 0x211027
|
||||
#define APIRECEIVER 0x211020
|
||||
#define APIGUI 0x211021
|
||||
#define APICTB 0x211103
|
||||
#define APIGOTTHARD 0x211103
|
||||
#define APIGOTTHARD2 0x211103
|
||||
#define APIJUNGFRAU 0x211103
|
||||
#define APIMYTHEN3 0x211103
|
||||
#define APIMOENCH 0x211103
|
||||
#define APIEIGER 0x211103
|
||||
#define APICTB 0x211117
|
||||
#define APIGOTTHARD 0x211117
|
||||
#define APIGOTTHARD2 0x211117
|
||||
#define APIJUNGFRAU 0x211117
|
||||
#define APIMYTHEN3 0x211117
|
||||
#define APIMOENCH 0x211111
|
||||
#define APIEIGER 0x211117
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace sls {
|
||||
|
||||
int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) {
|
||||
int ichan, iline = 0;
|
||||
short int idata;
|
||||
@@ -53,6 +55,39 @@ int readDataFile(std::string fname, short int *data, int nch) {
|
||||
return iline;
|
||||
}
|
||||
|
||||
std::vector<char> readBinaryFile(const std::string &fname,
|
||||
const std::string &errorPrefix) {
|
||||
// check if it exists
|
||||
struct stat st;
|
||||
if (stat(fname.c_str(), &st) != 0) {
|
||||
throw sls::RuntimeError(errorPrefix +
|
||||
std::string(" (file does not exist)"));
|
||||
}
|
||||
|
||||
FILE *fp = fopen(fname.c_str(), "rb");
|
||||
if (fp == nullptr) {
|
||||
throw sls::RuntimeError(errorPrefix +
|
||||
std::string(" (Could not open file: ") + fname + std::string(")"));
|
||||
}
|
||||
|
||||
// get file size to print progress
|
||||
ssize_t filesize = sls::getFileSize(fp, errorPrefix);
|
||||
|
||||
std::vector<char> buffer(filesize, 0);
|
||||
if ((ssize_t)fread(buffer.data(), sizeof(char), filesize, fp) != filesize) {
|
||||
throw sls::RuntimeError(errorPrefix +
|
||||
std::string(" (Could not read file)"));
|
||||
}
|
||||
|
||||
if (fclose(fp) != 0) {
|
||||
throw sls::RuntimeError(errorPrefix +
|
||||
std::string(" (Could not close file)"));
|
||||
}
|
||||
|
||||
LOG(logDEBUG1) << "Read file into memory";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int writeDataFile(std::ofstream &outfile, int nch, short int *data,
|
||||
int offset) {
|
||||
if (data == nullptr)
|
||||
@@ -96,7 +131,6 @@ void mkdir_p(const std::string &path, std::string dir) {
|
||||
mkdir_p(path.substr(i + 1), dir);
|
||||
}
|
||||
|
||||
namespace sls {
|
||||
int getFileSize(std::ifstream &ifs) {
|
||||
auto current_pos = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::end);
|
||||
@@ -104,4 +138,27 @@ int getFileSize(std::ifstream &ifs) {
|
||||
ifs.seekg(current_pos);
|
||||
return file_size;
|
||||
}
|
||||
|
||||
std::string getFileNameFromFilePath(const std::string &fpath) {
|
||||
std::string fname(fpath);
|
||||
std::size_t slashPos = fpath.rfind('/');
|
||||
if (slashPos != std::string::npos) {
|
||||
fname = fpath.substr(slashPos + 1, fpath.size() - 1);
|
||||
}
|
||||
return fname;
|
||||
}
|
||||
|
||||
ssize_t getFileSize(FILE* fd, const std::string &prependErrorString) {
|
||||
if (fseek(fd, 0, SEEK_END) != 0) {
|
||||
throw RuntimeError(prependErrorString + std::string(" (Seek error in src file)"));
|
||||
}
|
||||
size_t fileSize = ftell(fd);
|
||||
if (fileSize <= 0) {
|
||||
throw RuntimeError(prependErrorString + std::string(" (Could not get length of source file)"));
|
||||
}
|
||||
rewind(fd);
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
|
||||
} // namespace sls
|
||||
|
||||
Reference in New Issue
Block a user