Simulator (#28)

* WIP

* wip

* wip

* removed loop

* sending 1 frame

* send multiple frames

* c11 for server

* WIP

* WIP

* Add CMake for the simulators. Requires some refactoring to make slsDetectorServer a proper library.

* Working cmake for jungfrau

* Working cmake for eiger

* WIP

* WIP

* Add preliminary working eiger simulator and breaks the jungfrau simulator

* virtual servers connected

* changes to make it work for rhel7 and install binaries in bin

* removed some unnecessary prints

* removed binaries and virtual makefiles
This commit is contained in:
Dhanya Thattil
2019-06-03 10:16:54 +02:00
committed by GitHub
parent 073d06f143
commit 894cc1c9e0
22 changed files with 378 additions and 158 deletions

View File

@ -1,10 +1,14 @@
cmake_minimum_required(VERSION 3.9) cmake_minimum_required(VERSION 3.9)
project(slsDetectorPackage) project(slsDetectorPackage)
set(PROJECT_VERSION 5.0.0) set(PROJECT_VERSION 5.0.0)
include(cmake/project_version.cmake)
include(CheckIPOSupported) include(CheckIPOSupported)
include(cmake/project_version.cmake)
# Include additional modules that are used unconditionally # Include additional modules that are used unconditionally
include(GNUInstallDirs) include(GNUInstallDirs)
@ -34,6 +38,7 @@ option (SLS_USE_HDF5 "HDF5 File format" OFF)
option (SLS_USE_TEXTCLIENT "Text Client" ON) option (SLS_USE_TEXTCLIENT "Text Client" ON)
option (SLS_USE_RECEIVER "Receiver" ON) option (SLS_USE_RECEIVER "Receiver" ON)
option (SLS_USE_GUI "GUI" OFF) option (SLS_USE_GUI "GUI" OFF)
option (SLS_USE_SIMULATOR "Simulator" OFF)
option (SLS_USE_TESTS "TESTS" OFF) option (SLS_USE_TESTS "TESTS" OFF)
option (SLS_USE_INTEGRATION_TESTS "Integration Tests" OFF) option (SLS_USE_INTEGRATION_TESTS "Integration Tests" OFF)
option(SLS_USE_SANITIZER "Sanitizers for debugging" OFF) option(SLS_USE_SANITIZER "Sanitizers for debugging" OFF)
@ -87,10 +92,12 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-Wno-misleading-indentation # mostly in rapidjson remove using clang format -Wno-misleading-indentation # mostly in rapidjson remove using clang format
-Wduplicated-cond -Wduplicated-cond
-Wnull-dereference ) -Wnull-dereference )
endif() endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
target_compile_options(slsProjectWarnings INTERFACE target_compile_options(slsProjectWarnings INTERFACE
-Wno-class-memaccess ) -Wno-class-memaccess )
endif() endif()
endif() endif()
@ -115,6 +122,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_RPATH "$ORIGIN") set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
find_package(Doxygen) find_package(Doxygen)
find_package(ZeroMQ 4 REQUIRED) find_package(ZeroMQ 4 REQUIRED)
@ -130,6 +139,7 @@ if (SLS_USE_TEXTCLIENT)
add_subdirectory(slsDetectorSoftware) add_subdirectory(slsDetectorSoftware)
endif (SLS_USE_TEXTCLIENT) endif (SLS_USE_TEXTCLIENT)
if (SLS_USE_RECEIVER) if (SLS_USE_RECEIVER)
if (SLS_USE_HDF5) if (SLS_USE_HDF5)
find_package(HDF5 1.10 COMPONENTS CXX REQUIRED) find_package(HDF5 1.10 COMPONENTS CXX REQUIRED)
@ -146,6 +156,10 @@ if (SLS_USE_GUI)
endif() endif()
endif (SLS_USE_GUI) endif (SLS_USE_GUI)
if (SLS_USE_SIMULATOR)
add_subdirectory(slsDetectorServers)
endif (SLS_USE_SIMULATOR)
if (SLS_USE_INTEGRATION_TESTS) if (SLS_USE_INTEGRATION_TESTS)
add_subdirectory(integrationTests) add_subdirectory(integrationTests)
endif (SLS_USE_INTEGRATION_TESTS) endif (SLS_USE_INTEGRATION_TESTS)
@ -160,9 +174,13 @@ configure_file( .clang-tidy
if (DOXYGEN_FOUND) if (DOXYGEN_FOUND)
# set input and output files
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/Doxyfile.in) set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen/Doxyfile.in)
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
# request to configure the file
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
message("Doxygen build started")
# note the option ALL which allows to build the docs together with the application # note the option ALL which allows to build the docs together with the application
add_custom_target( docs add_custom_target( docs

16
cmk.sh
View File

@ -8,6 +8,7 @@ RECEIVER=0
GUI=0 GUI=0
DEBUG=0 DEBUG=0
PYTHON=0 PYTHON=0
SIMULATOR=0
CLEAN=0 CLEAN=0
@ -16,7 +17,7 @@ CMAKE_PRE=""
CMAKE_POST="" CMAKE_POST=""
usage() { echo -e " usage() { echo -e "
Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [-h] [-d <HDF5 directory>] [-j] <Number of threads> Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [s] [-h] [-d <HDF5 directory>] [-j] <Number of threads>
-[no option]: only make -[no option]: only make
-c: Clean -c: Clean
-b: Builds/Rebuilds CMake files normal mode -b: Builds/Rebuilds CMake files normal mode
@ -26,6 +27,7 @@ Usage: $0 [-c] [-b] [-p] [e] [t] [r] [g] [-h] [-d <HDF5 directory>] [-j] <Number
-t: Build/Rebuilds only text client -t: Build/Rebuilds only text client
-r: Build/Rebuilds only receiver -r: Build/Rebuilds only receiver
-g: Build/Rebuilds only gui -g: Build/Rebuilds only gui
-s: Simulator
-j: Number of threads to compile through -j: Number of threads to compile through
-e: Debug mode -e: Debug mode
@ -63,7 +65,7 @@ For rebuilding only certain sections
" ; exit 1; } " ; exit 1; }
while getopts ":bpchd:j:trges:" opt ; do while getopts ":bpchd:j:trges" opt ; do
case $opt in case $opt in
b) b)
echo "Building of CMake files Required" echo "Building of CMake files Required"
@ -110,6 +112,10 @@ while getopts ":bpchd:j:trges:" opt ; do
echo "Compiling Options: Debug" echo "Compiling Options: Debug"
DEBUG=1 DEBUG=1
;; ;;
s)
echo "Compiling Options: Simulator"
SIMULATOR=1
;;
\?) \?)
echo "Invalid option: -$OPTARG" echo "Invalid option: -$OPTARG"
usage usage
@ -173,6 +179,12 @@ if [ $DEBUG -eq 1 ]; then
echo "Debug Option enabled" echo "Debug Option enabled"
fi fi
#Simulator
if [ $SIMULATOR -eq 1 ]; then
CMAKE_POST+=" -DCMAKE_BUILD_TYPE=Debug -DSLS_USE_SIMULATOR=ON "
echo "Simulator Option enabled"
fi
#hdf5 rebuild #hdf5 rebuild
if [ $HDF5 -eq 1 ]; then if [ $HDF5 -eq 1 ]; then

View File

@ -1,15 +1,15 @@
hostname bchip038+ hostname localhost
0:rx_udpport 50004 0:rx_udpport 50004
0:rx_udpip 10.1.1.100 0:rx_udpip 172.24.8.84
0:detectorip 10.1.1.10 0:detectorip 172.24.8.254
rx_hostname pcmoench01 rx_hostname localhost
powerchip 1 #powerchip 1
#extsig:0 trigger_in_rising_edge #extsig:0 trigger_in_rising_edge
#timing trigger #timing trigger
outdir /external_pool/jungfrau_data/softwaretest outdir /tmp/slsdetector

View File

@ -107,4 +107,4 @@ TEST_CASE("Set and read timers", "[.integration][.multi]") {
// MAX_TIMERS // MAX_TIMERS
d.freeSharedMemory(); d.freeSharedMemory();
} }

View File

@ -0,0 +1,2 @@
add_subdirectory(eigerDetectorServer)
add_subdirectory(jungfrauDetectorServer)

View File

@ -0,0 +1,57 @@
set(src
slsDetectorFunctionList.c
slsDetectorServer.c
slsDetectorServer_funcs.c
communication_funcs.c
)
add_executable(eigerDetectorServerMaster
${src}
)
target_include_directories(eigerDetectorServerMaster
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(eigerDetectorServerMaster
PUBLIC EIGERD PCCOMPILE STOP_SERVER
PUBLIC VIRTUAL DVIRTUAL_9M
PUBLIC VIRTUAL_MASTER
)
target_link_libraries(eigerDetectorServerMaster
PUBLIC pthread rt
)
set_target_properties(eigerDetectorServerMaster PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
install(TARGETS eigerDetectorServerMaster
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
add_executable(eigerDetectorServerSlave
${src}
)
target_include_directories(eigerDetectorServerSlave
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(eigerDetectorServerSlave
PUBLIC EIGERD PCCOMPILE STOP_SERVER
PUBLIC VIRTUAL DVIRTUAL_9M
)
target_link_libraries(eigerDetectorServerSlave
PUBLIC pthread rt
)
set_target_properties(eigerDetectorServerSlave PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
install(TARGETS eigerDetectorServerSlave
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@ -1,28 +0,0 @@
CC = gcc
CFLAGS += -Wall -DEIGERD -DPCCOMPILE -DSTOP_SERVER #-DVERBOSE
CFLAGS += -DVIRTUAL -DVIRTUAL_9M
MASTERFLAG += -DVIRTUAL_MASTER
LDLIBS += -lm -lstdc++ -pthread
DESTDIR ?= bin
SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c
all: clean master slave
master: $(SRC_CLNT)
mkdir -p $(DESTDIR)
$(CC) -o eigerDetectorServer_virtualMaster $(SRC_CLNT) $(CFLAGS) $(MASTERFLAG) $(LDLIBS)
mv eigerDetectorServer_virtualMaster $(DESTDIR)
slave: $(SRC_CLNT)
mkdir -p $(DESTDIR)
$(CC) -o eigerDetectorServer_virtualSlave $(SRC_CLNT) $(CFLAGS) $(LDLIBS)
mv eigerDetectorServer_virtualSlave $(DESTDIR)
clean:
rm -rf $(DESTDIR)/eigerDetectorServer_virtualMaster $(DESTDIR)/eigerDetectorServer_virtualSlave *.o

View File

@ -0,0 +1 @@
../slsDetectorServer/communication_funcs_UDP.h

View File

@ -11,6 +11,7 @@
#include <unistd.h> //to gethostname #include <unistd.h> //to gethostname
#include <string.h> #include <string.h>
#ifdef VIRTUAL #ifdef VIRTUAL
#include "communication_funcs_UDP.h"
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
#endif #endif
@ -182,11 +183,8 @@ void basictests() {
/* Ids */ /* Ids */
int64_t getDetectorId(enum idMode arg) { int64_t getDetectorId(enum idMode arg) {
#ifdef VIRTUAL
return 0;
#else
int64_t retval = -1;
int64_t retval = -1;
switch(arg) { switch(arg) {
case DETECTOR_SERIAL_NUMBER: case DETECTOR_SERIAL_NUMBER:
retval = getDetectorNumber();/** to be implemented with mac? */ retval = getDetectorNumber();/** to be implemented with mac? */
@ -203,7 +201,7 @@ int64_t getDetectorId(enum idMode arg) {
} }
return retval; return retval;
#endif
} }
u_int64_t getFirmwareVersion() { u_int64_t getFirmwareVersion() {
@ -1026,6 +1024,7 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
} }
#ifdef VIRTUAL #ifdef VIRTUAL
int dacval = 0;
if (!mV) { if (!mV) {
(detectorModules)->dacs[ind] = val; (detectorModules)->dacs[ind] = val;
} }
@ -1213,7 +1212,21 @@ enum externalCommunicationMode getTiming() {
/* configure mac */ /* configure mac */
int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2) { int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2) {
#ifndef VIRTUAL #ifdef VIRTUAL
char cDestIp[MAX_STR_LENGTH];
memset(cDestIp, 0, MAX_STR_LENGTH);
sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff);
FILE_LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d, port2:%d)\n", cDestIp, udpport, udpport2));
if (setUDPDestinationDetails(0, cDestIp, udpport) == FAIL) {
FILE_LOG(logERROR, ("could not set udp destination IP and port\n"));
return FAIL;
}
if (setUDPDestinationDetails(1, cDestIp, udpport2) == FAIL) {
FILE_LOG(logERROR, ("could not set udp destination IP and port2\n"));
return FAIL;
}
return OK;
#else
FILE_LOG(logINFO, ("Configuring MAC\n")); FILE_LOG(logINFO, ("Configuring MAC\n"));
int src_port = DEFAULT_UDP_SOURCE_PORT; int src_port = DEFAULT_UDP_SOURCE_PORT;
@ -1606,6 +1619,14 @@ int prepareAcquisition() {
int startStateMachine() { int startStateMachine() {
#ifdef VIRTUAL #ifdef VIRTUAL
// create udp socket
if(createUDPSocket(0) != OK) {
return FAIL;
}
if(createUDPSocket(1) != OK) {
return FAIL;
}
FILE_LOG(logINFOBLUE, ("starting state machine\n"));
eiger_virtual_status = 1; eiger_virtual_status = 1;
eiger_virtual_stop = 0; eiger_virtual_stop = 0;
if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) {
@ -1638,23 +1659,109 @@ int startStateMachine() {
FILE_LOG(logINFOGREEN, ("Acquisition started\n")); FILE_LOG(logINFOGREEN, ("Acquisition started\n"));
} }
/*while(getRunStatus() == IDLE) {FILE_LOG(logINFO, ("waiting for being not idle anymore\n"));}*/
return ret; return ret;
#endif #endif
} }
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
eiger_virtual_status = 1; int64_t periodns = eiger_virtual_period;
int wait_in_s = nimages_per_request * eiger_virtual_period; int numFrames = nimages_per_request;
FILE_LOG(logINFO, ("going to wait for %d s\n", wait_in_s)); int64_t exp_ns = eiger_virtual_exptime;
while(!eiger_virtual_stop && (wait_in_s >= 0)) {
usleep(1000 * 1000);
wait_in_s--;
}
FILE_LOG(logINFO, ("Virtual Timer Done***\n"));
int dr = eiger_dynamicrange;
double bytesPerPixel = (double)dr/8.00;
int tgEnable = send_to_ten_gig;
int datasize = (tgEnable ? 4096 : 1024);
int packetsize = datasize + sizeof(sls_detector_header);
int numPacketsPerFrame = (tgEnable ? 4 : 16) * dr;
int npixelsx = 256 * 2 * bytesPerPixel;
int databytes = 256 * 256 * 2 * bytesPerPixel;
FILE_LOG(logINFO, (" dr:%f\n bytesperpixel:%d\n tgenable:%d\n datasize:%d\n packetsize:%d\n numpackes:5d\n npixelsx:%d\n databytes:%d\n",
dr, bytesPerPixel, tgEnable, datasize, packetsize, numPacketsPerFrame, npixelsx, databytes));
//TODO: Generate data
char imageData[databytes * 2];
memset(imageData, 0, databytes * 2);
{
int i = 0;
for (i = 0; i < databytes * 2; i += sizeof(uint8_t)) {
*((uint8_t*)(imageData + i)) = i;
}
}
//TODO: Send data
{
int frameNr = 1;
for(frameNr=1; frameNr <= numFrames; ++frameNr ) {
int srcOffset = 0;
int srcOffset2 = npixelsx;
struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin);
usleep(exp_ns / 1000);
char packetData[packetsize];
memset(packetData, 0, packetsize);
char packetData2[packetsize];
memset(packetData2, 0, packetsize);
// loop packet
{
int i = 0;
for(i = 0; i != numPacketsPerFrame; ++i) {
int dstOffset = sizeof(sls_detector_header);
int dstOffset2 = sizeof(sls_detector_header);
// set header
sls_detector_header* header = (sls_detector_header*)(packetData);
header->frameNumber = frameNr;
header->packetNumber = i;
header = (sls_detector_header*)(packetData2);
header->frameNumber = frameNr;
header->packetNumber = i;
// fill data
{
int psize = 0;
for (psize = 0; psize < datasize; psize += npixelsx) {
if (dr == 32 && tgEnable == 0) {
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx/2);
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx/2);
srcOffset += npixelsx;
srcOffset2 += npixelsx;
dstOffset += npixelsx/2;
dstOffset2 += npixelsx/2;
} else {
memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx);
memcpy(packetData2 + dstOffset2, imageData + srcOffset2, npixelsx);
srcOffset += 2 * npixelsx;
srcOffset2 += 2 * npixelsx;
dstOffset += npixelsx;
dstOffset2 += npixelsx;
}
}
}
sendUDPPacket(0, packetData, packetsize);
sendUDPPacket(1, packetData2, packetsize);
}
}
FILE_LOG(logINFO, ("Sent frame: %d\n", frameNr));
clock_gettime(CLOCK_REALTIME, &end);
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));
if (periodns > time_ns) {
usleep((periodns - time_ns)/ 1000);
}
}
}
closeUDPSocket(0);
closeUDPSocket(1);
eiger_virtual_status = 0; eiger_virtual_status = 0;
return NULL; return NULL;
} }
@ -1662,6 +1769,7 @@ void* start_timer(void* arg) {
int stopStateMachine() { int stopStateMachine() {
FILE_LOG(logINFORED, ("Going to stop acquisition\n")); FILE_LOG(logINFORED, ("Going to stop acquisition\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
@ -1749,10 +1857,6 @@ enum runStatus getRunStatus() {
void readFrame(int *ret, char *mess) { void readFrame(int *ret, char *mess) {
#ifdef VIRTUAL #ifdef VIRTUAL
while(eiger_virtual_status) {
//FILE_LOG(logERROR ,"Waiting for finished flag\n"));
usleep(5000);
}
FILE_LOG(logINFOGREEN, ("acquisition successfully finished\n")); FILE_LOG(logINFOGREEN, ("acquisition successfully finished\n"));
return; return;
#else #else
@ -1857,12 +1961,3 @@ int getTotalNumberOfChannels() {return ((int)getNumberOfChannelsPerChip() * (in
int getNumberOfChips() {return NCHIP;} int getNumberOfChips() {return NCHIP;}
int getNumberOfDACs() {return NDAC;} int getNumberOfDACs() {return NDAC;}
int getNumberOfChannelsPerChip() {return NCHAN;} int getNumberOfChannelsPerChip() {return NCHAN;}

View File

@ -0,0 +1,26 @@
add_executable(jungfrauDetectorServer
slsDetectorFunctionList.c
slsDetectorServer.c
slsDetectorServer_funcs.c
communication_funcs.c
)
target_include_directories(jungfrauDetectorServer
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(jungfrauDetectorServer
PUBLIC JUNGFRAUD VIRTUAL STOP_SERVER
)
target_link_libraries(jungfrauDetectorServer
PUBLIC pthread rt
)
set_target_properties(jungfrauDetectorServer PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
install(TARGETS jungfrauDetectorServer
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

View File

@ -1,27 +0,0 @@
CC = gcc
CFLAGS += -Wall -DJUNGFRAUD -DVIRTUAL -DSTOP_SERVER #-DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lstdc++ -pthread
PROGS = jungfrauDetectorServer_virtual
DESTDIR ?= bin
INSTMODE = 0777
SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c
OBJS = $(SRC_CLNT:.c=.o)
all: clean versioning $(PROGS)
boot: $(OBJS)
versioning:
@echo `tput setaf 6; ./updateGitVersion.sh; tput sgr0;`
$(PROGS): $(OBJS)
# echo $(OBJS)
mkdir -p $(DESTDIR)
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
mv $(PROGS) $(DESTDIR)
clean:
rm -rf $(DESTDIR)/$(PROGS) *.o

View File

@ -0,0 +1 @@
../slsDetectorServer/communication_funcs_UDP.h

View File

@ -1,7 +1,7 @@
#include "slsDetectorFunctionList.h" #include "slsDetectorFunctionList.h"
#include "versionAPI.h" #include "versionAPI.h"
#include "logger.h" #include "logger.h"
#include <sys/select.h>
#include "AD9257.h" // commonServerFunctions.h, blackfin.h, ansi.h #include "AD9257.h" // commonServerFunctions.h, blackfin.h, ansi.h
#include "LTC2620.h" // dacs #include "LTC2620.h" // dacs
#include "MAX1932.h" // hv #include "MAX1932.h" // hv
@ -9,6 +9,7 @@
#ifndef VIRTUAL #ifndef VIRTUAL
#include "programfpga.h" #include "programfpga.h"
#else #else
#include "communication_funcs_UDP.h"
#include "blackfin.h" #include "blackfin.h"
#include <string.h> #include <string.h>
#include <unistd.h> // usleep #include <unistd.h> // usleep
@ -1097,6 +1098,14 @@ int configureMAC(int numInterfaces, int selInterface,
uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport,
uint32_t destip2, uint64_t destmac2, uint64_t sourcemac2, uint32_t sourceip2, uint32_t udpport2) { uint32_t destip2, uint64_t destmac2, uint64_t sourcemac2, uint32_t sourceip2, uint32_t udpport2) {
#ifdef VIRTUAL #ifdef VIRTUAL
char cDestIp[MAX_STR_LENGTH];
memset(cDestIp, 0, MAX_STR_LENGTH);
sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff);
FILE_LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, udpport));
if (setUDPDestinationDetails(0, cDestIp, udpport) == FAIL) {
FILE_LOG(logERROR, ("could not set udp destination IP and port\n"));
return FAIL;
}
return OK; return OK;
#endif #endif
FILE_LOG(logINFOBLUE, ("Configuring MAC\n")); FILE_LOG(logINFOBLUE, ("Configuring MAC\n"));
@ -1437,7 +1446,7 @@ void setAdcPhase(int val, int degrees){
alignDeserializer(); alignDeserializer();
} }
int getPhase(degrees) { int getPhase(int degrees) {
if (!degrees) if (!degrees)
return adcPhase; return adcPhase;
// convert back to degrees // convert back to degrees
@ -1581,11 +1590,16 @@ int setNetworkParameter(enum NETWORKINDEX mode, int value) {
int startStateMachine(){ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
// create udp socket
if(createUDPSocket(0) != OK) {
return FAIL;
}
FILE_LOG(logINFOBLUE, ("starting state machine\n"));
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; virtual_stop = 0;
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
virtual_status = 0;
FILE_LOG(logERROR, ("Could not start Virtual acquisition thread\n")); FILE_LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0;
return FAIL; return FAIL;
} }
FILE_LOG(logINFOGREEN, ("Virtual Acquisition started\n")); FILE_LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1606,16 +1620,69 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
int wait_in_s = (setTimer(FRAME_NUMBER, -1) * int64_t periodns = setTimer(FRAME_PERIOD, -1);
int numFrames = (setTimer(FRAME_NUMBER, -1) *
setTimer(CYCLES_NUMBER, -1) * setTimer(CYCLES_NUMBER, -1) *
(setTimer(STORAGE_CELL_NUMBER, -1) + 1) * (setTimer(STORAGE_CELL_NUMBER, -1) + 1));
(setTimer(FRAME_PERIOD, -1)/(1E9))); int64_t exp_ns = setTimer(ACQUISITION_TIME, -1);
FILE_LOG(logDEBUG1, ("going to wait for %d s\n", wait_in_s));
while(!virtual_stop && (wait_in_s >= 0)) { //TODO: Generate data
usleep(1000 * 1000); char imageData[DATA_BYTES];
wait_in_s--; memset(imageData, 0, DATA_BYTES);
} {
FILE_LOG(logINFOGREEN, ("Virtual Timer Done\n")); int i = 0;
for (i = 0; i < DATA_BYTES; i += sizeof(uint16_t)) {
*((uint16_t*)(imageData + i)) = i;
}
}
int datasize = 8192;
//TODO: Send data
{
int frameNr = 0;
for(frameNr=0; frameNr!= numFrames; ++frameNr ) {
int srcOffset = 0;
struct timespec begin, end;
clock_gettime(CLOCK_REALTIME, &begin);
usleep(exp_ns / 1000);
const int size = datasize + 112;
char packetData[size];
memset(packetData, 0, sizeof(sls_detector_header));
// loop packet
{
int i = 0;
for(i=0; i!=128; ++i) {
// set header
sls_detector_header* header = (sls_detector_header*)(packetData);
header->frameNumber = frameNr;
header->packetNumber = i;
// fill data
memcpy(packetData + sizeof(sls_detector_header), imageData + srcOffset, datasize);
srcOffset += datasize;
sendUDPPacket(0, packetData, size);
}
}
FILE_LOG(logINFO, ("Sent frame: %d\n", frameNr));
clock_gettime(CLOCK_REALTIME, &end);
int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec));
if (periodns > time_ns) {
usleep((periodns - time_ns)/ 1000);
}
}
}
// }
closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
return NULL; return NULL;
@ -1694,10 +1761,7 @@ enum runStatus getRunStatus(){
void readFrame(int *ret, char *mess){ void readFrame(int *ret, char *mess){
#ifdef VIRTUAL #ifdef VIRTUAL
while(virtual_status) { FILE_LOG(logINFOGREEN, ("acquisition successfully finished\n"));
//FILE_LOG(logERROR, ("Waiting for finished flag\n");
usleep(5000);
}
return; return;
#endif #endif
// wait for status to be done // wait for status to be done
@ -1745,5 +1809,3 @@ int getTotalNumberOfChannels(){return ((int)getNumberOfChannelsPerChip() * (int
int getNumberOfChips(){return NCHIP;} int getNumberOfChips(){return NCHIP;}
int getNumberOfDACs(){return NDAC;} int getNumberOfDACs(){return NDAC;}
int getNumberOfChannelsPerChip(){return NCHAN;} int getNumberOfChannelsPerChip(){return NCHAN;}

View File

@ -4,8 +4,12 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/select.h>
#include <unistd.h> #include <unistd.h>
#define SEND_REC_MAX_SIZE 4096 #define SEND_REC_MAX_SIZE 4096
#define DEFAULT_PORTNO 1952 #define DEFAULT_PORTNO 1952
#define DEFAULT_BACKLOG 5 #define DEFAULT_BACKLOG 5

View File

@ -15,25 +15,25 @@
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
int udpSockfd = -1; int udpSockfd[2] = {-1, -1};
struct addrinfo* udpServerAddrInfo = 0; struct addrinfo* udpServerAddrInfo[2] = {0, 0};
unsigned short int udpDestinationPort = 0; unsigned short int udpDestinationPort[2] = {0, 0};
char udpDestinationIp[MAX_STR_LENGTH] = ""; char udpDestinationIp[2][MAX_STR_LENGTH] = {"", ""};
//DEFAULT_TX_UDP_PORT;// src port //DEFAULT_TX_UDP_PORT;// src port
int getUdPSocketDescriptor() { int getUdPSocketDescriptor(int index) {
return udpSockfd; return udpSockfd[index];
} }
int setUDPDestinationDetails(const char* ip, unsigned short int port) { int setUDPDestinationDetails(int index, const char* ip, unsigned short int port) {
udpDestinationPort = port; udpDestinationPort[index] = port;
size_t len = strlen(ip); size_t len = strlen(ip);
memset(udpDestinationIp, 0, MAX_STR_LENGTH); memset(udpDestinationIp[index], 0, MAX_STR_LENGTH);
strncpy(udpDestinationIp, ip, len > MAX_STR_LENGTH ? MAX_STR_LENGTH : len ); strncpy(udpDestinationIp[index], ip, len > MAX_STR_LENGTH ? MAX_STR_LENGTH : len );
if (udpServerAddrInfo) { if (udpServerAddrInfo[index]) {
freeaddrinfo(udpServerAddrInfo); freeaddrinfo(udpServerAddrInfo[index]);
udpServerAddrInfo = 0; udpServerAddrInfo[index] = 0;
} }
// convert ip to internet address // convert ip to internet address
@ -45,73 +45,73 @@ int setUDPDestinationDetails(const char* ip, unsigned short int port) {
hints.ai_protocol = 0; hints.ai_protocol = 0;
char sport[100]; char sport[100];
memset(sport, 0, 100); memset(sport, 0, 100);
sprintf(sport, "%d", udpDestinationPort); sprintf(sport, "%d", udpDestinationPort[index]);
int err = getaddrinfo(udpDestinationIp, sport, &hints, &udpServerAddrInfo); int err = getaddrinfo(udpDestinationIp[index], sport, &hints, &udpServerAddrInfo[index]);
if (err != 0) { if (err != 0) {
FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d. " FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d. "
"(Error code:%d, %s)\n", udpDestinationIp, udpDestinationPort, err, gai_strerror(err))); "(Error code:%d, %s)\n", udpDestinationIp[index], udpDestinationPort[index], err, gai_strerror(err)));
return FAIL; return FAIL;
} }
if (udpServerAddrInfo == NULL) { if (udpServerAddrInfo[index] == NULL) {
FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d " FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d "
"(getaddrinfo returned NULL)\n", udpDestinationIp, udpDestinationPort)); "(getaddrinfo returned NULL)\n", udpDestinationIp[index], udpDestinationPort[index]));
udpServerAddrInfo = 0; udpServerAddrInfo[index] = 0;
return FAIL; return FAIL;
} }
return OK; return OK;
} }
int createUDPSocket() { int createUDPSocket(int index) {
FILE_LOG(logDEBUG2, ("Creating UDP Socket\n")); FILE_LOG(logDEBUG2, ("Creating UDP Socket %d\n", index));
if (!strlen(udpDestinationIp)) { if (!strlen(udpDestinationIp[index])) {
FILE_LOG(logERROR, ("No destination UDP ip specified.\n")); FILE_LOG(logERROR, ("No destination UDP ip specified.\n"));
return FAIL; return FAIL;
} }
if (udpSockfd != -1) { if (udpSockfd[index] != -1) {
FILE_LOG(logERROR, ("Strange that Udp socket was still open. Closing it to create a new one\n")); FILE_LOG(logERROR, ("Strange that Udp socket was still open. Closing it to create a new one\n"));
close(udpSockfd); close(udpSockfd[index]);
udpSockfd = -1; udpSockfd[index] = -1;
} }
// Creating socket file descriptor // Creating socket file descriptor
udpSockfd = socket(udpServerAddrInfo->ai_family, udpServerAddrInfo->ai_socktype, udpServerAddrInfo->ai_protocol); udpSockfd[index] = socket(udpServerAddrInfo[index]->ai_family, udpServerAddrInfo[index]->ai_socktype, udpServerAddrInfo[index]->ai_protocol);
if (udpSockfd == -1 ) { if (udpSockfd[index] == -1 ) {
FILE_LOG(logERROR, ("UDP socket at port %d failed. (Error code:%d, %s)\n", FILE_LOG(logERROR, ("UDP socket at port %d failed. (Error code:%d, %s)\n",
udpDestinationPort, errno, gai_strerror(errno))); udpDestinationPort[index], errno, gai_strerror(errno)));
return FAIL; return FAIL;
} }
FILE_LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n", FILE_LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n",
udpDestinationPort, udpDestinationIp)); udpDestinationPort[index], udpDestinationIp[index]));
// connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet // connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet
// using write without a connect will end in segv // using write without a connect will end in segv
if (connect(udpSockfd,udpServerAddrInfo->ai_addr, udpServerAddrInfo->ai_addrlen)==-1) { if (connect(udpSockfd[index],udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen)==-1) {
FILE_LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n", FILE_LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n",
udpDestinationIp, udpDestinationPort, errno, gai_strerror(errno))); udpDestinationIp[index], udpDestinationPort[index], errno, gai_strerror(errno)));
} }
FILE_LOG(logINFO, ("Udp client socket connected\n", FILE_LOG(logINFO, ("Udp client socket connected\n",
udpDestinationPort, udpDestinationIp)); udpDestinationPort[index], udpDestinationIp[index]));
return OK; return OK;
} }
int sendUDPPacket(const char* buf, int length) { int sendUDPPacket(int index, const char* buf, int length) {
int n = write(udpSockfd, buf, length); int n = write(udpSockfd[index], buf, length);
// udp sends atomically, no need to handle partial data // udp sends atomically, no need to handle partial data
if (n == -1) { if (n == -1) {
FILE_LOG(logERROR, ("Could not send udp packet. (Error code:%d, %s)\n", FILE_LOG(logERROR, ("Could not send udp packet for socket %d. (Error code:%d, %s)\n",
n, errno, gai_strerror(errno))); index, n, errno, gai_strerror(errno)));
} else { } else {
FILE_LOG(logDEBUG2, ("%d bytes sent\n", n)); FILE_LOG(logDEBUG2, ("%d bytes sent\n", n));
} }
return n; return n;
} }
void closeUDPSocket() { void closeUDPSocket(int index) {
if (udpSockfd != -1) { if (udpSockfd[index] != -1) {
FILE_LOG(logINFO, ("Udp client socket closed\n")); FILE_LOG(logINFO, ("Udp client socket closed\n"));
close(udpSockfd); close(udpSockfd[index]);
udpSockfd = -1; udpSockfd[index] = -1;
} }
} }

View File

@ -5,7 +5,7 @@
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> // FILE #include <stdio.h> // FILE
#include <sys/types.h>
/**************************************************** /****************************************************
This functions are used by the slsDetectroServer_funcs interface. This functions are used by the slsDetectroServer_funcs interface.

View File

@ -30,7 +30,6 @@ void error(char *msg){
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
// print version // print version
if (argc > 1 && !strcasecmp(argv[1], "-version")) { if (argc > 1 && !strcasecmp(argv[1], "-version")) {
int version = 0; int version = 0;
@ -142,4 +141,3 @@ int main(int argc, char *argv[]){
FILE_LOG(logINFO,("Goodbye!\n")); FILE_LOG(logINFO,("Goodbye!\n"));
return 0; return 0;
} }

View File

@ -92,7 +92,7 @@ if (SLS_USE_TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif(SLS_USE_TESTS) endif(SLS_USE_TESTS)
install(TARGETS slsReceiverShared install(TARGETS slsReceiverShared slsReceiver
EXPORT "${TARGETS_EXPORT_NAME}" EXPORT "${TARGETS_EXPORT_NAME}"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}

View File

@ -6,6 +6,5 @@
#define APIRECEIVER 0x190405 #define APIRECEIVER 0x190405
#define APIGUI 0x190405 #define APIGUI 0x190405
#define APIEIGER 0x190516 #define APIEIGER 0x190516
#define APICTB 0x190528 #define APICTB 0x190528
#define APIJUNGFRAU 0x190528 #define APIJUNGFRAU 0x190528