Compare commits

..

5 Commits

Author SHA1 Message Date
d5a712ab42 WIP 2021-11-11 16:03:39 +01:00
fa931b8fca WIP 2021-11-11 16:00:45 +01:00
37bf3600ad only static 2021-11-11 15:58:41 +01:00
96f6561080 only static 2021-11-11 15:57:22 +01:00
9ca831d954 cmake 3.9 and removed zmq 2021-11-11 15:41:50 +01:00
102 changed files with 1909 additions and 3081 deletions

View File

@ -1,12 +1,12 @@
# SPDX-License-Identifier: LGPL-3.0-or-other # SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.9)
project(slsDetectorPackage) project(slsDetectorPackage)
set(PROJECT_VERSION 6.1.0) set(PROJECT_VERSION 6.0.0)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
cmake_policy(SET CMP0074 NEW) # cmake_policy(SET CMP0074 NEW)
include(cmake/project_version.cmake) include(cmake/project_version.cmake)
#functions to add compiler flags #functions to add compiler flags
@ -67,7 +67,10 @@ set(ClangFormat_EXCLUDE_PATTERNS "build/"
${CMAKE_BINARY_DIR}) ${CMAKE_BINARY_DIR})
find_package(ClangFormat) find_package(ClangFormat)
#Enable LTO if available
include(CheckIPOSupported)
check_ipo_supported(RESULT SLS_LTO_AVAILABLE)
message(STATUS "SLS_LTO_AVAILABLE:" ${SLS_LTO_AVAILABLE})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@ -78,16 +81,6 @@ if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif() endif()
#Enable LTO if available
include(CheckIPOSupported)
check_ipo_supported(RESULT SLS_LTO_AVAILABLE)
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE)
message(STATUS "Building with link time optimization")
else()
message(STATUS "Building without link time optimization")
endif()
#Add two fake libraries to manage options #Add two fake libraries to manage options
add_library(slsProjectOptions INTERFACE) add_library(slsProjectOptions INTERFACE)
add_library(slsProjectWarnings INTERFACE) add_library(slsProjectWarnings INTERFACE)
@ -140,10 +133,11 @@ endif()
# Add or disable warnings depending on if the compiler supports them # Add or disable warnings depending on if the compiler supports them
# The function checks internally and sets HAS_warning-name # The function checks internally and sets HAS_warning-name
sls_enable_cxx_warning("-Wnull-dereference") # sls_enable_cxx_warning("-Wnull-dereference")
sls_enable_cxx_warning("-Wduplicated-cond") # sls_enable_cxx_warning("-Wduplicated-cond")
sls_disable_cxx_warning("-Wclass-memaccess") # sls_disable_cxx_warning("-Wclass-memaccess")
sls_disable_c_warning("-Wstringop-truncation") # sls_disable_c_warning("-Wstringop-truncation")
# sls_disable_c_warning("-Wformat-nonliteral")
if(SLS_USE_SANITIZER) if(SLS_USE_SANITIZER)
@ -178,35 +172,35 @@ set(CMAKE_INSTALL_RPATH $ORIGIN)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found") # set(ZeroMQ_HINT "" CACHE STRING "Hint where ZeroMQ could be found")
#Adapted from: https://github.com/zeromq/cppzmq/ # #Adapted from: https://github.com/zeromq/cppzmq/
if (NOT TARGET libzmq) # if (NOT TARGET libzmq)
if(ZeroMQ_HINT) # if(ZeroMQ_HINT)
message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}") # message(STATUS "Looking for ZeroMQ in: ${ZeroMQ_HINT}")
find_package(ZeroMQ 4 # find_package(ZeroMQ 4
NO_DEFAULT_PATH # NO_DEFAULT_PATH
HINTS ${ZeroMQ_DIR} # HINTS ${ZeroMQ_DIR}
) # )
else() # else()
find_package(ZeroMQ 4 QUIET) # find_package(ZeroMQ 4 QUIET)
endif() # endif()
# libzmq autotools install: fallback to pkg-config # # libzmq autotools install: fallback to pkg-config
if(NOT ZeroMQ_FOUND) # if(NOT ZeroMQ_FOUND)
message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)") # message(STATUS "CMake libzmq package not found, trying again with pkg-config (normal install of zeromq)")
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config) # list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/libzmq-pkg-config)
find_package(ZeroMQ 4 REQUIRED) # find_package(ZeroMQ 4 REQUIRED)
endif() # endif()
# TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work # # TODO "REQUIRED" above should already cause a fatal failure if not found, but this doesn't seem to work
if(NOT ZeroMQ_FOUND) # if(NOT ZeroMQ_FOUND)
message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config") # message(FATAL_ERROR "ZeroMQ was not found, neither as a CMake package nor via pkg-config")
endif() # endif()
if (ZeroMQ_FOUND AND NOT TARGET libzmq) # if (ZeroMQ_FOUND AND NOT TARGET libzmq)
message(FATAL_ERROR "ZeroMQ version not supported!") # message(FATAL_ERROR "ZeroMQ version not supported!")
endif() # endif()
endif() # endif()
if (SLS_USE_TESTS) if (SLS_USE_TESTS)
enable_testing() enable_testing()

View File

@ -1,7 +1,7 @@
SLS Detector Package Minor Release 6.1.0 released on 25.11.2021 SLS Detector Package 6.0.0 released on 21.10.2021
=============================================================== ==================================================
This document describes the differences between v6.1.0 and v6.0.0. This document describes the differences between v6.0.0 and v5.1.0.
@ -9,9 +9,10 @@ This document describes the differences between v6.1.0 and v6.0.0.
-------- --------
1. New or Changed Features 1. New or Changed Features
2. Resolved Issues 2. Resolved Issues
3. Firmware Requirements 3. Known Issues
4. Kernel Requirements 4. Changes in Next Major Release
5. Download, Documentation & Support 5. Firmware Requirements
6. Download, Documentation & Support
@ -19,97 +20,277 @@ This document describes the differences between v6.1.0 and v6.0.0.
1. New or Changed Features 1. New or Changed Features
========================== ==========================
Client Added License. Read COPYING for more details.
Client
------ ------
1. Shared libraries
They are versioned from this release on (6.0.0).
1. Kernel version 2. [Jungfrau] Chip version
Commandline: kernelversion, API: getKernelVersion Features for chipv1.1 incorporated
Command line: chipversion, API: getchipVersion
2. [Jungfrau][Mythen3][Gotthard2][Gotthard][Moench][Ctb] gets chip version (1.0 or 1.1)
Update Kernel chipv1.1 requires config_jungfrau.txt on detector server and HW 2.0.
Commandline: updatekernel, API: updatekernel
You could damage the detector. Please use with caution.
3. Update Detector Server (no tftp)
Commandline: updatedetectorserver, API: updateDetectorServer
Updates the detector server without using tftp. It also creates a
symbolic link to a shorter name and reboots. The API using tftp
(copydetectorserver) is deprecated.
4. Update Firmware and Server (no tftp)
Commandline: update (fewer arguments), API: updateFirmwareAndServer
(overloaded) Same as before, except the server is transferred to the
detector without tftp. The previous API and command (fewer arguments)
using tftp is deprecated.
5. Update mode in Detector server
Commandline: udpatemode, API set/getUpdateMode
One can set detector server to update mode (especially if server and
firmware are incompatible that the server cannot start up without errors).
This mode will limit access to a few operations only needed to update the
detector. Setting it will create an empty file (udpate.txt) and resetting
it will delete the empty file. Ofcourse, command line "--update" will
overwrite any file detection and start server in update mode.
Detector Server 3. [Jungfrau] Chip configuration (only chipv1.1)
--------------- powering on the chip and changing settings will configure the chip.
Hence, required before acquisition.
4. [Jungfrau] Settings and Gain mode
Settings can be gain0 and highgain0. Gain mode can be dynamicgain,
forceswitchg1, forceswitchg2, fixg1, fixg2, fixg0. fixg0 must be
used with EXTRA caution as you can damage the detector.
Changing settings also changes dac values of 3 dacs
(vref_prech, vref_ds and vref_comp) and reconfigures chip (only v1.1)
5. [Jungfrau] Storage cells (only chipv1.1)
Additional number of storage cells not applicable for chipv1.1.
Storage cell start is only allowed from 0 - 3 for chipv1.1
(0 - 15 for chipv1.0).
Command line: extrastoragecells, Previous Command line: storagecells
API: remains the same.
6. [Gotthard2][Jungfrau] Filter Resistor
Command line: filterresistor, API: getFilterResistor/ setFilterResistor
Previous Command: filter, setFilter/ getFilter
Set Filter resistor. Increasing values for increasing resistance.
[Jungfrau] only for chipv1.1. Options: [0|1]. Default is 1.
[Gotthard2] Options: [0|1|2|3]. Default is 0.
7. [Jungfrau] Filter cell (only chipv1.1)
Command line: filtercells, API: getNumberOfFilterCells/ setNumberOfFilterCells
Set filter cell. Options: [0-12]. Advanced user command.
8. [Jungfrau] Comparator disable time (only chipv1.1)
Command line: compdisabletime, API: getComparatorDisableTime/
setComparatorDisableTime
One can customize the period to disable comparator.
9. [Eiger][Jungfrau] Read n rows
Command line: readnrows, API: getReadNRows/ setReadNRows
Previous Command: readnlines, getPartialReadout/ setPartialReadout
[Eiger] same as before
[Jungfrau] Options: 8 - 512, multiples of 8. Default is 512.
10. [Gotthard2][Jungfrau] Current source
Command line: currentsource, API: getCurrentSource, setCurrentSource
Enable or disable current source. Default is disabled.
[Gotthard2] Can only enable or disable.
[Jungfrau] Can choose to fix, select source and choose normal or low
current. Normal/ low only for chipv1.1.
Select source is 0-63 for chipv1.0 and a 64 bit mask for chipv1.1.
11. Default dac
Command line: defaultdac, API: getDefaultDac/ setDefaultDac
change default value of a dac
[Jungfrau][Mythen3] Also change default value of dac for particular
setting.
12. Reset dacs
Command line: resetdacs, API: resetToDefaultDacs
Previous command: defaultdacs
Resets dacs to their default values or hard coded values.
13. [Mythen3] Gain Capacitance
Command line: gaincaps, API: getGainCaps/ setGainCaps
Set various gain capacitances.
14. [Gotthard2] Veto Streaming from chip
Command line: veto, API: getVeto/ setVeto
This command used to mean veto streaming from detector. Now, it means
veto streaming from chip (New feature). Default is disabled.
15. [Gotthard2] Veto streaming from detector
Command line: vetostream, API: getVetoStream, setVetoStream
Options: None, local link interface, 10 10GbE, Both
Default: None
10GbE (as before) will enable 2 udp interfaces in receiver.
16. [Gotthard2] Veto algorithm
Command line: vetoalg, API: getVetoAlgorithm/ setVetoAlgorithm
Set veto algorithm for each interface.
Options: hits, raw
17. [Eiger][Gotthard2][Mythen3] Module ID
Command line: moduleid, API: getModuleId
Previous command (Eiger only): serialnumber, getSerialNumber
Unique id read from txt file on detector and streamed out in udp header.
18. [Gotthard2]
Command line: dbitpipeline, API: getDBITPipeline/ setDBITPipeline
Set pipeline to latch digital bits. Options: 0-7
19. [Eiger][Jungfrau] Round Robin commands
Command line, udp_dstlist, API: getDestinationUDPList/
setDestinationUDPList
Round robin commands at the moment does not configure the receiver.
Set multiple udp destinations in the detector to stream udp data packets
to. Upto 32 destinations. Refer documentation for details.
Command line, udp_numdst, API: getNumberofUDPDestinations
[Jungfrau] Command line, udp_firstdst, API: getFirstUDPDestination/
setFirstUDPDestination
20. Command Line Parsing
Parsing of detector index and module index has been modified to
integrate round robin index.
[detector index]-[module index]:[round robin index] [command]
It is backwards compatible.
For ease, one can also execute
sls_detector_put [module index] [command]
21. Clear Udp Destination
Command line, udp_cleardst, API: clearUDPDestinations
This is useful when changing receivers for a detector or for round robin
system.
22. Shared Memory Naming
Shared memory name has been changed to reflect a more appropriate naming
scheme.
23. [Eiger][Mythen3] Blocking trigger
Command line: blockingtrigger, API: sendSoftwareTrigger
Sends software trigger signal to detector and blocks till frames are
sent out for that trigger.
24. [Eiger] Data stream enable for ports
Command line: datastream, API: getDataStream/ setDataStream
Enable or disable each port. Default: enabled
25. Changing TCP ports
This will only affect shared memory and will not try to change the
current tcp port of the control/stop server in detector.
26. [Eiger][Jungfrau][Gotthard2] Speed
Command line: readoutspeed, readoutspeedlist API: getReadoutSpeed/ setReadoutSpeed /
getReadoutSpeedList
Previous command: speed, setSpeed/ getSpeed
[Eiger][Jungfrau] same as before.
[Gotthard2] New command to set readout speed. Options: 108, 144 (in MHz)
27. [Eiger][Jungfrau] Flip rows
Command line: fliprows, API: getFlipRows/ setFlipRows
Previous command: flippeddatax, setBottom/ getBottom
[Jungfrau] Flips rows in detector only for HW v2.0.
slsReceiver and slsDetectorGui will not flip them again.
[Eiger] same as before.
28. [Jungfrau]
Command line changes: autocompdisable, Previous command line: auto_comp_disable
Detector servers
----------------
1. [Gotthard2] Bad Channels moved to a new register, default settings
including clock frequency changed
2. [Gotthard2] Updated config file in detector server
Virtual servers
----------------
1. Artifical pixel values increasing by every packet, instead of every pixel.
2. All possible features updated.
Receiver
--------
1. Frames caught in metadata
Frames caught by the master receiver is added to master file metadata.
Hdf5 and Binary version numbers changed to 6.3
2. Removed Padding option for Deactivated half modules.
3. Changing Receiver TCP ports
This will only affect shared memory and will not try to change the
current tcp port of the receiver.
Gui
----
1. [Mythen3] counters added in settings tab
1. [Gotthard2] speed
Ensuring dbitpipeline is default when changing speed. This has an effect
only if dbitpipeline was changed in between.
2. Resolved Issues 2. Resolved Issues
================== ==================
Detector Server Detector Servers
--------------- ----------------
1. [Gotthard2] Tolerance in time parameters.
Eg. 220 ns was being set to 215 ns, instead of 222ns.
2. [Jungfrau] Stopping in trigger mode and then switching to auto timing mode
blocks data streaming from detector. Workaround fix made in
detector server to reset core until next firmware release.
3. [Jungfrau][CTB][Moench][Gotthard][Gotthard2][Mythen3] Firmware Programming
Firmware programming incorporates more validations such as checksum of
program. Always ensure client and server are of same release before
programming firmware.
4. [Eiger] Stop sends last frame
Stop acquisition will now also send out all complete frames in fifo.
5. [Eiger] Bottom not rotated in quad mode. Fixed.
6. [Mythen3] counter mask effect on vthreshold
Setting counter mask changes vth daac values (ie. disabling sets to 2800),
vthreshold only changes for enabled counters, setting vth overwrites
dac even if counter disabled and when counters enabled, remembers set
values.
1. [Jungfrau][Moench][Ctb] Programming Firmware Failures 7. [Eiger] fast quad fix for loading trimbits
Firmware programming via software failures are fixed using a new kernel
and corresponding changes in server software. Software works with both
old and new kernels.
2. [Gotthard2][Mythen3]
Verifies kernel version at server start up.
3. [Jungfrau]
Verifies HW2.0 before trying to set read n rows or flip rows.
Has no effect when not using slsReceiver.
4. [Eiger]
Thresholdnotb command loads threshold energy without trimbits, but had
a bug in the server that was setting nchip to 0 and further trimval or
trim commands would no work reliably. This is fixed now.
Client
------
1. Receiver Id in the commands in config files were ignored. Fixed.
2. Execute command now also mentions which module failed.
3. [Jungfrau][Moench][Ctb]
Programming firmware procedure did not delete temporary file created in
6.0.0. Fixed.
8. [Eiger] Can also use copydetectorserver command.
[All] copydetectorserver command also creates a link to the binary copied
with a shorter name ([detector]DetectorServer only)
Receiver Receiver
-------- --------
1. Setting receiver hostname to "none" threw an exception. Fixed. 1. Disabled port or deactivated (half) modules will not create files.
2. [Jungfrau]
Since the server verifies HW2.0 for number of rows before trying to set it,
the receiver now does not show incorrect missing packets stemming from this
issue.
3. Firmware Requirements
3. Known Issues
===============
Receiver
--------
1. It does not handle readnrows or partial readout. Only the summary
is adjusted to print in red. However, it will still write complete
images with missing data padded. Roi will be implemented in future
that can be complemented with this feature to remove the additional
data in files.
2. Round robin is not implemented in receiver side, ie. one cannot configure
more than 1 receiver at a time. This will/might be done in the future.
4. Changes in Next Major Release
================================
1. Naming of Package
The package might be renamed and so might the binaries, libraries,
namespace,include paths in the next major release (which is breaking API).
5. Firmware Requirements
======================== ========================
Eiger Eiger
@ -144,6 +325,7 @@ This document describes the differences between v6.1.0 and v6.0.0.
Detector Upgrade Detector Upgrade
================ ================
The following can be upgraded remotely: The following can be upgraded remotely:
Eiger via bit files Eiger via bit files
Jungfrau via command <.pof> Jungfrau via command <.pof>
@ -162,34 +344,8 @@ This document describes the differences between v6.1.0 and v6.0.0.
4. Kernel Requirements
======================
Blackfin 6. Download, Documentation & Support
========
Latest version: Fri Oct 29 00:00:00 2021
Older ones will work, but might have issues with programming firmware via
the package.
Nios
====
Compatible version: Mon May 10 18:00:21 CEST 2021
Kernel Upgrade
==============
Eiger via bit files
Others via command
Commands: udpatekernel, kernelversion
Instructions available at
https://slsdetectorgroup.github.io/devdoc/commandline.html
https://slsdetectorgroup.github.io/devdoc/detector.html
https://slsdetectorgroup.github.io/devdoc/pydetector.html
5. Download, Documentation & Support
==================================== ====================================
Download Download

View File

@ -7,9 +7,9 @@ function(enable_cxx_warning flag target)
check_cxx_compiler_flag(${flag} ${flag_name}) check_cxx_compiler_flag(${flag} ${flag_name})
if(${flag_name}) if(${flag_name})
target_compile_options(${target} INTERFACE ${flag}) target_compile_options(${target} INTERFACE ${flag})
message(STATUS "Adding: ${flag} to ${target}") message("Adding: ${flag} to ${target}")
else() else()
message(STATUS "Flag: ${flag} not supported") message("Flag: ${flag} not supported")
endif() endif()
endfunction() endfunction()
@ -18,9 +18,9 @@ function(enable_c_warning flag target)
check_c_compiler_flag(${flag} ${flag_name}) check_c_compiler_flag(${flag} ${flag_name})
if(${flag_name}) if(${flag_name})
target_compile_options(${target} INTERFACE ${flag}) target_compile_options(${target} INTERFACE ${flag})
message(STATUS "Adding: ${flag} to ${target}") message("Adding: ${flag} to ${target}")
else() else()
message(STATUS "Flag: ${flag} not supported") message("Flag: ${flag} not supported")
endif() endif()
endfunction() endfunction()
@ -31,10 +31,10 @@ function(disable_cxx_warning flag target)
if(${flag_name}) if(${flag_name})
string(REPLACE "-W" "-Wno-" neg_flag ${flag}) string(REPLACE "-W" "-Wno-" neg_flag ${flag})
message(STATUS "Adding: ${neg_flag} to ${target}") message("Adding: ${neg_flag} to ${target}")
target_compile_options(${target} INTERFACE ${neg_flag}) target_compile_options(${target} INTERFACE ${neg_flag})
else() else()
message(STATUS "Warning: ${flag} not supported no need to disable") message("Warning: ${flag} not supported no need to disable")
endif() endif()
endfunction() endfunction()
@ -43,10 +43,10 @@ function(disable_c_warning flag target)
check_c_compiler_flag(${flag} ${flag_name}) check_c_compiler_flag(${flag} ${flag_name})
if(${flag_name}) if(${flag_name})
string(REPLACE "-W" "-Wno-" neg_flag ${flag}) string(REPLACE "-W" "-Wno-" neg_flag ${flag})
message(STATUS "Adding: ${neg_flag} to ${target}") message("Adding: ${neg_flag} to ${target}")
target_compile_options(${target} INTERFACE ${neg_flag}) target_compile_options(${target} INTERFACE ${neg_flag})
else() else()
message(STATUS "Warning: ${flag} not supported no need to disable") message("Warning: ${flag} not supported no need to disable")
endif() endif()
endfunction() endfunction()

2
cmk.sh
View File

@ -1,6 +1,6 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-3.0-or-other # SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package # Copyright (C) 2021 Contributors to the SLS Detector Package
#!/bin/bash
CMAKE="cmake3" CMAKE="cmake3"
BUILDDIR="build" BUILDDIR="build"
INSTALLDIR="" INSTALLDIR=""

View File

@ -3,7 +3,6 @@ python:
- 3.7 - 3.7
- 3.8 - 3.8
- 3.9 - 3.9
- 3.10
numpy: numpy:
- 1.17 - 1.17

View File

@ -61,6 +61,7 @@ set( HEADERS
#set(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) #set(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# ROOT dictionary generation # ROOT dictionary generation
include("${ROOT_DIR}/RootMacros.cmake")
root_generate_dictionary(ctbDict ${HEADERS} LINKDEF ctbLinkDef.h) root_generate_dictionary(ctbDict ${HEADERS} LINKDEF ctbLinkDef.h)
add_library(ctbRootLib SHARED ctbDict.cxx) add_library(ctbRootLib SHARED ctbDict.cxx)
target_include_directories(ctbRootLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(ctbRootLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
@ -85,5 +86,4 @@ target_link_libraries(ctbGui PUBLIC
set_target_properties(ctbGui PROPERTIES set_target_properties(ctbGui PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )

View File

@ -305,53 +305,43 @@ Firmware Troubleshooting with blackfin
5. If one can't list it, read the next section to try to get the blackfin to list it. 5. If one can't list it, read the next section to try to get the blackfin to list it.
How to get back mtd3 drive remotely (udpating kernel) How to get back mtd3 drive remotely (copying new kernel)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You have 2 alternatives to update the kernel.
1. Commands via software (>= v6.0.0) .. code-block:: bash
.. code-block:: bash
sls_detector_put updatekernel /home/...path-to-kernel-image
2. or command line
.. code-block:: bash # step 1: get the kernel image (uImage.lzma) from slsdetectorgroup
# and copy it to pc's tftp folder
# step 1: get the kernel image (uImage.lzma) from slsdetectorgroup
# and copy it to pc's tftp folder
# step 2: connect to the board # step 2: connect to the board
telnet bchipxxx telnet bchipxxx
#step 3: go to directory for space #step 3: go to directory for space
cd /var/tmp/ cd /var/tmp/
# step 3: copy kernel to board # step 3: copy kernel to board
tftp pcxxx -r uImage.lzma -g tftp pcxxx -r uImage.lzma -g
# step 4: verify kernel copied properly # step 4: verify kernel copied properly
ls -lrt ls -lrt
# step 5: erase flash # step 5: erase flash
flash_eraseall /dev/mtd1 flash_eraseall /dev/mtd1
# step 6: copy new image to kernel drive # step 6: copy new image to kernel drive
cat uImage.lzma > /dev/mtd1 cat uImage.lzma > /dev/mtd1
# step 7: # step 7:
sync sync
# step 8: # step 8:
reboot reboot
# step 9: verification # step 9: verification
telnet bchipxxx telnet bchipxxx
uname -a # verify kernel date uname -a # verify kernel date
more /proc/mtd # verify mtd3 is listed more /proc/mtd # verify mtd3 is listed
Last Resort using USB Blaster Last Resort using USB Blaster
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -247,19 +247,6 @@ Possible causes could be the following:
* For Jungfrau, refer to :ref:`Jungfrau Power Supply Troubleshooting<Jungfrau Troubleshooting Power Supply>`. * For Jungfrau, refer to :ref:`Jungfrau Power Supply Troubleshooting<Jungfrau Troubleshooting Power Supply>`.
Cannot ping module (Nios)
^^^^^^^^^^^^^^^^^^^^^^^^^
If you executed "reboot" command on the board, you cannot ping it anymore unless you power cycle. To reboot the controller, please use the software command ("rebootcontroller"), which talks to the microcontroller.
Gotthard2
---------
Cannot get data without a module attached
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You cannot get data without a module attached as a specific pin is floating. Attach module to get data.
Gotthard Gotthard
---------- ----------

View File

@ -16,8 +16,8 @@ from parse import remove_comments
allow_bitwise_op = ["M3_GainCaps"] allow_bitwise_op = ["M3_GainCaps"]
allow_bitwise_op = ["streamingInterface"] allow_bitwise_op = ["streamingInterface"]
op_key = {"operator|": "|", op_key = {"operator|": "__or__",
"operator&" : "&"} "operator&" : "__and__"}
def single_line_enum(line): def single_line_enum(line):
sub = line[line.find('{')+1:line.find('}')] sub = line[line.find('{')+1:line.find('}')]
@ -92,7 +92,8 @@ def generate_enum_string(enums):
#Here add the operators #Here add the operators
for op in operators: for op in operators:
data.append(f"\n\t.def(py::self {op_key[op]} slsDetectorDefs::{key}())") data.append(f"\n\t.def(\"{op_key[op]}\", py::overload_cast< const slsDetectorDefs::streamingInterface&, const slsDetectorDefs::streamingInterface&>(&{op}))")
data.append(';\n\n') data.append(';\n\n')
return ''.join(data) return ''.join(data)

View File

@ -224,19 +224,6 @@ class Detector(CppDetectorApi):
""" """
return ut.lhex(self.getDetectorServerVersion()) return ut.lhex(self.getDetectorServerVersion())
@property
@element
def kernelversion(self):
"""
Kernel version on the detector including time and date
Example
-------
>>> d.kernelversion
'#37 PREEMPT Thu Oct 13 14:51:04 CEST 2016'
"""
return self.getKernelVersion()
@property @property
def clientversion(self): def clientversion(self):
"""Client software version in format [YYMMDD] """Client software version in format [YYMMDD]
@ -1669,7 +1656,6 @@ class Detector(CppDetectorApi):
'client': self.clientversion, 'client': self.clientversion,
'firmware': self.firmwareversion, 'firmware': self.firmwareversion,
'detectorserver': self.detectorserverversion, 'detectorserver': self.detectorserverversion,
'kernel': self.kernelversion,
'receiver': self.rx_version} 'receiver': self.rx_version}
@property @property
@ -2515,7 +2501,6 @@ class Detector(CppDetectorApi):
----- -----
:getter: always returns in seconds. To get in datetime.delta, use getBurstPeriod :getter: always returns in seconds. To get in datetime.delta, use getBurstPeriod
:setter: Not Implemented
Example Example
----------- -----------
@ -3437,10 +3422,10 @@ class Detector(CppDetectorApi):
[Gotthard2][Mythen3] Frequency of clock in Hz. [Gotthard2][Mythen3] Frequency of clock in Hz.
Note Note
---- -----
:setter: Not implemented. Use clkdiv to set frequency :setter: Not implemented. Use clkdiv to set frequency
Example Example
------- -------
>>> d.clkfreq[0] >>> d.clkfreq[0]

View File

@ -67,10 +67,6 @@ void init_det(py::module &m) {
(Result<int64_t>(Detector::*)(sls::Positions) const) & (Result<int64_t>(Detector::*)(sls::Positions) const) &
Detector::getDetectorServerVersion, Detector::getDetectorServerVersion,
py::arg() = Positions{}) py::arg() = Positions{})
.def("getKernelVersion",
(Result<std::string>(Detector::*)(sls::Positions) const) &
Detector::getKernelVersion,
py::arg() = Positions{})
.def("getSerialNumber", .def("getSerialNumber",
(Result<int64_t>(Detector::*)(sls::Positions) const) & (Result<int64_t>(Detector::*)(sls::Positions) const) &
Detector::getSerialNumber, Detector::getSerialNumber,
@ -1521,14 +1517,6 @@ void init_det(py::module &m) {
sls::Positions)) & sls::Positions)) &
Detector::copyDetectorServer, Detector::copyDetectorServer,
py::arg(), py::arg(), py::arg() = Positions{}) 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", .def("rebootController",
(void (Detector::*)(sls::Positions)) & Detector::rebootController, (void (Detector::*)(sls::Positions)) & Detector::rebootController,
py::arg() = Positions{}) py::arg() = Positions{})
@ -1537,19 +1525,6 @@ void init_det(py::module &m) {
const std::string &, sls::Positions)) & const std::string &, sls::Positions)) &
Detector::updateFirmwareAndServer, Detector::updateFirmwareAndServer,
py::arg(), py::arg(), py::arg(), py::arg() = Positions{}) 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("getUpdateMode",
(Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getUpdateMode,
py::arg() = Positions{})
.def("setUpdateMode",
(void (Detector::*)(bool, sls::Positions)) &
Detector::setUpdateMode,
py::arg(), py::arg() = Positions{})
.def("readRegister", .def("readRegister",
(Result<uint32_t>(Detector::*)(uint32_t, sls::Positions) const) & (Result<uint32_t>(Detector::*)(uint32_t, sls::Positions) const) &
Detector::readRegister, Detector::readRegister,

View File

@ -1,5 +1,4 @@
/* WARINING This file is auto generated any edits might be overwritten without /* WARINING This file is auto generated any edits might be overwritten without warning */
* warning */
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
@ -43,19 +42,15 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::frameDiscardPolicy>(Defs, "frameDiscardPolicy") py::enum_<slsDetectorDefs::frameDiscardPolicy>(Defs, "frameDiscardPolicy")
.value("NO_DISCARD", slsDetectorDefs::frameDiscardPolicy::NO_DISCARD) .value("NO_DISCARD", slsDetectorDefs::frameDiscardPolicy::NO_DISCARD)
.value("DISCARD_EMPTY_FRAMES", .value("DISCARD_EMPTY_FRAMES", slsDetectorDefs::frameDiscardPolicy::DISCARD_EMPTY_FRAMES)
slsDetectorDefs::frameDiscardPolicy::DISCARD_EMPTY_FRAMES) .value("DISCARD_PARTIAL_FRAMES", slsDetectorDefs::frameDiscardPolicy::DISCARD_PARTIAL_FRAMES)
.value("DISCARD_PARTIAL_FRAMES", .value("NUM_DISCARD_POLICIES", slsDetectorDefs::frameDiscardPolicy::NUM_DISCARD_POLICIES)
slsDetectorDefs::frameDiscardPolicy::DISCARD_PARTIAL_FRAMES)
.value("NUM_DISCARD_POLICIES",
slsDetectorDefs::frameDiscardPolicy::NUM_DISCARD_POLICIES)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::fileFormat>(Defs, "fileFormat") py::enum_<slsDetectorDefs::fileFormat>(Defs, "fileFormat")
.value("BINARY", slsDetectorDefs::fileFormat::BINARY) .value("BINARY", slsDetectorDefs::fileFormat::BINARY)
.value("HDF5", slsDetectorDefs::fileFormat::HDF5) .value("HDF5", slsDetectorDefs::fileFormat::HDF5)
.value("NUM_FILE_FORMATS", .value("NUM_FILE_FORMATS", slsDetectorDefs::fileFormat::NUM_FILE_FORMATS)
slsDetectorDefs::fileFormat::NUM_FILE_FORMATS)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::dimension>(Defs, "dimension") py::enum_<slsDetectorDefs::dimension>(Defs, "dimension")
@ -64,25 +59,19 @@ void init_enums(py::module &m) {
.export_values(); .export_values();
py::enum_<slsDetectorDefs::externalSignalFlag>(Defs, "externalSignalFlag") py::enum_<slsDetectorDefs::externalSignalFlag>(Defs, "externalSignalFlag")
.value("TRIGGER_IN_RISING_EDGE", .value("TRIGGER_IN_RISING_EDGE", slsDetectorDefs::externalSignalFlag::TRIGGER_IN_RISING_EDGE)
slsDetectorDefs::externalSignalFlag::TRIGGER_IN_RISING_EDGE) .value("TRIGGER_IN_FALLING_EDGE", slsDetectorDefs::externalSignalFlag::TRIGGER_IN_FALLING_EDGE)
.value("TRIGGER_IN_FALLING_EDGE", .value("INVERSION_ON", slsDetectorDefs::externalSignalFlag::INVERSION_ON)
slsDetectorDefs::externalSignalFlag::TRIGGER_IN_FALLING_EDGE) .value("INVERSION_OFF", slsDetectorDefs::externalSignalFlag::INVERSION_OFF)
.value("INVERSION_ON",
slsDetectorDefs::externalSignalFlag::INVERSION_ON)
.value("INVERSION_OFF",
slsDetectorDefs::externalSignalFlag::INVERSION_OFF)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::timingMode>(Defs, "timingMode") py::enum_<slsDetectorDefs::timingMode>(Defs, "timingMode")
.value("AUTO_TIMING", slsDetectorDefs::timingMode::AUTO_TIMING) .value("AUTO_TIMING", slsDetectorDefs::timingMode::AUTO_TIMING)
.value("TRIGGER_EXPOSURE", .value("TRIGGER_EXPOSURE", slsDetectorDefs::timingMode::TRIGGER_EXPOSURE)
slsDetectorDefs::timingMode::TRIGGER_EXPOSURE)
.value("GATED", slsDetectorDefs::timingMode::GATED) .value("GATED", slsDetectorDefs::timingMode::GATED)
.value("BURST_TRIGGER", slsDetectorDefs::timingMode::BURST_TRIGGER) .value("BURST_TRIGGER", slsDetectorDefs::timingMode::BURST_TRIGGER)
.value("TRIGGER_GATED", slsDetectorDefs::timingMode::TRIGGER_GATED) .value("TRIGGER_GATED", slsDetectorDefs::timingMode::TRIGGER_GATED)
.value("NUM_TIMING_MODES", .value("NUM_TIMING_MODES", slsDetectorDefs::timingMode::NUM_TIMING_MODES)
slsDetectorDefs::timingMode::NUM_TIMING_MODES)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::dacIndex>(Defs, "dacIndex") py::enum_<slsDetectorDefs::dacIndex>(Defs, "dacIndex")
@ -170,16 +159,13 @@ void init_enums(py::module &m) {
.value("HIGH_VOLTAGE", slsDetectorDefs::dacIndex::HIGH_VOLTAGE) .value("HIGH_VOLTAGE", slsDetectorDefs::dacIndex::HIGH_VOLTAGE)
.value("TEMPERATURE_ADC", slsDetectorDefs::dacIndex::TEMPERATURE_ADC) .value("TEMPERATURE_ADC", slsDetectorDefs::dacIndex::TEMPERATURE_ADC)
.value("TEMPERATURE_FPGA", slsDetectorDefs::dacIndex::TEMPERATURE_FPGA) .value("TEMPERATURE_FPGA", slsDetectorDefs::dacIndex::TEMPERATURE_FPGA)
.value("TEMPERATURE_FPGAEXT", .value("TEMPERATURE_FPGAEXT", slsDetectorDefs::dacIndex::TEMPERATURE_FPGAEXT)
slsDetectorDefs::dacIndex::TEMPERATURE_FPGAEXT)
.value("TEMPERATURE_10GE", slsDetectorDefs::dacIndex::TEMPERATURE_10GE) .value("TEMPERATURE_10GE", slsDetectorDefs::dacIndex::TEMPERATURE_10GE)
.value("TEMPERATURE_DCDC", slsDetectorDefs::dacIndex::TEMPERATURE_DCDC) .value("TEMPERATURE_DCDC", slsDetectorDefs::dacIndex::TEMPERATURE_DCDC)
.value("TEMPERATURE_SODL", slsDetectorDefs::dacIndex::TEMPERATURE_SODL) .value("TEMPERATURE_SODL", slsDetectorDefs::dacIndex::TEMPERATURE_SODL)
.value("TEMPERATURE_SODR", slsDetectorDefs::dacIndex::TEMPERATURE_SODR) .value("TEMPERATURE_SODR", slsDetectorDefs::dacIndex::TEMPERATURE_SODR)
.value("TEMPERATURE_FPGA2", .value("TEMPERATURE_FPGA2", slsDetectorDefs::dacIndex::TEMPERATURE_FPGA2)
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA2) .value("TEMPERATURE_FPGA3", slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
.value("TEMPERATURE_FPGA3",
slsDetectorDefs::dacIndex::TEMPERATURE_FPGA3)
.value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN) .value("TRIMBIT_SCAN", slsDetectorDefs::dacIndex::TRIMBIT_SCAN)
.value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A) .value("V_POWER_A", slsDetectorDefs::dacIndex::V_POWER_A)
.value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B) .value("V_POWER_B", slsDetectorDefs::dacIndex::V_POWER_B)
@ -218,20 +204,15 @@ void init_enums(py::module &m) {
.value("VERYLOWGAIN", slsDetectorDefs::detectorSettings::VERYLOWGAIN) .value("VERYLOWGAIN", slsDetectorDefs::detectorSettings::VERYLOWGAIN)
.value("G1_HIGHGAIN", slsDetectorDefs::detectorSettings::G1_HIGHGAIN) .value("G1_HIGHGAIN", slsDetectorDefs::detectorSettings::G1_HIGHGAIN)
.value("G1_LOWGAIN", slsDetectorDefs::detectorSettings::G1_LOWGAIN) .value("G1_LOWGAIN", slsDetectorDefs::detectorSettings::G1_LOWGAIN)
.value("G2_HIGHCAP_HIGHGAIN", .value("G2_HIGHCAP_HIGHGAIN", slsDetectorDefs::detectorSettings::G2_HIGHCAP_HIGHGAIN)
slsDetectorDefs::detectorSettings::G2_HIGHCAP_HIGHGAIN) .value("G2_HIGHCAP_LOWGAIN", slsDetectorDefs::detectorSettings::G2_HIGHCAP_LOWGAIN)
.value("G2_HIGHCAP_LOWGAIN", .value("G2_LOWCAP_HIGHGAIN", slsDetectorDefs::detectorSettings::G2_LOWCAP_HIGHGAIN)
slsDetectorDefs::detectorSettings::G2_HIGHCAP_LOWGAIN) .value("G2_LOWCAP_LOWGAIN", slsDetectorDefs::detectorSettings::G2_LOWCAP_LOWGAIN)
.value("G2_LOWCAP_HIGHGAIN",
slsDetectorDefs::detectorSettings::G2_LOWCAP_HIGHGAIN)
.value("G2_LOWCAP_LOWGAIN",
slsDetectorDefs::detectorSettings::G2_LOWCAP_LOWGAIN)
.value("G4_HIGHGAIN", slsDetectorDefs::detectorSettings::G4_HIGHGAIN) .value("G4_HIGHGAIN", slsDetectorDefs::detectorSettings::G4_HIGHGAIN)
.value("G4_LOWGAIN", slsDetectorDefs::detectorSettings::G4_LOWGAIN) .value("G4_LOWGAIN", slsDetectorDefs::detectorSettings::G4_LOWGAIN)
.value("GAIN0", slsDetectorDefs::detectorSettings::GAIN0) .value("GAIN0", slsDetectorDefs::detectorSettings::GAIN0)
.value("UNDEFINED", slsDetectorDefs::detectorSettings::UNDEFINED) .value("UNDEFINED", slsDetectorDefs::detectorSettings::UNDEFINED)
.value("UNINITIALIZED", .value("UNINITIALIZED", slsDetectorDefs::detectorSettings::UNINITIALIZED)
slsDetectorDefs::detectorSettings::UNINITIALIZED)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::clockIndex>(Defs, "clockIndex") py::enum_<slsDetectorDefs::clockIndex>(Defs, "clockIndex")
@ -244,8 +225,7 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::readoutMode>(Defs, "readoutMode") py::enum_<slsDetectorDefs::readoutMode>(Defs, "readoutMode")
.value("ANALOG_ONLY", slsDetectorDefs::readoutMode::ANALOG_ONLY) .value("ANALOG_ONLY", slsDetectorDefs::readoutMode::ANALOG_ONLY)
.value("DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY) .value("DIGITAL_ONLY", slsDetectorDefs::readoutMode::DIGITAL_ONLY)
.value("ANALOG_AND_DIGITAL", .value("ANALOG_AND_DIGITAL", slsDetectorDefs::readoutMode::ANALOG_AND_DIGITAL)
slsDetectorDefs::readoutMode::ANALOG_AND_DIGITAL)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel") py::enum_<slsDetectorDefs::speedLevel>(Defs, "speedLevel")
@ -259,18 +239,14 @@ void init_enums(py::module &m) {
py::enum_<slsDetectorDefs::burstMode>(Defs, "burstMode") py::enum_<slsDetectorDefs::burstMode>(Defs, "burstMode")
.value("BURST_INTERNAL", slsDetectorDefs::burstMode::BURST_INTERNAL) .value("BURST_INTERNAL", slsDetectorDefs::burstMode::BURST_INTERNAL)
.value("BURST_EXTERNAL", slsDetectorDefs::burstMode::BURST_EXTERNAL) .value("BURST_EXTERNAL", slsDetectorDefs::burstMode::BURST_EXTERNAL)
.value("CONTINUOUS_INTERNAL", .value("CONTINUOUS_INTERNAL", slsDetectorDefs::burstMode::CONTINUOUS_INTERNAL)
slsDetectorDefs::burstMode::CONTINUOUS_INTERNAL) .value("CONTINUOUS_EXTERNAL", slsDetectorDefs::burstMode::CONTINUOUS_EXTERNAL)
.value("CONTINUOUS_EXTERNAL",
slsDetectorDefs::burstMode::CONTINUOUS_EXTERNAL)
.value("NUM_BURST_MODES", slsDetectorDefs::burstMode::NUM_BURST_MODES) .value("NUM_BURST_MODES", slsDetectorDefs::burstMode::NUM_BURST_MODES)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::timingSourceType>(Defs, "timingSourceType") py::enum_<slsDetectorDefs::timingSourceType>(Defs, "timingSourceType")
.value("TIMING_INTERNAL", .value("TIMING_INTERNAL", slsDetectorDefs::timingSourceType::TIMING_INTERNAL)
slsDetectorDefs::timingSourceType::TIMING_INTERNAL) .value("TIMING_EXTERNAL", slsDetectorDefs::timingSourceType::TIMING_EXTERNAL)
.value("TIMING_EXTERNAL",
slsDetectorDefs::timingSourceType::TIMING_EXTERNAL)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::M3_GainCaps>(Defs, "M3_GainCaps") py::enum_<slsDetectorDefs::M3_GainCaps>(Defs, "M3_GainCaps")
@ -289,17 +265,14 @@ void init_enums(py::module &m) {
.value("BOTTOM", slsDetectorDefs::portPosition::BOTTOM) .value("BOTTOM", slsDetectorDefs::portPosition::BOTTOM)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::streamingInterface>(Defs, "streamingInterface", py::enum_<slsDetectorDefs::streamingInterface>(Defs, "streamingInterface", py::arithmetic())
py::arithmetic())
.value("NONE", slsDetectorDefs::streamingInterface::NONE) .value("NONE", slsDetectorDefs::streamingInterface::NONE)
.value("LOW_LATENCY_LINK", .value("LOW_LATENCY_LINK", slsDetectorDefs::streamingInterface::LOW_LATENCY_LINK)
slsDetectorDefs::streamingInterface::LOW_LATENCY_LINK) .value("ETHERNET_10GB", slsDetectorDefs::streamingInterface::ETHERNET_10GB)
.value("ETHERNET_10GB",
slsDetectorDefs::streamingInterface::ETHERNET_10GB)
.value("ALL", slsDetectorDefs::streamingInterface::ALL) .value("ALL", slsDetectorDefs::streamingInterface::ALL)
.export_values() .export_values()
.def(py::self | slsDetectorDefs::streamingInterface()) .def("__or__", py::overload_cast<const slsDetectorDefs::streamingInterface &, const slsDetectorDefs::streamingInterface &>(&operator|))
.def(py::self & slsDetectorDefs::streamingInterface()); .def("__and__", py::overload_cast<const slsDetectorDefs::streamingInterface &, const slsDetectorDefs::streamingInterface &>(&operator&));
py::enum_<slsDetectorDefs::vetoAlgorithm>(Defs, "vetoAlgorithm") py::enum_<slsDetectorDefs::vetoAlgorithm>(Defs, "vetoAlgorithm")
.value("ALG_HITS", slsDetectorDefs::vetoAlgorithm::ALG_HITS) .value("ALG_HITS", slsDetectorDefs::vetoAlgorithm::ALG_HITS)

View File

@ -1,23 +0,0 @@
from slsdet.enums import streamingInterface
import pytest
def test_streamingInterface_bitwise():
"""Bitwise operations on streaming interfaces are allowed"""
sif_none = streamingInterface.NONE
sif_low = streamingInterface.LOW_LATENCY_LINK
sif_10g = streamingInterface.ETHERNET_10GB
sif_all = streamingInterface.ALL
assert sif_low | sif_none == sif_low
assert sif_10g | sif_none == sif_10g
assert sif_low | sif_10g == sif_all
assert sif_10g | sif_all == sif_all
assert sif_10g & sif_low == sif_none
assert sif_low & sif_low == sif_low
assert sif_all & sif_all == sif_all
def test_streamingInterface_bitwise_only_allowed_on_same_type():
with pytest.raises(Exception):
assert streamingInterface.LOW_LATENCY_LINK & 5 == 7

View File

@ -0,0 +1 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv6.0.0

View File

@ -1 +0,0 @@
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv6.1.0

View File

@ -39,7 +39,7 @@ foreach(exe ${MOENCH_EXECUTABLES})
set_target_properties(${exe} PROPERTIES set_target_properties(${exe} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
set_property(TARGET ${exe} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET ${exe} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()

View File

@ -110,7 +110,7 @@ target_link_libraries(slsDetectorGui PUBLIC
set_target_properties(slsDetectorGui PROPERTIES set_target_properties(slsDetectorGui PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
set_property(TARGET slsDetectorGui PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsDetectorGui PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()

View File

@ -17,7 +17,7 @@ add_executable(ctbDetectorServer_virtual
../slsDetectorServer/src/INA226.c ../slsDetectorServer/src/INA226.c
../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programViaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../slsDetectorServer/src/loadPattern.c ../slsDetectorServer/src/loadPattern.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c

View File

@ -16,7 +16,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)programViaBlackfin.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)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -97,14 +97,8 @@ void basictests() {
return; return;
#else #else
initError = defineGPIOpins(initErrorMessage); defineGPIOpins();
if (initError == FAIL) { resetFPGA();
return;
}
initError = resetFPGA(initErrorMessage);
if (initError == FAIL) {
return;
}
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Dangerous to continue.\n");

View File

@ -2699,6 +2699,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac)); LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac));
LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan)); LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan));
destMod->ndac = srcMod->ndac;
destMod->nchip = srcMod->nchip;
destMod->nchan = srcMod->nchan;
if (srcMod->reg >= 0) if (srcMod->reg >= 0)
destMod->reg = srcMod->reg; destMod->reg = srcMod->reg;
if (srcMod->iodelay >= 0) if (srcMod->iodelay >= 0)
@ -2709,7 +2712,7 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
destMod->eV[0] = srcMod->eV[0]; destMod->eV[0] = srcMod->eV[0];
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg)); LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0 && srcMod->nchan != 0) { if (destMod->nchan != 0) {
for (int ichan = 0; ichan < (srcMod->nchan); ichan++) { for (int ichan = 0; ichan < (srcMod->nchan); ichan++) {
if (*((srcMod->chanregs) + ichan) >= 0) if (*((srcMod->chanregs) + ichan) >= 0)
*((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan); *((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan);

View File

@ -12,7 +12,7 @@ add_executable(gotthard2DetectorServer_virtual
../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/LTC2620_Driver.c
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/ASIC_Driver.c ../slsDetectorServer/src/ASIC_Driver.c
../slsDetectorServer/src/programViaNios.c ../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c
) )

View File

@ -15,7 +15,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)/programViaNios.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)/programFpgaNios.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -101,7 +101,7 @@ void basictests() {
} }
// does check only if flag is 0 (by default), set by command line // does check only if flag is 0 (by default), set by command line
if ((!debugflag) && (!updateFlag) && if ((!debugflag) && (!updateFlag) &&
((validateKernelVersion(KERNEL_DATE_VRSN) == FAIL) || (checkType() == FAIL) || ((checkKernelVersion() == FAIL) || (checkType() == FAIL) ||
(testFpga() == FAIL) || (testBus() == FAIL))) { (testFpga() == FAIL) || (testBus() == FAIL))) {
sprintf(initErrorMessage, sprintf(initErrorMessage,
"Could not pass basic tests of FPGA and bus. Dangerous to " "Could not pass basic tests of FPGA and bus. Dangerous to "
@ -184,6 +184,13 @@ void basictests() {
#endif #endif
} }
int checkKernelVersion() {
#ifdef VIRTUAL
return OK;
#endif
return Nios_checkKernelVersion(KERNEL_DATE_VRSN);
}
int checkType() { int checkType() {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
@ -2083,40 +2090,24 @@ int setReadoutSpeed(int val) {
case G2_108MHZ: case G2_108MHZ:
LOG(logINFOBLUE, ("Setting readout speed to 108 MHz\n")); LOG(logINFOBLUE, ("Setting readout speed to 108 MHz\n"));
if (setClockDivider(READOUT_C0, SPEED_108_CLKDIV_0) == FAIL) { if (setClockDivider(READOUT_C0, SPEED_108_CLKDIV_0) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 108 MHz. Failed to set readout clk 0 to %d\n", SPEED_108_CLKDIV_0));
return FAIL; return FAIL;
} }
if (setClockDivider(READOUT_C1, SPEED_108_CLKDIV_1) == FAIL) { if (setClockDivider(READOUT_C1, SPEED_108_CLKDIV_1) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 108 MHz. Failed to set readout clk 1 to %d\n", SPEED_108_CLKDIV_1));
return FAIL; return FAIL;
} }
if (setPhase(READOUT_C1, SPEED_108_CLKPHASE_DEG_1, 1) == FAIL) { if (setPhase(READOUT_C1, SPEED_108_CLKPHASE_DEG_1, 1) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 108 MHz. Failed to set clk phase 1 %d deg\n", SPEED_108_CLKPHASE_DEG_1));
return FAIL;
}
setDBITPipeline(SPEED_144_DBIT_PIPELINE);
if (getDBITPipeline() != SPEED_144_DBIT_PIPELINE) {
LOG(logERROR, ("Could not set readout speed to 108 MHz. Failed to set dbitpipeline to %d \n", SPEED_144_DBIT_PIPELINE));
return FAIL; return FAIL;
} }
break; break;
case G2_144MHZ: case G2_144MHZ:
LOG(logINFOBLUE, ("Setting readout speed to 144 MHz\n")); LOG(logINFOBLUE, ("Setting readout speed to 144 MHz\n"));
if (setClockDivider(READOUT_C0, SPEED_144_CLKDIV_0) == FAIL) { if (setClockDivider(READOUT_C0, SPEED_144_CLKDIV_0) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 144 MHz. Failed to set readout clk 0 to %d\n", SPEED_144_CLKDIV_0));
return FAIL; return FAIL;
} }
if (setClockDivider(READOUT_C1, SPEED_144_CLKDIV_1) == FAIL) { if (setClockDivider(READOUT_C1, SPEED_144_CLKDIV_1) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 144 MHz. Failed to set readout clk 1 to %d\n", SPEED_144_CLKDIV_1));
return FAIL; return FAIL;
} }
if (setPhase(READOUT_C1, SPEED_144_CLKPHASE_DEG_1, 1) == FAIL) { if (setPhase(READOUT_C1, SPEED_144_CLKPHASE_DEG_1, 1) == FAIL) {
LOG(logERROR, ("Could not set readout speed to 144 MHz. Failed to set clk phase 1 %d deg\n", SPEED_144_CLKPHASE_DEG_1));
return FAIL;
}
setDBITPipeline(SPEED_144_DBIT_PIPELINE);
if (getDBITPipeline() != SPEED_144_DBIT_PIPELINE) {
LOG(logERROR, ("Could not set readout speed to 144 MHz. Failed to set dbitpipeline to %d \n", SPEED_144_DBIT_PIPELINE));
return FAIL; return FAIL;
} }
break; break;

View File

@ -4,7 +4,7 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN (0x210527) #define REQRD_FRMWRE_VRSN (0x210527)
#define KERNEL_DATE_VRSN "Mon May 10 18:00:21 CEST 2021" #define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020"
#define ID_FILE "detid_gotthard2.txt" #define ID_FILE "detid_gotthard2.txt"
#define LINKED_SERVER_NAME "gotthard2DetectorServer" #define LINKED_SERVER_NAME "gotthard2DetectorServer"
@ -67,11 +67,9 @@
#define SPEED_144_CLKDIV_0 (6) #define SPEED_144_CLKDIV_0 (6)
#define SPEED_144_CLKDIV_1 (6) #define SPEED_144_CLKDIV_1 (6)
#define SPEED_144_CLKPHASE_DEG_1 (122) // 125 not possible #define SPEED_144_CLKPHASE_DEG_1 (122) // 125 not possible
#define SPEED_144_DBIT_PIPELINE (1)
#define SPEED_108_CLKDIV_0 (8) #define SPEED_108_CLKDIV_0 (8)
#define SPEED_108_CLKDIV_1 (8) #define SPEED_108_CLKDIV_1 (8)
#define SPEED_108_CLKPHASE_DEG_1 (268) // 270 not possible #define SPEED_108_CLKPHASE_DEG_1 (268) // 270 not possible
#define SPEED_108_DBIT_PIPELINE (1)
/* Firmware Definitions */ /* Firmware Definitions */
#define FIXED_PLL_FREQUENCY (20000000) // 20MHz #define FIXED_PLL_FREQUENCY (20000000) // 20MHz

View File

@ -11,7 +11,6 @@ add_executable(gotthardDetectorServer_virtual
../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/common.c ../slsDetectorServer/src/common.c
../slsDetectorServer/src/commonServerFunctions.c ../slsDetectorServer/src/commonServerFunctions.c
../slsDetectorServer/src/programViaBlackfin.c
../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c

View File

@ -15,7 +15,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)programViaBlackfin.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)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)
all: clean $(PROGS) all: clean $(PROGS)

View File

@ -6,8 +6,6 @@
#define LINKED_SERVER_NAME "gotthardDetectorServer" #define LINKED_SERVER_NAME "gotthardDetectorServer"
#define CTRL_SRVR_INIT_TIME_US (300 * 1000)
/* Enums */ /* Enums */
enum ADCINDEX { TEMP_FPGA, TEMP_ADC }; enum ADCINDEX { TEMP_FPGA, TEMP_ADC };
enum DACINDEX { enum DACINDEX {

View File

@ -12,7 +12,7 @@ add_executable(jungfrauDetectorServer_virtual
../slsDetectorServer/src/ALTERA_PLL.c ../slsDetectorServer/src/ALTERA_PLL.c
../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programViaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c

View File

@ -15,7 +15,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)programViaBlackfin.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)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -74,14 +74,8 @@ void basictests() {
} }
return; return;
#else #else
initError = defineGPIOpins(initErrorMessage); defineGPIOpins();
if (initError == FAIL) { resetFPGA();
return;
}
initError = resetFPGA(initErrorMessage);
if (initError == FAIL) {
return;
}
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Dangerous to continue.\n");
@ -501,14 +495,12 @@ void setupDetector() {
// temp threshold and reset event // temp threshold and reset event
setThresholdTemperature(DEFAULT_TMP_THRSHLD); setThresholdTemperature(DEFAULT_TMP_THRSHLD);
setTemperatureEvent(0); setTemperatureEvent(0);
setFlipRows(DEFAULT_FLIP_ROWS);
if (getChipVersion() == 11) { if (getChipVersion() == 11) {
setFilterResistor(DEFAULT_FILTER_RESISTOR); setFilterResistor(DEFAULT_FILTER_RESISTOR);
setNumberOfFilterCells(DEFAULT_FILTER_CELL); setNumberOfFilterCells(DEFAULT_FILTER_CELL);
} }
if (!isHardwareVersion2()) { setReadNRows(MAX_ROWS_PER_READOUT);
setFlipRows(DEFAULT_FLIP_ROWS);
setReadNRows(MAX_ROWS_PER_READOUT);
}
} }
int resetToDefaultDacs(int hardReset) { int resetToDefaultDacs(int hardReset) {
@ -1673,11 +1665,6 @@ int setReadNRows(int value) {
LOG(logERROR, ("Invalid number of rows %d\n", value)); LOG(logERROR, ("Invalid number of rows %d\n", value));
return FAIL; return FAIL;
} }
if (isHardwareVersion2()) {
LOG(logERROR, ("Could not set number of rows. Only available for "
"Hardware Board version 2.0.\n"));
return FAIL;
}
// regval is numpackets - 1 // regval is numpackets - 1
int regval = (value / READ_N_ROWS_MULTIPLE) - 1; int regval = (value / READ_N_ROWS_MULTIPLE) - 1;
@ -1686,6 +1673,7 @@ int setReadNRows(int value) {
bus_w(addr, bus_r(addr) & ~READ_N_ROWS_NUM_ROWS_MSK); bus_w(addr, bus_r(addr) & ~READ_N_ROWS_NUM_ROWS_MSK);
bus_w(addr, bus_r(addr) | ((regval << READ_N_ROWS_NUM_ROWS_OFST) & bus_w(addr, bus_r(addr) | ((regval << READ_N_ROWS_NUM_ROWS_OFST) &
READ_N_ROWS_NUM_ROWS_MSK)); READ_N_ROWS_NUM_ROWS_MSK));
if (value == MAX_ROWS_PER_READOUT) { if (value == MAX_ROWS_PER_READOUT) {
LOG(logINFO, ("Disabling Partial Readout (#rows)\n")); LOG(logINFO, ("Disabling Partial Readout (#rows)\n"));
bus_w(addr, bus_r(addr) & ~READ_N_ROWS_ENBL_MSK); bus_w(addr, bus_r(addr) & ~READ_N_ROWS_ENBL_MSK);
@ -1697,10 +1685,6 @@ int setReadNRows(int value) {
} }
int getReadNRows() { int getReadNRows() {
// cannot set it in old board
if (isHardwareVersion2()) {
return MAX_ROWS_PER_READOUT;
}
int enable = (bus_r(READ_N_ROWS_REG) & READ_N_ROWS_ENBL_MSK); int enable = (bus_r(READ_N_ROWS_REG) & READ_N_ROWS_ENBL_MSK);
int regval = ((bus_r(READ_N_ROWS_REG) & READ_N_ROWS_NUM_ROWS_MSK) >> int regval = ((bus_r(READ_N_ROWS_REG) & READ_N_ROWS_NUM_ROWS_MSK) >>
READ_N_ROWS_NUM_ROWS_OFST); READ_N_ROWS_NUM_ROWS_OFST);
@ -2173,11 +2157,6 @@ int getFlipRows() {
} }
void setFlipRows(int arg) { void setFlipRows(int arg) {
if (isHardwareVersion2()) {
LOG(logERROR, ("Could not set flip rows. Only available for "
"Hardware Board version 2.0.\n"));
return;
}
if (arg >= 0) { if (arg >= 0) {
if (arg == 0) { if (arg == 0) {
LOG(logINFO, ("Switching off bottom row flipping\n")); LOG(logINFO, ("Switching off bottom row flipping\n"));

View File

@ -14,7 +14,7 @@ add_executable(moenchDetectorServer_virtual
../slsDetectorServer/src/ALTERA_PLL.c ../slsDetectorServer/src/ALTERA_PLL.c
../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programViaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/loadPattern.c ../slsDetectorServer/src/loadPattern.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c

View File

@ -16,7 +16,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)programViaBlackfin.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)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -94,14 +94,8 @@ void basictests() {
return; return;
#else #else
initError = defineGPIOpins(initErrorMessage); defineGPIOpins();
if (initError == FAIL) { resetFPGA();
return;
}
initError = resetFPGA(initErrorMessage);
if (initError == FAIL) {
return;
}
if (mapCSP0() == FAIL) { if (mapCSP0() == FAIL) {
strcpy(initErrorMessage, strcpy(initErrorMessage,
"Could not map to memory. Dangerous to continue.\n"); "Could not map to memory. Dangerous to continue.\n");

View File

@ -12,7 +12,7 @@ add_executable(mythen3DetectorServer_virtual
../slsDetectorServer/src/common.c ../slsDetectorServer/src/common.c
../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/LTC2620_Driver.c
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/programViaNios.c ../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/loadPattern.c ../slsDetectorServer/src/loadPattern.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
../../slsSupportLib/src/md5.c ../../slsSupportLib/src/md5.c

View File

@ -16,7 +16,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)/programViaNios.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)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -96,9 +96,8 @@ void basictests() {
} }
// does check only if flag is 0 (by default), set by command line // does check only if flag is 0 (by default), set by command line
if ((!debugflag) && (!updateFlag) && if ((!debugflag) && (!updateFlag) &&
((validateKernelVersion(KERNEL_DATE_VRSN) == FAIL) || ((checkKernelVersion() == FAIL) || (checkType() == FAIL) ||
(checkType() == FAIL) || (testFpga() == FAIL) || (testFpga() == FAIL) || (testBus() == FAIL))) {
(testBus() == FAIL))) {
strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. " strcpy(initErrorMessage, "Could not pass basic tests of FPGA and bus. "
"Dangerous to continue.\n"); "Dangerous to continue.\n");
LOG(logERROR, ("%s\n\n", initErrorMessage)); LOG(logERROR, ("%s\n\n", initErrorMessage));
@ -178,6 +177,13 @@ void basictests() {
#endif #endif
} }
int checkKernelVersion() {
#ifdef VIRTUAL
return OK;
#endif
return Nios_checkKernelVersion(KERNEL_DATE_VRSN);
}
int checkType() { int checkType() {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
@ -2488,6 +2494,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac)); LOG(logDEBUG1, ("DACs: src %d, dest %d\n", srcMod->ndac, destMod->ndac));
LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan)); LOG(logDEBUG1, ("Chans: src %d, dest %d\n", srcMod->nchan, destMod->nchan));
destMod->ndac = srcMod->ndac;
destMod->nchip = srcMod->nchip;
destMod->nchan = srcMod->nchan;
if (srcMod->reg >= 0) if (srcMod->reg >= 0)
destMod->reg = srcMod->reg; destMod->reg = srcMod->reg;
/* /*
@ -2503,7 +2512,7 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) {
LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg)); LOG(logDEBUG1, ("Copying register %x (%x)\n", destMod->reg, srcMod->reg));
if (destMod->nchan != 0 && srcMod->nchan != 0) { if (destMod->nchan != 0) {
for (int ichan = 0; ichan < (srcMod->nchan); ichan++) { for (int ichan = 0; ichan < (srcMod->nchan); ichan++) {
*((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan); *((destMod->chanregs) + ichan) = *((srcMod->chanregs) + ichan);
} }

View File

@ -4,7 +4,7 @@
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN (0x210910) #define REQRD_FRMWRE_VRSN (0x210910)
#define KERNEL_DATE_VRSN "Mon May 10 18:00:21 CEST 2021" #define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020"
#define ID_FILE "detid_mythen3.txt" #define ID_FILE "detid_mythen3.txt"
#define LINKED_SERVER_NAME "mythen3DetectorServer" #define LINKED_SERVER_NAME "mythen3DetectorServer"

View File

@ -8,18 +8,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#define UPDATE_FILE "update.txt"
#ifdef VIRTUAL
#define TEMP_PROG_FOLDER_NAME "/tmp/"
#else
#define TEMP_PROG_FOLDER_NAME "/var/tmp/"
#define TEMP_PROG_FOLDER_NAME_ALL_FILES "/var/tmp/*"
#endif
#define TEMP_PROG_FILE_NAME TEMP_PROG_FOLDER_NAME "tmp.rawbin"
enum numberMode { DEC, HEX }; 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 * Convert a value from a range to a different range (eg voltage to dac or vice
@ -37,11 +26,7 @@ int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
int getAbsPath(char *buf, size_t bufSize, char *fname); int getAbsPath(char *buf, size_t bufSize, char *fname);
int getTimeFromString(char *buf, time_t *result); int GetTimeFromString(char *buf, time_t *result);
int getKernelVersion(char *retvals);
int validateKernelVersion(char *expectedVersion);
void validate(int *ret, char *mess, int arg, int retval, char *modename, void validate(int *ret, char *mess, int arg, int retval, char *modename,
enum numberMode nummode); enum numberMode nummode);
@ -49,20 +34,9 @@ void validate64(int *ret, char *mess, int64_t arg, int64_t retval,
char *modename, enum numberMode nummode); char *modename, enum numberMode nummode);
int getModuleIdInFile(int *ret, char *mess, char *fileName); int getModuleIdInFile(int *ret, char *mess, char *fileName);
int verifyChecksumFromBuffer(char *mess, char *functionType, int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
char *clientChecksum, char *buffer, ssize_t bytes); ssize_t bytes);
int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum, int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname);
char *fname); int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
int verifyChecksumFromFlash(char *mess, char *functionType, ssize_t fsize);
char *clientChecksum, char *fname, ssize_t fsize); int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg);
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);
int createEmptyFile(char *mess, char *fname, char *errorPrefix);
int deleteFile(char *mess, char *fname, char *errorPrefix);

View File

@ -89,3 +89,7 @@ int mapCSP0(void);
* Get Nios base address * Get Nios base address
*/ */
u_int32_t *Nios_getBaseAddress(); u_int32_t *Nios_getBaseAddress();
/** check kernel version against expected version string (complain if too old)
* @returns OK or FAIL */
int Nios_checkKernelVersion(char *expectedVersion);

View File

@ -0,0 +1,32 @@
// 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);

View File

@ -2,8 +2,6 @@
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once #pragma once
#include "common.h"
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -15,10 +13,9 @@ void NotifyServerStartSuccess();
/** reset fpga and controller(only implemented for >= v1.1 boards) */ /** reset fpga and controller(only implemented for >= v1.1 boards) */
void rebootControllerAndFPGA(); void rebootControllerAndFPGA();
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
char *functionType, char *checksum, char *fpgasrc,
uint64_t fsize); uint64_t fsize);
int getDrive(char *mess, enum PROGRAM_INDEX index); int getDrive(char *mess);
int openFileForFlash(char *mess, FILE **flashfd); int openFileForFlash(FILE **flashfd, char *mess);
int eraseFlash(char *mess); int eraseFlash(char *mess);
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, char *buffer); int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess);

View File

@ -1,38 +0,0 @@
// 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>
#define BLACKFIN_DEFINED
int defineGPIOpins(char *mess);
int FPGAdontTouchFlash(char *mess);
int FPGATouchFlash(char *mess);
int resetFPGA(char *mess);
int emptyTempFolder(char *mess);
int allowUpdate(char *mess, char *functionType);
/**
* 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);

View File

@ -12,10 +12,9 @@
#endif #endif
#if defined(MYTHEN3D) || defined(GOTTHARD2D) #if defined(MYTHEN3D) || defined(GOTTHARD2D)
#include "programViaNios.h" #include "programFpgaNios.h"
#elif defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) || defined(MOENCHD) || \ #elif defined(CHIPTESTBOARDD) || defined(JUNGFRAUD) || defined(MOENCHD)
defined(GOTTHARDD) #include "programFpgaBlackfin.h"
#include "programViaBlackfin.h"
#endif #endif
#if defined(MYTHEN3D) || defined(GOTTHARD2D) #if defined(MYTHEN3D) || defined(GOTTHARD2D)
@ -61,6 +60,9 @@ typedef struct udpStruct_s {
int isInitCheckDone(); int isInitCheckDone();
int getInitResult(char **mess); int getInitResult(char **mess);
void basictests(); void basictests();
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
int checkKernelVersion();
#endif
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || \ #if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || \
defined(MOENCHD) || defined(MYTHEN3D) || defined(GOTTHARD2D) defined(MOENCHD) || defined(MYTHEN3D) || defined(GOTTHARD2D)
int checkType(); int checkType();

View File

@ -9,7 +9,6 @@
#define REBOOT (-400) #define REBOOT (-400)
// initialization functions // initialization functions
int updateModeAllowedFunction(int file_des);
int printSocketReadError(); int printSocketReadError();
void init_detector(); void init_detector();
int decode_function(int); int decode_function(int);
@ -277,16 +276,4 @@ int clear_all_udp_dst(int);
int get_udp_first_dest(int); int get_udp_first_dest(int);
int set_udp_first_dest(int); int set_udp_first_dest(int);
int get_readout_speed(int); int get_readout_speed(int);
int set_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);
int get_update_mode(int);
int set_update_mode(int);

View File

@ -3,7 +3,6 @@
#include "blackfin.h" #include "blackfin.h"
#include "RegisterDefs.h" #include "RegisterDefs.h"
#include "clogger.h" #include "clogger.h"
#include "common.h"
#include "sls/ansi.h" #include "sls/ansi.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
@ -127,4 +126,4 @@ int mapCSP0(void) {
return OK; return OK;
} }
uint32_t *Blackfin_getBaseAddress() { return csp0base; } uint32_t *Blackfin_getBaseAddress() { return csp0base; }

View File

@ -4,14 +4,10 @@
#include "common.h" #include "common.h"
#include "clogger.h" #include "clogger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "slsDetectorServer_defs.h"
#include <libgen.h> // dirname #include <libgen.h> // dirname
#include <string.h> #include <string.h>
#include <sys/utsname.h> // uname #include <unistd.h> // readlink
#include <unistd.h> // readlink
extern int executeCommand(char *command, char *result, enum TLogLevel level);
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin, int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
int outputMax, int inputValue, int *outputValue) { int outputMax, int inputValue, int *outputValue) {
@ -68,105 +64,15 @@ int getAbsPath(char *buf, size_t bufSize, char *fname) {
return OK; return OK;
} }
int getTimeFromString(char *buf, time_t *result) { int GetTimeFromString(char *buf, time_t *result) {
char buffer[255] = {0};
strcpy(buffer, buf);
// remove timezone as strptime cannot validate timezone despite
// documentation (for blackfin)
LOG(logDEBUG, ("kernel v %s\n", buffer));
const char *timezone = {"CEST"};
char *res = strstr(buffer, timezone);
if (res != NULL) {
size_t cestPos = res - buffer;
size_t pos = cestPos + strlen(timezone) + 1;
while (pos != strlen(buffer)) {
buffer[cestPos] = buffer[pos];
++cestPos;
++pos;
}
buffer[cestPos] = '\0';
}
LOG(logDEBUG, ("kernel v after removing CEST %s\n", buffer));
// convert to time structure
struct tm t; struct tm t;
if (NULL == strptime(buffer, "%a %b %d %H:%M:%S %Y", &t)) { if (NULL == strptime(buf, "%a %b %d %H:%M:%S %Z %Y", &t)) {
return FAIL; return FAIL;
} }
// 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));
*result = mktime(&t); *result = mktime(&t);
return OK; return OK;
} }
int getKernelVersion(char *retvals) {
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));
return FAIL;
}
strcpy(retvals, buf.version);
LOG(logINFOBLUE, ("Kernel Version: %s\n", retvals));
return OK;
}
int validateKernelVersion(char *expectedVersion) {
// extract kernel date string
char version[255] = {0};
if (getKernelVersion(version) == FAIL) {
LOG(logERROR, ("Could not validate kernel version\n"));
return FAIL;
}
LOG(logDEBUG, ("utsname.version:%s\n", version));
char currentVersion[255] = {0};
#ifdef VIRTUAL
strcpy(currentVersion, expectedVersion);
#else
// remove first word (#version number)
const char *ptr = strchr(version, ' ');
if (ptr == NULL) {
LOG(logERROR, ("Could not parse kernel version\n"));
return FAIL;
}
strcpy(currentVersion, version + (ptr - version + 1));
#endif
// 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));
return FAIL;
}
// convert expected date into time
time_t expDate;
if (getTimeFromString(expectedVersion, &expDate) == FAIL) {
LOG(logERROR,
("Could not parse expected kernel date, %s\n", expectedVersion));
return FAIL;
}
// compare if kernel time is older than expected time
if (kernelDate < expDate) {
LOG(logERROR, ("Kernel Version Incompatible (too old)! Expected: [%s], "
"Got [%s]\n",
expectedVersion, currentVersion));
return FAIL;
}
LOG(logINFOBLUE, ("Kernel Version Compatible: %s [min.: %s]\n",
currentVersion, expectedVersion));
return OK;
}
void validate(int *ret, char *mess, int arg, int retval, char *modename, void validate(int *ret, char *mess, int arg, int retval, char *modename,
enum numberMode nummode) { enum numberMode nummode) {
if (*ret == OK && arg != GET_FLAG && retval != arg) { if (*ret == OK && arg != GET_FLAG && retval != arg) {
@ -242,39 +148,30 @@ int getModuleIdInFile(int *ret, char *mess, char *fileName) {
return retval; return retval;
} }
int verifyChecksumFromBuffer(char *mess, char *functionType, int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
char *clientChecksum, char *buffer,
ssize_t bytes) { ssize_t bytes) {
LOG(logINFO, ("\tVerifying Checksum from memory...\n")); LOG(logINFO, ("\tVerifying Checksum...\n"));
MD5_CTX c; MD5_CTX c;
if (!MD5_Init_SLS(&c)) { if (!MD5_Init_SLS(&c)) {
sprintf(mess, strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
if (!MD5_Update_SLS(&c, buffer, bytes)) { if (!MD5_Update_SLS(&c, buffer, bytes)) {
sprintf(mess, strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
return verifyChecksum(mess, functionType, clientChecksum, &c, return verifyChecksum(mess, clientChecksum, &c, "copied program");
"copied program (buffer)");
} }
int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum, int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
char *fname) { LOG(logINFO, ("\tVerifying Checksum...\n"));
LOG(logINFO, ("\tVerifying Checksum of file...\n"));
FILE *fp = fopen(fname, "r"); FILE *fp = fopen(fname, "r");
if (fp == NULL) { if (fp == NULL) {
sprintf( sprintf(mess, "Unable to open %s in read mode to get checksum\n",
mess, fname);
"Could not %s. Unable to open %s in read mode to get checksum\n",
functionType, fname);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -282,9 +179,7 @@ int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum,
MD5_CTX c; MD5_CTX c;
if (!MD5_Init_SLS(&c)) { if (!MD5_Init_SLS(&c)) {
fclose(fp); fclose(fp);
sprintf(mess, strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -295,10 +190,7 @@ int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum,
while (bytes > 0) { while (bytes > 0) {
if (!MD5_Update_SLS(&c, buf, bytes)) { if (!MD5_Update_SLS(&c, buf, bytes)) {
fclose(fp); fclose(fp);
sprintf( strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
mess,
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -307,20 +199,17 @@ int verifyChecksumFromFile(char *mess, char *functionType, char *clientChecksum,
} }
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead)); LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
fclose(fp); fclose(fp);
return verifyChecksum(mess, functionType, clientChecksum, &c, return verifyChecksum(mess, clientChecksum, &c, "copied program");
"copied program (file)");
} }
int verifyChecksumFromFlash(char *mess, char *functionType, int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
char *clientChecksum, char *fname, ssize_t fsize) { ssize_t fsize) {
LOG(logINFO, ("\tVerifying Checksum from flash...\n")); LOG(logINFO, ("\tVerifying FlashChecksum...\n"));
FILE *fp = fopen(fname, "r"); FILE *fp = fopen(fname, "r");
if (fp == NULL) { if (fp == NULL) {
sprintf( sprintf(mess, "Unable to open %s in read mode to get checksum\n",
mess, fname);
"Could not %s. Unable to open %s in read mode to get checksum\n",
functionType, fname);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -328,9 +217,7 @@ int verifyChecksumFromFlash(char *mess, char *functionType,
MD5_CTX c; MD5_CTX c;
if (!MD5_Init_SLS(&c)) { if (!MD5_Init_SLS(&c)) {
fclose(fp); fclose(fp);
sprintf(mess, strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
"Could not %s. Unable to calculate checksum (MD5_Init_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -350,39 +237,33 @@ int verifyChecksumFromFlash(char *mess, char *functionType,
if (!MD5_Update_SLS(&c, buf, bytes)) { if (!MD5_Update_SLS(&c, buf, bytes)) {
fclose(fp); fclose(fp);
sprintf( strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
mess,
"Could not %s. Unable to calculate checksum (MD5_Update_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
// read only until a particular size (drive) // read only until a particular size (drive)
if (fsize != 0 && totalBytesRead >= fsize) { if (fsize != 0 && totalBytesRead >= fsize) {
LOG(logINFO, LOG(logINFO,
("\tReached %lu bytes. Not reading more\n", totalBytesRead)); ("\tReached %lu bytes. Not reading more\n", totalBytesRead));
break; break;
} }
// for less than 128 bytes bytes = fread(buf, 1, readUnitSize, fp);
ssize_t bytesToRead = readUnitSize;
if ((readUnitSize + totalBytesRead) > fsize) {
bytesToRead = fsize - totalBytesRead;
}
bytes = fread(buf, 1, bytesToRead, fp);
totalBytesRead += bytes; totalBytesRead += bytes;
} }
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead)); LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
fclose(fp); fclose(fp);
return verifyChecksum(mess, functionType, clientChecksum, &c, "flash"); int ret = verifyChecksum(mess, clientChecksum, &c, "flash");
if (ret == OK) {
LOG(logINFO, ("Checksum in Flash verified\n"));
}
return ret;
} }
int verifyChecksum(char *mess, char *functionType, char *clientChecksum, int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg) {
MD5_CTX *c, char *msg) {
unsigned char out[MD5_DIGEST_LENGTH]; unsigned char out[MD5_DIGEST_LENGTH];
if (!MD5_Final_SLS(out, c)) { if (!MD5_Final_SLS(out, c)) {
sprintf(mess, strcpy(mess, "Unable to calculate checksum (MD5_Final_SLS)\n");
"Could not %s. Unable to calculate checksum (MD5_Final_SLS)\n",
functionType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -402,265 +283,12 @@ int verifyChecksum(char *mess, char *functionType, char *clientChecksum,
// compare checksum // compare checksum
if (strcmp(clientChecksum, checksum)) { if (strcmp(clientChecksum, checksum)) {
sprintf(mess, sprintf(mess,
"Could not %s. Checksum of %s does not match. Client " "Checksum of %s does not match. Client "
"checksum:%s, copied checksum:%s. Please try again before " "checksum:%s, copied checksum:%s\n",
"rebooting.\n", msg, clientChecksum, checksum);
functionType, msg, clientChecksum, checksum);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
LOG(logINFO, ("\tChecksum of %s verified\n", msg)); LOG(logINFO, ("\tChecksum verified\n"));
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
const int fileNameSize = 128;
char linkname[fileNameSize];
if (getAbsPath(linkname, fileNameSize, LINKED_SERVER_NAME) == FAIL) {
sprintf(
mess,
"Could not copy detector server. Could not get abs path of current "
"process\n");
LOG(logERROR, (mess));
return FAIL;
}
if (snprintf(cmd, MAX_STR_LENGTH, "ln -sf %s %s", sname, linkname) >=
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)
#ifndef VIRTUAL
#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",
linkname) >= 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
#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;
}
int createEmptyFile(char *mess, char *fname, char *errorPrefix) {
const int fileNameSize = 128;
char fullname[fileNameSize];
if (getAbsPath(fullname, fileNameSize, fname) == FAIL) {
sprintf(mess,
"Could not %s. Could not get abs path of current "
"process\n",
errorPrefix);
LOG(logERROR, (mess));
return FAIL;
}
char cmd[MAX_STR_LENGTH] = {0};
char retvals[MAX_STR_LENGTH] = {0};
if (snprintf(cmd, MAX_STR_LENGTH, "touch %s", fullname) >= MAX_STR_LENGTH) {
sprintf(mess, "Could not %s. Command to create is too long\n",
errorPrefix);
LOG(logERROR, (mess));
return FAIL;
}
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not %s. (creating empty file %s): %s\n", errorPrefix,
fullname, retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tEmpty file created: %s (%s)\n", fullname, errorPrefix));
return OK;
}
int deleteFile(char *mess, char *fname, char *errorPrefix) {
const int fileNameSize = 128;
char fullname[fileNameSize];
if (getAbsPath(fullname, fileNameSize, fname) == FAIL) {
sprintf(mess,
"Could not %s. Could not get abs path of current "
"process\n",
errorPrefix);
LOG(logERROR, (mess));
return FAIL;
}
if (access(fullname, F_OK) == 0) {
char cmd[MAX_STR_LENGTH] = {0};
char retvals[MAX_STR_LENGTH] = {0};
if (snprintf(cmd, MAX_STR_LENGTH, "rm %s", fullname) >=
MAX_STR_LENGTH) {
sprintf(mess, "Could not %s. Command to delete is too long\n",
errorPrefix);
LOG(logERROR, (mess));
return FAIL;
}
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not %s. (deleting file %s). %s\n", errorPrefix,
fullname, retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tDeleted file: %s (%s)\n", fullname, errorPrefix));
} else {
LOG(logINFO,
("\tFile does not exist anyway: %s (%s)\n", fullname, errorPrefix));
}
return OK; return OK;
} }

View File

@ -7,8 +7,10 @@
#include "sls/ansi.h" #include "sls/ansi.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include <fcntl.h> // open #include <fcntl.h> // open
#include <sys/mman.h> // mmap #include <string.h>
#include <sys/mman.h> // mmap
#include <sys/utsname.h> // uname
/* global variables */ /* global variables */
u_int32_t *csp0base = 0; u_int32_t *csp0base = 0;
@ -130,3 +132,49 @@ int mapCSP0(void) {
} }
u_int32_t *Nios_getBaseAddress() { return csp0base; } u_int32_t *Nios_getBaseAddress() { return csp0base; }
int Nios_checkKernelVersion(char *expectedVersion) {
// extract kernel date string
struct utsname buf;
if (uname(&buf) == -1) {
LOG(logERROR, ("Could not get kernel version\n"));
return FAIL;
}
// remove first word (#version number)
const char *ptr = strchr(buf.version, ' ');
if (ptr == NULL) {
LOG(logERROR, ("Could not parse kernel version\n"));
return FAIL;
}
char output[256];
memset(output, 0, 256);
strcpy(output, buf.version + (ptr - buf.version + 1));
// convert kernel date string into time
time_t kernelDate;
if (GetTimeFromString(output, &kernelDate) == FAIL) {
LOG(logERROR, ("Could not parse retrieved kernel date, %s\n", output));
return FAIL;
}
// convert expected date into time
time_t expDate;
if (GetTimeFromString(expectedVersion, &expDate) == FAIL) {
LOG(logERROR,
("Could not parse expected kernel date, %s\n", expectedVersion));
return FAIL;
}
// compare if kernel time is older than expected time
if (kernelDate < expDate) {
LOG(logERROR, ("Kernel Version Incompatible (too old)! Expected: [%s], "
"Got [%s]\n",
expectedVersion, output));
return FAIL;
}
LOG(logINFOBLUE, ("Kernel Version Compatible: %s [min.: %s]\n", output,
expectedVersion));
return OK;
}

View File

@ -0,0 +1,381 @@
// 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);
void defineGPIOpins() {
#ifdef VIRTUAL
return;
#endif
if (!gpioDefined) {
// define the gpio pins
system("echo 7 > /sys/class/gpio/export");
system("echo 9 > /sys/class/gpio/export");
// define their direction
system("echo in > /sys/class/gpio/gpio7/direction");
system("echo out > /sys/class/gpio/gpio9/direction");
LOG(logINFO, ("gpio pins defined\n"));
gpioDefined = 1;
} else
LOG(logDEBUG1, ("gpio pins already defined earlier\n"));
}
void FPGAdontTouchFlash() {
#ifdef VIRTUAL
return;
#endif
// tell FPGA to not touch flash
system("echo 0 > /sys/class/gpio/gpio9/value");
// usleep(100*1000);
}
void FPGATouchFlash() {
#ifdef VIRTUAL
return;
#endif
// tell FPGA to touch flash to program itself
system("echo 1 > /sys/class/gpio/gpio9/value");
}
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 a consistent way to read from bfin flash
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;
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
#include "programViaNios.h" #include "programFpgaNios.h"
#include "clogger.h" #include "clogger.h"
#include "common.h" #include "common.h"
#include "sls/ansi.h" #include "sls/ansi.h"
@ -11,19 +11,10 @@
/* global variables */ /* global variables */
#define CMD_GET_FPGA_FLASH_DRIVE \ #define CMD_GET_FLASH "awk \'$5== \"Application\" {print $1}\' /proc/mtd"
"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 #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}; char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
#endif
char messageType[SHORT_STR_LENGTH] = {0};
#define MICROCONTROLLER_FILE "/dev/ttyAL0" #define MICROCONTROLLER_FILE "/dev/ttyAL0"
extern int executeCommand(char *command, char *result, enum TLogLevel level); extern int executeCommand(char *command, char *result, enum TLogLevel level);
@ -44,19 +35,19 @@ void rebootControllerAndFPGA() {
system(command); system(command);
} }
int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index, int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
char *functionType, char *checksum, char *fpgasrc,
uint64_t fsize) { uint64_t fsize) {
memset(messageType, 0, sizeof(messageType)); if (verifyChecksumFromBuffer(mess, checksum, fpgasrc, fsize) == FAIL) {
strcpy(messageType, functionType); return FAIL;
}
if (getDrive(mess, index) == FAIL) { if (getDrive(mess) == FAIL) {
return FAIL; return FAIL;
} }
FILE *flashfd = NULL; FILE *flashfd = NULL;
if (openFileForFlash(mess, &flashfd) == FAIL) { if (openFileForFlash(&flashfd, mess) == FAIL) {
return FAIL; return FAIL;
} }
@ -65,33 +56,21 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
return FAIL; return FAIL;
} }
if (writeToFlash(mess, fsize, flashfd, fpgasrc) == FAIL) { if (writeToFlash(fsize, flashfd, fpgasrc, mess) == FAIL) {
return FAIL; return FAIL;
} }
/* ignoring this until a consistent way to read from nios flash
/* remove condition when flash fpga fixed */ if (verifyChecksumFromFlash(mess, checksum, flashDriveName, fsize) ==
if (index == PROGRAM_KERNEL) { FAIL) {
if (verifyChecksumFromFlash(mess, messageType, checksum, flashDriveName, return FAIL;
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; return OK;
} }
int getDrive(char *mess, enum PROGRAM_INDEX index) { int getDrive(char *mess) {
#ifdef VIRTUAL #ifdef VIRTUAL
strcpy(flashDriveName, "/tmp/SLS_mtd3");
return OK; return OK;
#endif #endif
LOG(logDEBUG1, ("Finding flash drive...\n")); LOG(logDEBUG1, ("Finding flash drive...\n"));
@ -107,33 +86,18 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) {
char cmd[MAX_STR_LENGTH] = {0}; char cmd[MAX_STR_LENGTH] = {0};
char retvals[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) { if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not %s. (could not get flash drive: %s)\n", messageType, "Could not program fpga. (could not get flash drive: %s)\n",
retvals); retvals);
// LOG(logERROR, (mess)); already printed in executecommand // LOG(logERROR, (mess)); already printed in executecommand
return FAIL; 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, ":"); char *pch = strtok(retvals, ":");
if (pch == NULL) { if (pch == NULL) {
sprintf( strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n");
mess,
"Could not %s. Could not get mtd drive to flash (strtok fail).\n",
messageType);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -145,12 +109,11 @@ int getDrive(char *mess, enum PROGRAM_INDEX index) {
return OK; return OK;
} }
int openFileForFlash(char *mess, FILE **flashfd) { int openFileForFlash(FILE **flashfd, char *mess) {
*flashfd = fopen(flashDriveName, "w"); *flashfd = fopen(flashDriveName, "w");
if (*flashfd == NULL) { if (*flashfd == NULL) {
sprintf(mess, sprintf(mess, "Unable to open flash drive %s in write mode\n",
"Could not %s. Unable to open flash drive %s in write mode\n", flashDriveName);
messageType, flashDriveName);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
@ -167,16 +130,17 @@ int eraseFlash(char *mess) {
char cmd[MAX_STR_LENGTH] = {0}; char cmd[MAX_STR_LENGTH] = {0};
char retvals[MAX_STR_LENGTH] = {0}; char retvals[MAX_STR_LENGTH] = {0};
if (snprintf(cmd, MAX_STR_LENGTH, "flash_erase %s 0 0", flashDriveName) >= char *format = "flash_erase %s 0 0";
if (snprintf(cmd, MAX_STR_LENGTH, format, flashDriveName) >=
MAX_STR_LENGTH) { MAX_STR_LENGTH) {
sprintf(mess, "Could not %s. Command to erase flash is too long\n", strcpy(mess,
messageType); "Could not program fpga. Command to erase flash is too long\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not %s. (could not erase flash: %s)\n", messageType, "Could not program fpga. (could not erase flash: %s)\n",
retvals); retvals);
// LOG(logERROR, (mess)); already printed in executecommand // LOG(logERROR, (mess)); already printed in executecommand
return FAIL; return FAIL;
@ -186,20 +150,19 @@ int eraseFlash(char *mess) {
return OK; return OK;
} }
int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, char *buffer) { int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess) {
LOG(logINFO, ("\tWriting to Flash...\n")); LOG(logINFO, ("\tWriting to Flash...\n"));
ssize_t bytesWritten = fwrite((void *)buffer, sizeof(char), fsize, flashfd); ssize_t bytesWritten = fwrite((void *)buffer, sizeof(char), fsize, flashfd);
if (bytesWritten != fsize) { if (bytesWritten != fsize) {
fclose(flashfd); fclose(flashfd);
sprintf(mess, sprintf(mess,
"Could not %s. Incorrect bytes written to flash %lu " "Could not program fpga. Incorrect bytes written to flash %lu "
"[expected: %lu]\n", "[expected: %lu]\n",
messageType, (long int)bytesWritten, (long int)fsize); (long int)bytesWritten, (long int)fsize);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
fclose(flashfd); LOG(logINFO, ("\tWritten to Flash\n"));
LOG(logINFO, ("\tWrote %ld bytes to flash\n", bytesWritten));
return OK; return OK;
} }

View File

@ -1,616 +0,0 @@
// 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 CMD_GET_AMD_FLASH "dmesg | grep Amd"
#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) {
#ifdef VIRTUAL
return OK;
#else
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;
#endif
}
int allowUpdate(char *mess, char *functionType) {
LOG(logINFO, ("\tVerifying %s allowed...\n", functionType));
#ifdef VIRTUAL
return OK;
#endif
char retvals[MAX_STR_LENGTH] = {0};
if (executeCommand(CMD_GET_AMD_FLASH, retvals, logDEBUG1) == FAIL) {
// no amd found
if (strstr(retvals, "No result") != NULL) {
LOG(logINFO, ("\tNot Amd Flash\n"));
return OK;
}
// could not figure out if amd
snprintf(
mess, MAX_STR_LENGTH,
"Could not update %s. (Could not figure out if Amd flash: %s)\n",
functionType, retvals);
LOG(logERROR, (mess));
return FAIL;
}
// amd, only current kernel works with amd flash
if (validateKernelVersion(KERNEL_DATE_VRSN_3GPIO) == FAIL) {
getKernelVersion(retvals);
snprintf(mess, MAX_STR_LENGTH,
"Could not update %s. Kernel version %s is too old to "
"update the Amd flash/ root directory. Most likely, blackfin needs rescue or replacement. Please contact us.\n",
functionType, retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tAmd flash with compatible kernel version\n"));
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;
}

View File

@ -4,7 +4,6 @@
The port number is passed as an argument */ The port number is passed as an argument */
#include "clogger.h" #include "clogger.h"
#include "common.h"
#include "communication_funcs.h" #include "communication_funcs.h"
#include "sharedMemory.h" #include "sharedMemory.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
@ -151,7 +150,7 @@ int main(int argc, char *argv[]) {
break; break;
case 'u': case 'u':
LOG(logINFO, ("Detected update mode from command line\n")); LOG(logINFO, ("Detected update mode\n"));
updateFlag = 1; updateFlag = 1;
break; break;
@ -186,24 +185,6 @@ int main(int argc, char *argv[]) {
if (sharedMemory_create(portno) == FAIL) { if (sharedMemory_create(portno) == FAIL) {
return -1; return -1;
} }
if (updateFlag == 0) {
// update flag if update file exists (command line arg overwrites)
const int fileNameSize = 128;
char fname[fileNameSize];
if (getAbsPath(fname, fileNameSize, UPDATE_FILE) == FAIL) {
LOG(logERROR,
("Could not get abs path to check if update file exists. "
"Will try current folder instead.\n"));
strcpy(fname, UPDATE_FILE);
}
if (access(fname, F_OK) == 0) {
updateFlag = 1;
LOG(logINFOBLUE, ("File Found: Update Mode enabled\n"));
} else {
LOG(logINFOBLUE, ("File not Found: Update Mode diabled\n"));
}
}
#ifdef STOP_SERVER #ifdef STOP_SERVER
// start stop server process // start stop server process
char cmd[MAX_STR_LENGTH]; char cmd[MAX_STR_LENGTH];
@ -212,7 +193,7 @@ int main(int argc, char *argv[]) {
memset(portCmd, 0, 256); memset(portCmd, 0, 256);
sprintf(portCmd, "-p%d", portno); sprintf(portCmd, "-p%d", portno);
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
LOG(logDEBUG, ("i:%d argv[i]:%s\n", i, argv[i])); LOG(logINFOBLUE, ("i:%d argv[i]:%s\n", i, argv[i]));
// remove port argument (--port) and [value] // remove port argument (--port) and [value]
if (!strcasecmp(argv[i], "--port")) { if (!strcasecmp(argv[i], "--port")) {
++i; ++i;

View File

@ -77,42 +77,6 @@ char scanErrMessage[MAX_STR_LENGTH] = "";
/* initialization functions */ /* initialization functions */
int updateModeAllowedFunction(int file_des) {
unsigned int listsize = 19;
enum detFuncs list[] = {F_EXEC_COMMAND,
F_GET_DETECTOR_TYPE,
F_GET_FIRMWARE_VERSION,
F_GET_SERVER_VERSION,
F_GET_SERIAL_NUMBER,
F_WRITE_REGISTER,
F_READ_REGISTER,
F_LOCK_SERVER,
F_GET_LAST_CLIENT_IP,
F_PROGRAM_FPGA,
F_RESET_FPGA,
F_CHECK_VERSION,
F_COPY_DET_SERVER,
F_REBOOT_CONTROLLER,
F_GET_KERNEL_VERSION,
F_UPDATE_KERNEL,
F_UPDATE_DETECTOR_SERVER,
F_GET_UPDATE_MODE,
F_SET_UPDATE_MODE};
for (unsigned int i = 0; i < listsize; ++i) {
if ((unsigned int)fnum == list[i]) {
return OK;
}
}
ret = FAIL;
sprintf(mess,
"Funcion (%s) cannot be executed in update mode. Please disable "
"update mode to continue.\n",
getFunctionNameFromEnum((enum detFuncs)fnum));
LOG(logERROR, (mess));
Server_SendResult(file_des, INT32, NULL, 0);
return FAIL;
}
int printSocketReadError() { int printSocketReadError() {
LOG(logERROR, ("Error reading from socket. Possible socket crash.\n")); LOG(logERROR, ("Error reading from socket. Possible socket crash.\n"));
return FAIL; return FAIL;
@ -128,13 +92,14 @@ void init_detector() {
#ifdef EIGERD #ifdef EIGERD
udpDetails[0].dstport2 = DEFAULT_UDP_DST_PORTNO + 1; udpDetails[0].dstport2 = DEFAULT_UDP_DST_PORTNO + 1;
#endif #endif
lockStatus = 0;
if (isControlServer) { if (isControlServer) {
basictests(); basictests();
initControlServer(); initControlServer();
} else { } else
initStopServer(); initStopServer();
} strcpy(mess, "dummy message");
lockStatus = 0;
} }
int decode_function(int file_des) { int decode_function(int file_des) {
@ -153,13 +118,6 @@ int decode_function(int file_des) {
LOG(logERROR, ("Unknown function enum %d\n", fnum)); LOG(logERROR, ("Unknown function enum %d\n", fnum));
ret = (M_nofunc)(file_des); ret = (M_nofunc)(file_des);
} else { } else {
// udpate mode restricted functions, send error (without waitin for
// arguments)
if (updateFlag && updateModeAllowedFunction(file_des) == FAIL) {
return FAIL;
}
LOG(logDEBUG1, (" calling function fnum=%d, (%s)\n", fnum, LOG(logDEBUG1, (" calling function fnum=%d, (%s)\n", fnum,
getFunctionNameFromEnum((enum detFuncs)fnum))); getFunctionNameFromEnum((enum detFuncs)fnum)));
ret = (*flist[fnum])(file_des); ret = (*flist[fnum])(file_des);
@ -456,12 +414,6 @@ void function_table() {
flist[F_SET_UDP_FIRST_DEST] = &set_udp_first_dest; flist[F_SET_UDP_FIRST_DEST] = &set_udp_first_dest;
flist[F_GET_READOUT_SPEED] = &get_readout_speed; flist[F_GET_READOUT_SPEED] = &get_readout_speed;
flist[F_SET_READOUT_SPEED] = &set_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;
flist[F_GET_UPDATE_MODE] = &get_update_mode;
flist[F_SET_UPDATE_MODE] = &set_update_mode;
// check // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
LOG(logERROR, ("The last detector function enum has reached its " LOG(logERROR, ("The last detector function enum has reached its "
@ -490,9 +442,6 @@ void modeNotImplemented(char *modename, int mode) {
} }
int executeCommand(char *command, char *result, enum TLogLevel level) { int executeCommand(char *command, char *result, enum TLogLevel level) {
ret = OK;
memset(mess, 0, sizeof(mess));
const size_t tempsize = 256; const size_t tempsize = 256;
char temp[tempsize]; char temp[tempsize];
memset(temp, 0, tempsize); memset(temp, 0, tempsize);
@ -517,26 +466,29 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
memset(temp, 0, tempsize); memset(temp, 0, tempsize);
} }
result[MAX_STR_LENGTH - 1] = '\0'; result[MAX_STR_LENGTH - 1] = '\0';
if (strlen(result) == 0) {
strcpy(result, "No result");
}
int retval = OK;
int success = pclose(sysFile); int success = pclose(sysFile);
if (success) { if (strlen(result)) {
retval = FAIL; if (success) {
LOG(logERROR, ("Executing cmd[%s]:%s\n", cmd, result)); success = FAIL;
LOG(logERROR, ("%s\n", result));
} else {
LOG(level, ("Result:\n[%s]\n", result));
}
} else { } else {
LOG(level, ("Result:\n[%s]\n", result)); LOG(level, ("No result\n"));
} }
return success;
return retval;
} }
int M_nofunc(int file_des) { int M_nofunc(int file_des) {
ret = FAIL; ret = FAIL;
memset(mess, 0, sizeof(mess)); 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", sprintf(mess, "Unrecognized Function enum %d. Please do not proceed.\n",
fnum); fnum);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@ -1607,8 +1559,15 @@ 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 // only set
if (ret == OK && Server_VerifyLock() == OK) { else if (Server_VerifyLock() == OK) {
// check index // check index
// setsettings // setsettings
@ -3680,10 +3639,149 @@ int program_fpga(int file_des) {
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
#if defined(EIGERD) || defined(GOTTHARDD) #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(); functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0);
#else #else
receive_program(file_des, PROGRAM_FPGA); // 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"));
}
#endif #endif
return ret; return ret;
} }
@ -3701,25 +3799,9 @@ int reset_fpga(int file_des) {
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
if (isControlServer) { if (isControlServer) {
basictests(); // mapping of control server at least basictests(); // mapping of control server at least
char *message = NULL; initControlServer();
if (getInitResult(&message) == FAIL) { } else
ret = FAIL;
strcpy(mess, message);
LOG(logERROR, (mess));
} else {
initControlServer();
}
} else {
initStopServer(); // remapping of stop server initStopServer(); // remapping of stop server
}
if (ret == OK) {
char *message = NULL;
if (getInitResult(&message) == FAIL) {
ret = FAIL;
strcpy(mess, message);
LOG(logERROR, (mess));
}
}
} }
#endif #endif
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
@ -4143,32 +4225,112 @@ int copy_detector_server(int file_des) {
LOG(logINFOBLUE, ("Copying server %s from host %s\n", sname, hostname)); LOG(logINFOBLUE, ("Copying server %s from host %s\n", sname, hostname));
char cmd[MAX_STR_LENGTH] = {0}; char cmd[MAX_STR_LENGTH] = {0};
#ifdef BLACKFIN_DEFINED
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, "copy detector server");
#endif
// tftp server // tftp server
char *format = "tftp %s -r %s -g";
if (snprintf(cmd, MAX_STR_LENGTH, format, hostname, sname) >=
MAX_STR_LENGTH) {
ret = FAIL;
strcpy(mess, "Could not copy detector server. Command to copy "
"server 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 (tftp). %s\n", retvals);
// LOG(logERROR, (mess)); already printed in executecommand
} else {
LOG(logINFO, ("\tServer copied\n"));
}
// give permissions
if (ret == OK) { if (ret == OK) {
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname, if (snprintf(cmd, MAX_STR_LENGTH, "chmod 777 %s", sname) >=
sname) >= MAX_STR_LENGTH) { MAX_STR_LENGTH) {
ret = FAIL; ret = FAIL;
strcpy(mess, "Could not copy detector server. Command to copy " strcpy(mess, "Could not copy detector server. Command to give "
"server too long\n"); "permissions to server is too long\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) { } else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
ret = FAIL; ret = FAIL;
snprintf(mess, MAX_STR_LENGTH, snprintf(mess, MAX_STR_LENGTH,
"Could not copy detector server (tftp). %s\n", "Could not copy detector server (permissions). %s\n",
retvals); retvals);
// LOG(logERROR, (mess)); already printed in executecommand // LOG(logERROR, (mess)); already printed in executecommand
} else { } else {
LOG(logINFO, ("\tServer copied\n")); LOG(logINFO, ("\tPermissions modified\n"));
} }
} }
// symbolic link
if (ret == OK) { if (ret == OK) {
ret = setupDetectorServer(mess, sname); 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"));
}
} }
} }
#endif #endif
@ -4663,13 +4825,6 @@ int set_read_n_rows(int file_des) {
"of %d\n", "of %d\n",
arg, READ_N_ROWS_MULTIPLE); arg, READ_N_ROWS_MULTIPLE);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
}
// only for HW 2.0 (version = 3)
else if (isHardwareVersion2()) {
ret = FAIL;
strcpy(mess, "Could not set number of rows. Only available for "
"Hardware Board version 2.0.\n");
LOG(logERROR, (mess));
} else } else
#endif #endif
{ {
@ -4705,10 +4860,11 @@ int get_read_n_rows(int file_des) {
#if !defined(EIGERD) && !defined(JUNGFRAUD) #if !defined(EIGERD) && !defined(JUNGFRAUD)
functionNotImplemented(); functionNotImplemented();
#else #else
// get only
retval = getReadNRows(); retval = getReadNRows();
if (retval == -1) { if (retval == -1) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Could not get number of rows. \n"); sprintf(mess, "Could not get numbr of rows. \n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
LOG(logDEBUG1, ("number of rows retval: %u\n", retval)); LOG(logDEBUG1, ("number of rows retval: %u\n", retval));
@ -8681,16 +8837,8 @@ int get_flip_rows(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// get only // get only
// only for HW 2.0 (version = 3) retval = getFlipRows();
if (isHardwareVersion2()) { LOG(logDEBUG1, ("flip rows retval: %u\n", retval));
ret = FAIL;
strcpy(mess, "Could not get flip rows. Only available for "
"Hardware Board version 2.0.\n");
LOG(logERROR, (mess));
} else {
retval = getFlipRows();
LOG(logDEBUG1, ("flip rows retval: %u\n", retval));
}
#endif #endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }
@ -8749,16 +8897,8 @@ int get_num_filter_cells(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// get only // get only
// only for chipv1.1 retval = getNumberOfFilterCells();
if (getChipVersion() == 10) { LOG(logDEBUG1, ("num filter cells retval: %u\n", retval));
ret = FAIL;
strcpy(mess, "Could not get number of filter cells. Only available for "
"chip version 1.1\n");
LOG(logERROR, (mess));
} else {
retval = getNumberOfFilterCells();
LOG(logDEBUG1, ("num filter cells retval: %u\n", retval));
}
#endif #endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }
@ -9270,388 +9410,5 @@ int set_readout_speed(int file_des) {
} }
} }
#endif #endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
int get_kernel_version(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
char retvals[MAX_STR_LENGTH];
memset(retvals, 0, MAX_STR_LENGTH);
LOG(logDEBUG1, ("Getting kernel version\n"));
// get only
ret = getKernelVersion(retvals);
if (ret == FAIL) {
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));
}
// in same folder as current process (will also work for virtual then
// with write permissions)
{
const int fileNameSize = 128;
char fname[fileNameSize];
if (getAbsPath(fname, fileNameSize, serverName) == FAIL) {
ret = FAIL;
sprintf(mess,
"Could not %s. Could not get abs path of current "
"process\n",
functionType);
LOG(logERROR, (mess));
Server_SendResult(file_des, INT32, NULL, 0);
} else {
strcpy(serverName, fname);
}
}
if (ret == OK) {
#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
// only when writing to kernel flash or root directory
if (index != PROGRAM_FPGA) {
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, functionType);
if (ret == FAIL) {
Server_SendResult(file_des, INT32, NULL, 0);
return;
}
}
// 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
if (ret == OK) {
ret = moveBinaryFile(mess, serverName, TEMP_PROG_FILE_NAME,
"update detector server");
}
if (ret == OK) {
ret = verifyChecksumFromFile(mess, functionType, checksum,
serverName);
}
if (ret == OK) {
ret = setupDetectorServer(mess, serverName);
}
break;
#endif
default:
modeNotImplemented("Program index", (int)index);
break;
}
// send result
Server_SendResult(file_des, INT32, NULL, 0);
// free resources
free(src);
#endif
}
int get_update_mode(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting update mode\n"));
retval = updateFlag;
LOG(logDEBUG1, ("update mode retval: %d\n", retval));
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_update_mode(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = -1;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logDEBUG1, ("Setting update mode to \n", arg));
#ifdef BLACKFIN_DEFINED
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, "set/unset update mode");
#endif
if (ret == OK) {
switch (arg) {
case 0:
ret = deleteFile(mess, UPDATE_FILE, "unset update mode");
break;
case 1:
ret = createEmptyFile(mess, UPDATE_FILE, "set update mode");
break;
default:
ret = FAIL;
sprintf(mess, "Could not set updatemode. Options: 0 or 1\n");
LOG(logERROR, (mess));
break;
}
}
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
} }

View File

@ -9,16 +9,16 @@ set(SOURCES
src/Pattern.cpp src/Pattern.cpp
) )
add_library(slsDetectorObject OBJECT add_library(slsDetectorStatic STATIC
${SOURCES} ${SOURCES}
) )
target_include_directories(slsDetectorObject PUBLIC target_include_directories(slsDetectorStatic PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
) )
target_link_libraries(slsDetectorObject target_link_libraries(slsDetectorStatic
PUBLIC PUBLIC
slsProjectOptions slsProjectOptions
slsSupportStatic slsSupportStatic
@ -28,7 +28,7 @@ target_link_libraries(slsDetectorObject
slsProjectWarnings slsProjectWarnings
) )
set(DETECTOR_LIBRARY_TARGETS slsDetectorObject) set(DETECTOR_LIBRARY_TARGETS slsDetectorStatic)
set(PUBLICHEADERS set(PUBLICHEADERS
@ -39,29 +39,29 @@ set(PUBLICHEADERS
) )
#Shared library #Shared library
if(SLS_BUILD_SHARED_LIBRARIES) # if(SLS_BUILD_SHARED_LIBRARIES)
add_library(slsDetectorShared SHARED $<TARGET_OBJECTS:slsDetectorObject>) # add_library(slsDetectorShared SHARED $<TARGET_OBJECTS:slsDetectorObject>)
target_link_libraries(slsDetectorShared PUBLIC slsDetectorObject) # target_link_libraries(slsDetectorShared PUBLIC slsDetectorObject)
set_target_properties(slsDetectorShared PROPERTIES # set_target_properties(slsDetectorShared PROPERTIES
VERSION ${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH} # VERSION ${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH}
SOVERSION ${PACKAGE_VERSION_MAJOR} # SOVERSION ${PACKAGE_VERSION_MAJOR}
LIBRARY_OUTPUT_NAME SlsDetector # LIBRARY_OUTPUT_NAME SlsDetector
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin # LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}" # PUBLIC_HEADER "${PUBLICHEADERS}"
) # )
list(APPEND DETECTOR_LIBRARY_TARGETS slsDetectorShared) # list(APPEND DETECTOR_LIBRARY_TARGETS slsDetectorShared)
endif(SLS_BUILD_SHARED_LIBRARIES) # endif(SLS_BUILD_SHARED_LIBRARIES)
#Static library #Static library
add_library(slsDetectorStatic STATIC $<TARGET_OBJECTS:slsDetectorObject>) # add_library(slsDetectorStatic STATIC $<TARGET_OBJECTS:slsDetectorObject>)
target_link_libraries(slsDetectorStatic PUBLIC slsDetectorObject) # target_link_libraries(slsDetectorStatic PUBLIC slsDetectorObject)
set_target_properties(slsDetectorStatic PROPERTIES set_target_properties(slsDetectorStatic PROPERTIES
ARCHIVE_OUTPUT_NAME SlsDetectorStatic ARCHIVE_OUTPUT_NAME SlsDetectorStatic
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}" PUBLIC_HEADER "${PUBLICHEADERS}"
) )
list(APPEND DETECTOR_LIBRARY_TARGETS slsDetectorStatic) # list(APPEND DETECTOR_LIBRARY_TARGETS slsDetectorStatic)
@ -69,6 +69,9 @@ list(APPEND DETECTOR_LIBRARY_TARGETS slsDetectorStatic)
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE)
set_property(TARGET ${DETECTOR_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET ${DETECTOR_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
# set_property(TARGET slsDetectorObject PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
# set_property(TARGET slsDetectorStatic PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
# set_property(TARGET slsDetectorShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
@ -97,7 +100,7 @@ if(SLS_USE_TEXTCLIENT)
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
COMPILE_DEFINITIONS ${val2}=1 COMPILE_DEFINITIONS ${val2}=1
) )
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
set_property(TARGET ${val1} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET ${val1} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
endforeach() endforeach()

View File

@ -81,8 +81,6 @@ class Detector {
Result<int64_t> getDetectorServerVersion(Positions pos = {}) const; Result<int64_t> getDetectorServerVersion(Positions pos = {}) const;
Result<std::string> getKernelVersion(Positions pos = {}) const;
/* [Jungfrau][Gotthard][Mythen3][Gotthard2][CTB][Moench] */ /* [Jungfrau][Gotthard][Mythen3][Gotthard2][CTB][Moench] */
Result<int64_t> getSerialNumber(Positions pos = {}) const; Result<int64_t> getSerialNumber(Positions pos = {}) const;
@ -1733,8 +1731,7 @@ class Detector {
/** [Jungfrau][CTB][Moench] Advanced user Function! */ /** [Jungfrau][CTB][Moench] Advanced user Function! */
void resetFPGA(Positions pos = {}); void resetFPGA(Positions pos = {});
/** [[deprecated ("Replaced by updateDetectorServer, which does not require /** [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
* tftp")]] [Jungfrau][Eiger][Gotthard][CTB][Moench][Mythen3][Gotthard2]
* Advanced user Function! \n * Advanced user Function! \n
* Copy detector server fname from tftp folder of hostname to detector. Also * 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 * creates a symbolic link to a shorter name (without vx.x.x). Then the
@ -1745,55 +1742,22 @@ class Detector {
void copyDetectorServer(const std::string &fname, void copyDetectorServer(const std::string &fname,
const std::string &hostname, Positions pos = {}); 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 /** [Jungfrau][Gotthard][CTB][Moench][Mythen3][Gotthard2] Advanced user
* Function! */ * Function! */
void rebootController(Positions pos = {}); 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 shorter named
* server link at start up \n sname is name of detector server binary found
* on tftp folder of host pc \n hostname is name of pc to tftp from \n fname
* is programming file name with full path to it
*/
void updateFirmwareAndServer(const std::string &sname,
const std::string &hostname,
const std::string &fname, Positions pos = {});
/** /**
* Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the * Advanced user Function!\n [Jungfrau][Gotthard][CTB][Moench] Updates the
* firmware, detector server, make a soft link and then reboots detector * firmware, detector server, make a soft link and then reboots detector
* controller. \n [Mythen3][Gotthard2] Will require a script to start up the * 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 * shorter named server link at start up \n sname is name of detector
* detector server \n fname is programming file name with full path to it * server binary found on tftp folder of host pc \n hostname is name of pc
* to tftp from \n fname is programming file name with full path to it
*/ */
void updateFirmwareAndServer(const std::string &sname, void updateFirmwareAndServer(const std::string &sname,
const std::string &hostname,
const std::string &fname, Positions pos = {}); const std::string &fname, Positions pos = {});
Result<bool> getUpdateMode(Positions pos = {}) const;
/** Restarts detector server in update mode. This is useful when
* server-firmware compatibility is at its worst and server cannot start up
* normally */
void setUpdateMode(const bool updatemode, Positions pos = {});
/** Advanced user Function! \n /** Advanced user Function! \n
* Goes to stop server. Hence, can be called while calling blocking * Goes to stop server. Hence, can be called while calling blocking
* acquire(). \n [Eiger] Address is +0x100 for only left, +0x200 for only * acquire(). \n [Eiger] Address is +0x100 for only left, +0x200 for only

View File

@ -275,7 +275,7 @@ std::string CmdProxy::Versions(int action) {
if (!args.empty()) { if (!args.empty()) {
WrongNumberOfParameters(0); WrongNumberOfParameters(0);
} }
auto t = det->getFirmwareVersion(std::vector<int>{det_id}); auto t = det->getFirmwareVersion();
os << "\nDetector Type: " << OutString(det->getDetectorType()) os << "\nDetector Type: " << OutString(det->getDetectorType())
<< "\nPackage Version: " << det->getPackageVersion() << std::hex << "\nPackage Version: " << det->getPackageVersion() << std::hex
<< "\nClient Version: 0x" << det->getClientVersion(); << "\nClient Version: 0x" << det->getClientVersion();
@ -285,14 +285,10 @@ std::string CmdProxy::Versions(int action) {
os << "\nFirmware Version: " << OutStringHex(t); os << "\nFirmware Version: " << OutStringHex(t);
} }
os << "\nDetector Server Version: " os << "\nDetector Server Version: "
<< OutStringHex( << OutStringHex(det->getDetectorServerVersion());
det->getDetectorServerVersion(std::vector<int>{det_id}));
os << "\nDetector Server Version: "
<< OutString(det->getKernelVersion({std::vector<int>{det_id}}));
if (det->getUseReceiverFlag().squash(true)) { if (det->getUseReceiverFlag().squash(true)) {
os << "\nReceiver Version: " os << "\nReceiver Version: "
<< OutStringHex( << OutStringHex(det->getReceiverVersion());
det->getReceiverVersion(std::vector<int>{det_id}));
} }
os << std::dec << '\n'; os << std::dec << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
@ -1434,9 +1430,8 @@ std::string CmdProxy::UDPDestinationList(int action) {
throw sls::RuntimeError("udp_dstlist must be at module level."); throw sls::RuntimeError("udp_dstlist must be at module level.");
} }
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) { if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
throw sls::RuntimeError(std::string("Invalid receiver index ") + throw sls::RuntimeError(
std::to_string(rx_id) + "Invalid receiver index to get round robin entry.");
std::string(" to set round robin entry."));
} }
auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id}); auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
@ -2853,14 +2848,11 @@ std::string CmdProxy::CopyDetectorServer(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
LOG(logWARNING) << "Deprecated! Replaced by updatedetectorserver that "
"requires no tftp.\n";
os << "[server_name (in tftp folder)] " os << "[server_name (in tftp folder)] "
"[pc_host_name]\n\t[Jungfrau][Eiger][Ctb][Moench][Mythen3][" "[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 " "server is in the pc's tftp folder. Makes a symbolic link with a "
"shorter name (without vx.x.x). Then, detector controller " "shorter name (without vx.x.x). Then, detector reboots (except "
"reboots (except "
"Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server " "Eiger).\n\t[Jungfrau][Ctb][Moench]Also changes respawn server "
"to the link, which is effective after a reboot." "to the link, which is effective after a reboot."
<< '\n'; << '\n';
@ -2878,98 +2870,30 @@ std::string CmdProxy::CopyDetectorServer(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::UpdateDetectorServer(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
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() != 1) {
WrongNumberOfParameters(1);
}
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::string CmdProxy::UpdateFirmwareAndDetectorServer(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "\n\tUsing tftp: Deprecated!! [server_name" os << "[server_name (in tftp folder)] [pc_host_name] [fname.pof (incl "
" (in tftp folder)] [pc_host_name] [fname.pof (incl full path)]" "full path)]\n\t[Jungfrau][Gotthard][CTB][Moench] Updates the "
"\n\tWithout tftp: Recommended [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 " "firmware, detector server, creates the symbolic link and then "
"reboots detector controller. \n\t\t[Mythen3][Gotthard2] will " "reboots detector controller. \n\t[Mythen3][Gotthard2] will "
"require a script to start up the shorter named server link at " "require a script to start up the shorter named server link at "
"start up. \n\t\tsname is full path name of detector server " "start up. \n\tsname is name of detector server binary found on "
"binary" "tftp folder of host pc \n\thostname is name of pc to tftp from "
"\n\t\tfname is full path of programming file" "\n\tfname is programming file name"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
throw sls::RuntimeError("Cannot get"); throw sls::RuntimeError("Cannot get");
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() != 3 && args.size() != 2) { if (args.size() != 3) {
WrongNumberOfParameters(2); WrongNumberOfParameters(3);
} }
if (args[2].find(".pof") == std::string::npos) {
int fpos = args.size() - 1; throw sls::RuntimeError("Programming file must be a pof file.");
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});
} }
det->updateFirmwareAndServer(args[0], args[1], args[2],
std::vector<int>{det_id});
os << "successful\n"; os << "successful\n";
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");

View File

@ -767,7 +767,6 @@ class CmdProxy {
{"clientversion", &CmdProxy::ClientVersion}, {"clientversion", &CmdProxy::ClientVersion},
{"firmwareversion", &CmdProxy::FirmwareVersion}, {"firmwareversion", &CmdProxy::FirmwareVersion},
{"detectorserverversion", &CmdProxy::detectorserverversion}, {"detectorserverversion", &CmdProxy::detectorserverversion},
{"kernelversion", &CmdProxy::kernelversion},
{"rx_version", &CmdProxy::rx_version}, {"rx_version", &CmdProxy::rx_version},
{"serialnumber", &CmdProxy::serialnumber}, {"serialnumber", &CmdProxy::serialnumber},
{"moduleid", &CmdProxy::moduleid}, {"moduleid", &CmdProxy::moduleid},
@ -1059,11 +1058,8 @@ class CmdProxy {
{"programfpga", &CmdProxy::ProgramFpga}, {"programfpga", &CmdProxy::ProgramFpga},
{"resetfpga", &CmdProxy::resetfpga}, {"resetfpga", &CmdProxy::resetfpga},
{"copydetectorserver", &CmdProxy::CopyDetectorServer}, {"copydetectorserver", &CmdProxy::CopyDetectorServer},
{"updatedetectorserver", &CmdProxy::UpdateDetectorServer},
{"updatekernel", &CmdProxy::UpdateKernel},
{"rebootcontroller", &CmdProxy::rebootcontroller}, {"rebootcontroller", &CmdProxy::rebootcontroller},
{"update", &CmdProxy::UpdateFirmwareAndDetectorServer}, {"update", &CmdProxy::UpdateFirmwareAndDetectorServer},
{"updatemode", &CmdProxy::updatemode},
{"reg", &CmdProxy::Register}, {"reg", &CmdProxy::Register},
{"adcreg", &CmdProxy::AdcRegister}, {"adcreg", &CmdProxy::AdcRegister},
{"setbit", &CmdProxy::BitOperations}, {"setbit", &CmdProxy::BitOperations},
@ -1186,8 +1182,6 @@ class CmdProxy {
/* Advanced */ /* Advanced */
std::string ProgramFpga(int action); std::string ProgramFpga(int action);
std::string CopyDetectorServer(int action); std::string CopyDetectorServer(int action);
std::string UpdateDetectorServer(int action);
std::string UpdateKernel(int action);
std::string UpdateFirmwareAndDetectorServer(int action); std::string UpdateFirmwareAndDetectorServer(int action);
std::string Register(int action); std::string Register(int action);
std::string AdcRegister(int action); std::string AdcRegister(int action);
@ -1212,10 +1206,6 @@ class CmdProxy {
detectorserverversion, getDetectorServerVersion, detectorserverversion, getDetectorServerVersion,
"\n\tOn-board detector server software version in format [0xYYMMDD]."); "\n\tOn-board detector server software version in format [0xYYMMDD].");
GET_COMMAND(
kernelversion, getKernelVersion,
"\n\tGet kernel version on the detector including time and date.");
GET_COMMAND_HEX(rx_version, getReceiverVersion, GET_COMMAND_HEX(rx_version, getReceiverVersion,
"\n\tReceiver version in format [0xYYMMDD]."); "\n\tReceiver version in format [0xYYMMDD].");
@ -2185,12 +2175,6 @@ class CmdProxy {
"\n\t[Jungfrau][Ctb][Moench][Gotthard][Mythen3][" "\n\t[Jungfrau][Ctb][Moench][Gotthard][Mythen3]["
"Gotthard2] Reboot controller of detector."); "Gotthard2] Reboot controller of detector.");
INTEGER_COMMAND_VEC_ID(
updatemode, getUpdateMode, setUpdateMode, StringTo<int>,
"[0|1]\n\tRestart the detector server in update mode or not. This is "
"useful when server-firmware compatibility is at its worst and server "
"cannot start up normally");
EXECUTE_SET_COMMAND( EXECUTE_SET_COMMAND(
firmwaretest, executeFirmwareTest, firmwaretest, executeFirmwareTest,
"\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb][Moench] Firmware " "\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb][Moench] Firmware "

View File

@ -9,7 +9,6 @@
#include "Module.h" #include "Module.h"
#include "sls/Pattern.h" #include "sls/Pattern.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/logger.h" #include "sls/logger.h"
#include "sls/sls_detector_defs.h" #include "sls/sls_detector_defs.h"
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
@ -88,7 +87,7 @@ void Detector::loadParameters(const std::vector<std::string> &parameters) {
for (const auto &current_line : parameters) { for (const auto &current_line : parameters) {
parser.Parse(current_line); parser.Parse(current_line);
proxy.Call(parser.command(), parser.arguments(), parser.detector_id(), proxy.Call(parser.command(), parser.arguments(), parser.detector_id(),
defs::PUT_ACTION, std::cout, parser.receiver_id()); defs::PUT_ACTION);
} }
} }
@ -118,10 +117,6 @@ Result<int64_t> Detector::getDetectorServerVersion(Positions pos) const {
return pimpl->Parallel(&Module::getDetectorServerVersion, pos); return pimpl->Parallel(&Module::getDetectorServerVersion, pos);
} }
Result<std::string> Detector::getKernelVersion(Positions pos) const {
return pimpl->Parallel(&Module::getKernelVersion, pos);
}
Result<int64_t> Detector::getSerialNumber(Positions pos) const { Result<int64_t> Detector::getSerialNumber(Positions pos) const {
return pimpl->Parallel(&Module::getSerialNumber, pos); return pimpl->Parallel(&Module::getSerialNumber, pos);
} }
@ -2134,7 +2129,6 @@ void Detector::setAdditionalJsonParameter(const std::string &key,
// Advanced // Advanced
void Detector::programFPGA(const std::string &fname, Positions pos) { void Detector::programFPGA(const std::string &fname, Positions pos) {
LOG(logINFO) << "Updating Firmware...";
std::vector<char> buffer = pimpl->readProgrammingFile(fname); std::vector<char> buffer = pimpl->readProgrammingFile(fname);
pimpl->Parallel(&Module::programFPGA, pos, buffer); pimpl->Parallel(&Module::programFPGA, pos, buffer);
rebootController(pos); rebootController(pos);
@ -2146,30 +2140,12 @@ void Detector::resetFPGA(Positions pos) {
void Detector::copyDetectorServer(const std::string &fname, void Detector::copyDetectorServer(const std::string &fname,
const std::string &hostname, Positions pos) { const std::string &hostname, Positions pos) {
LOG(logINFO) << "Updating Detector Server (via tftp)...";
pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname); pimpl->Parallel(&Module::copyDetectorServer, pos, fname, hostname);
if (getDetectorType().squash() != defs::EIGER) { if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos); 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) { void Detector::rebootController(Positions pos) {
pimpl->Parallel(&Module::rebootController, pos); pimpl->Parallel(&Module::rebootController, pos);
} }
@ -2178,34 +2154,10 @@ void Detector::updateFirmwareAndServer(const std::string &sname,
const std::string &hostname, const std::string &hostname,
const std::string &fname, const std::string &fname,
Positions pos) { 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); pimpl->Parallel(&Module::copyDetectorServer, pos, sname, hostname);
programFPGA(fname, pos); 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(sname, "Update Detector Server");
std::string filename = sls::getFileNameFromFilePath(sname);
pimpl->Parallel(&Module::updateDetectorServer, pos, buffer, filename);
programFPGA(fname, pos);
}
Result<bool> Detector::getUpdateMode(Positions pos) const {
return pimpl->Parallel(&Module::getUpdateMode, pos);
}
void Detector::setUpdateMode(const bool updatemode, Positions pos) {
pimpl->Parallel(&Module::setUpdateMode, pos, updatemode);
if (getDetectorType().squash() != defs::EIGER) {
rebootController(pos);
}
}
Result<uint32_t> Detector::readRegister(uint32_t addr, Positions pos) const { Result<uint32_t> Detector::readRegister(uint32_t addr, Positions pos) const {
return pimpl->Parallel(&Module::readRegister, pos, addr); return pimpl->Parallel(&Module::readRegister, pos, addr);
} }
@ -2284,7 +2236,7 @@ Result<sls::IpAddr> Detector::getLastClientIP(Positions pos) const {
Result<std::string> Detector::executeCommand(const std::string &value, Result<std::string> Detector::executeCommand(const std::string &value,
Positions pos) { Positions pos) {
return pimpl->Parallel(&Module::executeCommand, pos, value); return pimpl->Parallel(&Module::execCommand, pos, value);
} }
Result<int64_t> Detector::getNumberOfFramesFromStart(Positions pos) const { Result<int64_t> Detector::getNumberOfFramesFromStart(Positions pos) const {

View File

@ -12,7 +12,6 @@
#include "sls/ToString.h" #include "sls/ToString.h"
#include "sls/container_utils.h" #include "sls/container_utils.h"
#include "sls/file_utils.h"
#include "sls/network_utils.h" #include "sls/network_utils.h"
#include "sls/string_utils.h" #include "sls/string_utils.h"
@ -338,9 +337,7 @@ void DetectorImpl::updateDetectorSize() {
<< shm()->numberOfChannels.y; << shm()->numberOfChannels.y;
for (auto &module : modules) { for (auto &module : modules) {
if (module->getUpdateMode() == 0) { module->updateNumberOfModule(shm()->numberOfModule);
module->updateNumberOfModule(shm()->numberOfModule);
}
} }
} }
@ -1264,7 +1261,8 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
throw RuntimeError("programfpga not implemented for this detector"); throw RuntimeError("programfpga not implemented for this detector");
} }
LOG(logINFO) << "This can take awhile. Please be patient."; LOG(logINFO)
<< "Updating Firmware. This can take awhile. Please be patient...";
LOG(logDEBUG1) << "Programming FPGA with file name:" << fname; LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
// check if it exists // check if it exists
@ -1282,7 +1280,14 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
} }
// get srcSize to print progress // get srcSize to print progress
ssize_t srcSize = sls::getFileSize(src, "Program FPGA"); 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);
// create temp destination file // create temp destination file
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX"; char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
@ -1354,12 +1359,36 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
if (close(dst) != 0) { if (close(dst) != 0) {
throw RuntimeError("Program FPGA: Could not close destination file"); throw RuntimeError("Program FPGA: Could not close destination file");
} }
LOG(logINFO) << "File has been converted to " << destfname; LOG(logINFOBLUE) << "File has been converted to " << destfname;
// load converted file to memory // loading dst file to memory
std::vector<char> buffer = readBinaryFile(destfname, "Program FPGA"); // FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r");
// delete temporary FILE *fp = fopen(destfname, "r");
unlink(destfname); 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";
return buffer; return buffer;
} }

View File

@ -284,7 +284,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** /**
* Convert raw file * Convert raw file
* [Jungfrau][Ctb][Moench] from pof file * [Jungfrau][Ctb] from pof file
* [Mythen3][Gotthard2] from rbf file * [Mythen3][Gotthard2] from rbf file
* @param fname name of pof/rbf file * @param fname name of pof/rbf file
* @returns binary of the program * @returns binary of the program

View File

@ -94,12 +94,6 @@ int64_t Module::getDetectorServerVersion() const {
return sendToDetector<int64_t>(F_GET_SERVER_VERSION); return sendToDetector<int64_t>(F_GET_SERVER_VERSION);
} }
std::string Module::getKernelVersion() const {
char retval[MAX_STR_LENGTH]{};
sendToDetector(F_GET_KERNEL_VERSION, nullptr, retval);
return retval;
}
int64_t Module::getSerialNumber() const { int64_t Module::getSerialNumber() const {
return sendToDetector<int64_t>(F_GET_SERIAL_NUMBER); return sendToDetector<int64_t>(F_GET_SERIAL_NUMBER);
} }
@ -836,9 +830,8 @@ std::vector<uint64_t> Module::getNumMissingPackets() const {
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(F_GET_NUM_MISSING_PACKETS); client.Send(F_GET_NUM_MISSING_PACKETS);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw ReceiverError( throw RuntimeError("Receiver " + std::to_string(moduleIndex) +
"Receiver " + std::to_string(moduleIndex) + " returned error: " + client.readErrorMessage());
" returned error: " + client.readErrorMessage());
} else { } else {
auto nports = client.Receive<int>(); auto nports = client.Receive<int>();
std::vector<uint64_t> retval(nports); std::vector<uint64_t> retval(nports);
@ -1170,18 +1163,17 @@ std::string Module::getReceiverHostname() const {
} }
void Module::setReceiverHostname(const std::string &receiverIP) { void Module::setReceiverHostname(const std::string &receiverIP) {
LOG(logDEBUG1) << "Setting up Receiver hostname with " << receiverIP; LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP;
if (getRunStatus() == RUNNING) {
throw RuntimeError("Cannot set receiver hostname. Acquisition already "
"running. Stop it first.");
}
if (receiverIP == "none") { if (receiverIP == "none") {
memset(shm()->rxHostname, 0, MAX_STR_LENGTH); memset(shm()->rxHostname, 0, MAX_STR_LENGTH);
sls::strcpy_safe(shm()->rxHostname, "none"); sls::strcpy_safe(shm()->rxHostname, "none");
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
return; }
if (getRunStatus() == RUNNING) {
LOG(logWARNING) << "Acquisition already running, Stopping it.";
stopAcquisition();
} }
// start updating // start updating
@ -1530,8 +1522,8 @@ void Module::sendReceiverRateCorrections(const std::vector<int64_t> &t) {
receiver.Send(static_cast<int>(t.size())); receiver.Send(static_cast<int>(t.size()));
receiver.Send(t); receiver.Send(t);
if (receiver.Receive<int>() == FAIL) { if (receiver.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) + throw RuntimeError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + receiver.readErrorMessage()); " returned error: " + receiver.readErrorMessage());
} }
} }
@ -1786,8 +1778,8 @@ void Module::sendVetoPhoton(const int chipIndex,
client.Send(gainIndices); client.Send(gainIndices);
client.Send(values); client.Send(values);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) + throw RuntimeError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
} }
@ -1798,15 +1790,15 @@ void Module::getVetoPhoton(const int chipIndex,
client.Send(F_GET_VETO_PHOTON); client.Send(F_GET_VETO_PHOTON);
client.Send(chipIndex); client.Send(chipIndex);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) + throw RuntimeError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
auto nch = client.Receive<int>(); auto nch = client.Receive<int>();
if (nch != shm()->nChan.x) { if (nch != shm()->nChan.x) {
throw DetectorError("Could not get veto photon. Expected " + throw RuntimeError("Could not get veto photon. Expected " +
std::to_string(shm()->nChan.x) + " channels, got " + std::to_string(shm()->nChan.x) + " channels, got " +
std::to_string(nch)); std::to_string(nch));
} }
std::vector<int> gainIndices(nch); std::vector<int> gainIndices(nch);
std::vector<int> values(nch); std::vector<int> values(nch);
@ -2033,8 +2025,8 @@ void Module::getBadChannels(const std::string &fname) const {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_GET_BAD_CHANNELS); client.Send(F_GET_BAD_CHANNELS);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) + throw RuntimeError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
// receive badchannels // receive badchannels
auto nch = client.Receive<int>(); auto nch = client.Receive<int>();
@ -2090,8 +2082,8 @@ void Module::setBadChannels(const std::string &fname) {
client.Send(badchannels); client.Send(badchannels);
} }
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw DetectorError("Detector " + std::to_string(moduleIndex) + throw RuntimeError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
} }
@ -2404,8 +2396,8 @@ std::map<std::string, std::string> Module::getAdditionalJsonHeader() const {
auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort); auto client = ReceiverSocket(shm()->rxHostname, shm()->rxTCPPort);
client.Send(F_GET_ADDITIONAL_JSON_HEADER); client.Send(F_GET_ADDITIONAL_JSON_HEADER);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) + throw RuntimeError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} else { } else {
auto size = client.Receive<int>(); auto size = client.Receive<int>();
std::string buff(size, '\0'); std::string buff(size, '\0');
@ -2453,8 +2445,8 @@ void Module::setAdditionalJsonHeader(
client.Send(&buff[0], buff.size()); client.Send(&buff[0], buff.size());
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw ReceiverError("Receiver " + std::to_string(moduleIndex) + throw RuntimeError("Receiver " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
} }
@ -2487,15 +2479,14 @@ void Module::programFPGA(std::vector<char> buffer) {
case JUNGFRAU: case JUNGFRAU:
case CHIPTESTBOARD: case CHIPTESTBOARD:
case MOENCH: case MOENCH:
sendProgram(true, buffer, F_PROGRAM_FPGA, "Update Firmware"); programFPGAviaBlackfin(buffer);
break; break;
case MYTHEN3: case MYTHEN3:
case GOTTHARD2: case GOTTHARD2:
sendProgram(false, buffer, F_PROGRAM_FPGA, "Update Firmware"); programFPGAviaNios(buffer);
break; break;
default: default:
throw RuntimeError("Updating Firmware via the package is not " throw RuntimeError("Program FPGA is not implemented for this detector");
"implemented for this detector");
} }
} }
@ -2506,8 +2497,7 @@ void Module::copyDetectorServer(const std::string &fname,
char args[2][MAX_STR_LENGTH]{}; char args[2][MAX_STR_LENGTH]{};
sls::strcpy_safe(args[0], fname.c_str()); sls::strcpy_safe(args[0], fname.c_str());
sls::strcpy_safe(args[1], hostname.c_str()); sls::strcpy_safe(args[1], hostname.c_str());
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "Sending detector server " << args[0] << " from host "
<< "): Sending detector server " << args[0] << " from host "
<< args[1]; << args[1];
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_COPY_DET_SERVER); client.Send(F_COPY_DET_SERVER);
@ -2517,65 +2507,15 @@ void Module::copyDetectorServer(const std::string &fname,
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw RuntimeError(os.str());
} }
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname 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() { void Module::rebootController() {
sendToDetector(F_REBOOT_CONTROLLER); sendToDetector(F_REBOOT_CONTROLLER);
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "Controller rebooted successfully!";
<< "): Controller rebooted successfully!";
}
bool Module::getUpdateMode() const {
return sendToDetector<int>(F_GET_UPDATE_MODE);
}
void Module::setUpdateMode(const bool updatemode) {
sendToDetector(F_SET_UPDATE_MODE, static_cast<int>(updatemode), nullptr);
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Update Mode set to " << updatemode << "!";
} }
uint32_t Module::readRegister(uint32_t addr) const { uint32_t Module::readRegister(uint32_t addr) const {
@ -2653,25 +2593,11 @@ sls::IpAddr Module::getLastClientIP() const {
return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP); return sendToDetector<sls::IpAddr>(F_GET_LAST_CLIENT_IP);
} }
std::string Module::executeCommand(const std::string &cmd) { std::string Module::execCommand(const std::string &cmd) {
char arg[MAX_STR_LENGTH]{}; char arg[MAX_STR_LENGTH]{};
char retval[MAX_STR_LENGTH]{}; char retval[MAX_STR_LENGTH]{};
sls::strcpy_safe(arg, cmd.c_str()); sls::strcpy_safe(arg, cmd.c_str());
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname sendToDetector(F_EXEC_COMMAND, arg, retval);
<< "): 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; return retval;
} }
@ -3228,8 +3154,8 @@ void Module::setModule(sls_detector_module &module, bool trimbits) {
client.Send(F_SET_MODULE); client.Send(F_SET_MODULE);
sendModule(&module, client); sendModule(&module, client);
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
throw DetectorError("Module " + std::to_string(moduleIndex) + throw RuntimeError("Detector " + std::to_string(moduleIndex) +
" returned error: " + client.readErrorMessage()); " returned error: " + client.readErrorMessage());
} }
} }
@ -3475,128 +3401,193 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
return myMod; return myMod;
} }
void Module::sendProgram(bool blackfin, std::vector<char> buffer, void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
const int functionEnum, // send program from memory to detector
const std::string &functionType, LOG(logINFO) << "Sending programming binary (from pof) to module "
const std::string serverName) { << moduleIndex << " (" << shm()->hostname << ")";
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname
<< "): Sending " << functionType;
// send fnum and filesize
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(functionEnum); client.Send(F_PROGRAM_FPGA);
uint64_t filesize = buffer.size(); uint64_t filesize = buffer.size();
client.Send(filesize); client.Send(filesize);
// send checksum // checksum
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize); std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
LOG(logDEBUG1) << "Checksum:" << checksum; LOG(logDEBUG1) << "Checksum:" << checksum;
char cChecksum[MAX_STR_LENGTH] = {0}; char cChecksum[MAX_STR_LENGTH];
memset(cChecksum, 0, MAX_STR_LENGTH);
strcpy(cChecksum, checksum.c_str()); strcpy(cChecksum, checksum.c_str());
client.Send(cChecksum); client.Send(cChecksum);
// send server name // opening file fail
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) { if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw RuntimeError(os.str());
} }
// send program // sending program in parts of 2mb each
if (blackfin) { uint64_t unitprogramsize = 0;
uint64_t unitprogramsize = 0; int currentPointer = 0;
int currentPointer = 0; while (filesize > 0) {
while (filesize > 0) { unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
unitprogramsize = MAX_BLACKFIN_PROGRAM_SIZE; if (unitprogramsize > filesize) { // less than 2mb
if (unitprogramsize > filesize) { unitprogramsize = filesize;
unitprogramsize = filesize;
}
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
<< "\t filesize:" << filesize;
client.Send(&buffer[currentPointer], unitprogramsize);
if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw DetectorError(os.str());
}
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
} }
} else { LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
client.Send(buffer); << "\t filesize:" << filesize;
client.Send(&buffer[currentPointer], unitprogramsize);
if (client.Receive<int>() == FAIL) {
std::cout << '\n';
std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage();
throw RuntimeError(os.str());
}
filesize -= unitprogramsize;
currentPointer += unitprogramsize;
} }
// tmp checksum verified in detector // checksum
if (client.Receive<int>() == FAIL) { if (client.Receive<int>() == FAIL) {
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw RuntimeError(os.str());
} }
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " (" LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
<< shm()->hostname << ")"; << shm()->hostname << ")";
// simulating erasing and writing to // simulating erasing flash
if (blackfin) { {
if (functionEnum == F_PROGRAM_FPGA) { LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex
simulatingActivityinDetector("Erasing Flash", << " (" << shm()->hostname << ")";
BLACKFIN_ERASE_FLASH_TIME); printf("%d%%\r", 0);
simulatingActivityinDetector("Writing to Flash", std::cout << std::flush;
BLACKFIN_WRITE_TO_FLASH_TIME); // erasing takes 65 seconds, printing here (otherwise need threads
} // in server-unnecessary)
} else { const int ERASE_TIME = 65;
if (functionEnum == F_PROGRAM_FPGA) { int count = ERASE_TIME + 1;
simulatingActivityinDetector("Erasing Flash", while (count > 0) {
NIOS_ERASE_FLASH_TIME_FPGA); std::this_thread::sleep_for(std::chrono::seconds(1));
simulatingActivityinDetector("Writing to Flash", --count;
NIOS_WRITE_TO_FLASH_TIME_FPGA); printf("%d%%\r",
} else if (functionEnum == F_UPDATE_KERNEL) { static_cast<int>(
simulatingActivityinDetector("Erasing Flash", (static_cast<double>(ERASE_TIME - count) / ERASE_TIME) *
NIOS_ERASE_FLASH_TIME_KERNEL); 100));
simulatingActivityinDetector("Writing to Flash", std::cout << std::flush;
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) { if (client.Receive<int>() == FAIL) {
std::ostringstream os; std::ostringstream os;
os << "Module " << moduleIndex << " (" << shm()->hostname << ")" os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
<< " returned error: " << client.readErrorMessage(); << " returned error: " << client.readErrorMessage();
throw DetectorError(os.str()); throw RuntimeError(os.str());
} }
LOG(logINFO) << "Module " << moduleIndex << " (" << shm()->hostname LOG(logINFO) << "FPGA programmed successfully";
<< "): " << functionType << " successful";
} }
void Module::simulatingActivityinDetector(const std::string &functionType, void Module::programFPGAviaNios(std::vector<char> buffer) {
const int timeRequired) { LOG(logINFO) << "Sending programming binary (from rbf) to Module "
LOG(logINFO) << "(Simulating) " << functionType << " for module "
<< moduleIndex << " (" << shm()->hostname << ")"; << moduleIndex << " (" << shm()->hostname << ")";
printf("%d%%\r", 0);
std::cout << std::flush; auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
const int ERASE_TIME = timeRequired; client.Send(F_PROGRAM_FPGA);
int count = ERASE_TIME + 1; uint64_t filesize = buffer.size();
while (count > 0) { client.Send(filesize);
std::this_thread::sleep_for(std::chrono::seconds(1));
--count; // checksum
printf( std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
"%d%%\r", LOG(logDEBUG1) << "Checksum:" << checksum;
static_cast<int>( char cChecksum[MAX_STR_LENGTH];
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100)); memset(cChecksum, 0, MAX_STR_LENGTH);
std::cout << std::flush; 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 RuntimeError(os.str());
} }
printf("\n"); 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;
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");
}
// 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 RuntimeError(os.str());
}
LOG(logINFO) << "FPGA programmed successfully";
} }
} // namespace sls } // namespace sls

View File

@ -91,7 +91,6 @@ class Module : public virtual slsDetectorDefs {
int64_t getFirmwareVersion() const; int64_t getFirmwareVersion() const;
int64_t getDetectorServerVersion() const; int64_t getDetectorServerVersion() const;
std::string getKernelVersion() const;
int64_t getSerialNumber() const; int64_t getSerialNumber() const;
int getModuleId() const; int getModuleId() const;
int64_t getReceiverSoftwareVersion() const; int64_t getReceiverSoftwareVersion() const;
@ -541,12 +540,7 @@ class Module : public virtual slsDetectorDefs {
void resetFPGA(); void resetFPGA();
void copyDetectorServer(const std::string &fname, void copyDetectorServer(const std::string &fname,
const std::string &hostname); const std::string &hostname);
void updateDetectorServer(std::vector<char> buffer,
const std::string &serverName);
void updateKernel(std::vector<char> buffer);
void rebootController(); void rebootController();
bool getUpdateMode() const;
void setUpdateMode(const bool updatemode);
uint32_t readRegister(uint32_t addr) const; uint32_t readRegister(uint32_t addr) const;
uint32_t writeRegister(uint32_t addr, uint32_t val); uint32_t writeRegister(uint32_t addr, uint32_t val);
void setBit(uint32_t addr, int n); void setBit(uint32_t addr, int n);
@ -570,7 +564,7 @@ class Module : public virtual slsDetectorDefs {
bool getLockDetector() const; bool getLockDetector() const;
void setLockDetector(bool lock); void setLockDetector(bool lock);
sls::IpAddr getLastClientIP() const; sls::IpAddr getLastClientIP() const;
std::string executeCommand(const std::string &cmd); std::string execCommand(const std::string &cmd);
int64_t getNumberOfFramesFromStart() const; int64_t getNumberOfFramesFromStart() const;
int64_t getActualTime() const; int64_t getActualTime() const;
int64_t getMeasurementTime() const; int64_t getMeasurementTime() const;
@ -751,20 +745,11 @@ class Module : public virtual slsDetectorDefs {
std::string getTrimbitFilename(detectorSettings settings, int e_eV); std::string getTrimbitFilename(detectorSettings settings, int e_eV);
sls_detector_module readSettingsFile(const std::string &fname, sls_detector_module readSettingsFile(const std::string &fname,
bool trimbits = true); bool trimbits = true);
void sendProgram(bool blackfin, std::vector<char> buffer, void programFPGAviaBlackfin(std::vector<char> buffer);
const int functionEnum, const std::string &functionType, void programFPGAviaNios(std::vector<char> buffer);
const std::string serverName = "");
void simulatingActivityinDetector(const std::string &functionType,
const int timeRequired);
const int moduleIndex; const int moduleIndex;
mutable sls::SharedMemory<sharedModule> shm{0, 0}; 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 } // namespace sls

View File

@ -103,13 +103,6 @@ TEST_CASE("detectorserverversion", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("detectorserverversion", {"0"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("detectorserverversion", {"0"}, -1, PUT));
} }
TEST_CASE("kernelversion", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
REQUIRE_NOTHROW(proxy.Call("kernelversion", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("kernelversion", {"0"}, -1, PUT));
}
TEST_CASE("serialnumber", "[.cmd]") { TEST_CASE("serialnumber", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
@ -540,13 +533,7 @@ TEST_CASE("fliprows", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
bool jungfrauhw2 = false; if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) {
if (det_type == defs::JUNGFRAU &&
((det.getSerialNumber().tsquash("inconsistent serial number to test") &
0x30000) == 0x30000)) {
jungfrauhw2 = true;
}
if (det_type == defs::EIGER || jungfrauhw2) {
auto previous = det.getFlipRows(); auto previous = det.getFlipRows();
auto previous_numudp = det.getNumberofUDPInterfaces(); auto previous_numudp = det.getNumberofUDPInterfaces();
if (det_type == defs::JUNGFRAU) { if (det_type == defs::JUNGFRAU) {
@ -1557,47 +1544,32 @@ TEST_CASE("readnrows", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) {
bool jungfrauhw2 = false; auto prev_val = det.getReadNRows();
if (det_type == defs::JUNGFRAU && {
((det.getSerialNumber().tsquash( std::ostringstream oss;
"inconsistent serial number to test") & proxy.Call("readnrows", {"256"}, -1, PUT, oss);
0x30000) == 0x30000)) { REQUIRE(oss.str() == "readnrows 256\n");
jungfrauhw2 = true;
} }
if (det_type == defs::JUNGFRAU && !jungfrauhw2) { {
{ std::ostringstream oss;
std::ostringstream oss; proxy.Call("readnrows", {}, -1, GET, oss);
proxy.Call("readnrows", {}, -1, GET, oss); REQUIRE(oss.str() == "readnrows 256\n");
REQUIRE(oss.str() == "readnrows 512\n"); }
} {
} else { std::ostringstream oss;
auto prev_val = det.getReadNRows(); proxy.Call("readnrows", {"16"}, -1, PUT, oss);
{ REQUIRE(oss.str() == "readnrows 16\n");
std::ostringstream oss; }
proxy.Call("readnrows", {"256"}, -1, PUT, oss); if (det_type == defs::JUNGFRAU) {
REQUIRE(oss.str() == "readnrows 256\n"); REQUIRE_THROWS(proxy.Call("readnrows", {"7"}, -1, PUT));
} REQUIRE_THROWS(proxy.Call("readnrows", {"20"}, -1, PUT));
{ REQUIRE_THROWS(proxy.Call("readnrows", {"44"}, -1, PUT));
std::ostringstream oss; REQUIRE_THROWS(proxy.Call("readnrows", {"513"}, -1, PUT));
proxy.Call("readnrows", {}, -1, GET, oss); REQUIRE_THROWS(proxy.Call("readnrows", {"1"}, -1, PUT));
REQUIRE(oss.str() == "readnrows 256\n"); }
} REQUIRE_THROWS(proxy.Call("readnrows", {"0"}, -1, PUT));
{ for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss; det.setReadNRows(prev_val[i], {i});
proxy.Call("readnrows", {"16"}, -1, PUT, oss);
REQUIRE(oss.str() == "readnrows 16\n");
}
if (det_type == defs::JUNGFRAU) {
REQUIRE_THROWS(proxy.Call("readnrows", {"7"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("readnrows", {"20"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("readnrows", {"44"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("readnrows", {"513"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("readnrows", {"1"}, -1, PUT));
}
REQUIRE_THROWS(proxy.Call("readnrows", {"0"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setReadNRows(prev_val[i], {i});
}
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("readnrows", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("readnrows", {}, -1, GET));
@ -2026,6 +1998,8 @@ TEST_CASE("stop", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("stop", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("stop", {}, -1, GET));
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
std::chrono::nanoseconds prev_val; std::chrono::nanoseconds prev_val;
bool virtualDet =
det.isVirtualDetectorServer().tsquash("inconsistent virtual servers");
if (det_type != defs::MYTHEN3) { if (det_type != defs::MYTHEN3) {
prev_val = det.getExptime().tsquash("inconsistent exptime to test"); prev_val = det.getExptime().tsquash("inconsistent exptime to test");
} else { } else {
@ -2056,8 +2030,11 @@ TEST_CASE("stop", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("status", {}, -1, GET, oss); proxy.Call("status", {}, -1, GET, oss);
REQUIRE(((oss.str() == "status stopped\n") || if (!virtualDet && det_type == defs::JUNGFRAU) {
(oss.str() == "status idle\n"))); REQUIRE(oss.str() == "status stopped\n");
} else {
REQUIRE(oss.str() == "status idle\n");
}
} }
det.setExptime(-1, prev_val); det.setExptime(-1, prev_val);
det.setPeriod(prev_period); det.setPeriod(prev_period);
@ -2069,6 +2046,8 @@ TEST_CASE("status", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
std::chrono::nanoseconds prev_val; std::chrono::nanoseconds prev_val;
bool virtualDet =
det.isVirtualDetectorServer().tsquash("inconsistent virtual servers");
if (det_type != defs::MYTHEN3) { if (det_type != defs::MYTHEN3) {
prev_val = det.getExptime().tsquash("inconsistent exptime to test"); prev_val = det.getExptime().tsquash("inconsistent exptime to test");
} else { } else {
@ -2095,8 +2074,11 @@ TEST_CASE("status", "[.cmd]") {
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("status", {}, -1, GET, oss); proxy.Call("status", {}, -1, GET, oss);
REQUIRE(((oss.str() == "status stopped\n") || if (!virtualDet && det_type == defs::JUNGFRAU) {
(oss.str() == "status idle\n"))); REQUIRE(oss.str() == "status stopped\n");
} else {
REQUIRE(oss.str() == "status idle\n");
}
} }
det.setExptime(-1, prev_val); det.setExptime(-1, prev_val);
det.setPeriod(prev_period); det.setPeriod(prev_period);
@ -2719,25 +2701,6 @@ 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]") { TEST_CASE("rebootcontroller", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -104,7 +104,7 @@ if (SLS_USE_RECEIVER_BINARIES)
set_target_properties(slsReceiver PROPERTIES set_target_properties(slsReceiver PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
set_property(TARGET slsReceiver PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsReceiver PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
@ -124,7 +124,7 @@ if (SLS_USE_RECEIVER_BINARIES)
set_target_properties(slsMultiReceiver PROPERTIES set_target_properties(slsMultiReceiver PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
) )
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
set_property(TARGET slsMultiReceiver PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsMultiReceiver PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()

View File

@ -355,7 +355,7 @@ std::string Implementation::getFilePath() const { return filePath; }
void Implementation::setFilePath(const std::string &c) { void Implementation::setFilePath(const std::string &c) {
if (!c.empty()) { if (!c.empty()) {
sls::mkdir_p(c); // throws if it can't create mkdir_p(c); // throws if it can't create
filePath = c; filePath = c;
} }
LOG(logINFO) << "File path: " << filePath; LOG(logINFO) << "File path: " << filePath;

View File

@ -66,21 +66,21 @@ target_include_directories(md5sls
# Create an object library to avoid building the library twice # Create an object library to avoid building the library twice
add_library(slsSupportObject OBJECT add_library(slsSupportStatic STATIC
${SOURCES} ${SOURCES}
${HEADERS} ${HEADERS}
) )
target_include_directories(slsSupportObject target_include_directories(slsSupportStatic
PUBLIC PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
) )
target_link_libraries(slsSupportObject target_link_libraries(slsSupportStatic
PUBLIC PUBLIC
slsProjectOptions slsProjectOptions
libzmq # libzmq
rapidjson rapidjson
PRIVATE PRIVATE
slsProjectWarnings slsProjectWarnings
@ -92,33 +92,33 @@ if (SLS_USE_TESTS)
endif(SLS_USE_TESTS) endif(SLS_USE_TESTS)
#List of targets to support adding removing targets as config #List of targets to support adding removing targets as config
set(SUPPORT_LIBRARY_TARGETS slsSupportObject) set(SUPPORT_LIBRARY_TARGETS slsSupportStatic)
# Add shared library version of the support lib # Add shared library version of the support lib
if(SLS_BUILD_SHARED_LIBRARIES) # if(SLS_BUILD_SHARED_LIBRARIES)
add_library(slsSupportShared SHARED $<TARGET_OBJECTS:slsSupportObject>) # add_library(slsSupportShared SHARED $<TARGET_OBJECTS:slsSupportObject>)
target_link_libraries(slsSupportShared PUBLIC slsSupportObject) # target_link_libraries(slsSupportShared PUBLIC slsSupportObject)
set_target_properties(slsSupportShared PROPERTIES # set_target_properties(slsSupportShared PROPERTIES
VERSION ${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH} # VERSION ${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH}
SOVERSION ${PACKAGE_VERSION_MAJOR} # SOVERSION ${PACKAGE_VERSION_MAJOR}
LIBRARY_OUTPUT_NAME SlsSupport # LIBRARY_OUTPUT_NAME SlsSupport
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin # LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}" # PUBLIC_HEADER "${PUBLICHEADERS}"
) # )
list(APPEND SUPPORT_LIBRARY_TARGETS slsSupportShared) # list(APPEND SUPPORT_LIBRARY_TARGETS slsSupportShared)
endif(SLS_BUILD_SHARED_LIBRARIES) # endif(SLS_BUILD_SHARED_LIBRARIES)
# Add static version of the support lib # Add static version of the support lib
add_library(slsSupportStatic STATIC $<TARGET_OBJECTS:slsSupportObject>) # add_library(slsSupportStatic STATIC $<TARGET_OBJECTS:slsSupportObject>)
target_link_libraries(slsSupportStatic PUBLIC slsSupportObject) # target_link_libraries(slsSupportStatic PUBLIC slsSupportObject)
set_target_properties(slsSupportStatic PROPERTIES set_target_properties(slsSupportStatic PROPERTIES
ARCHIVE_OUTPUT_NAME SlsSupportStatic ARCHIVE_OUTPUT_NAME SlsSupportStatic
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
PUBLIC_HEADER "${PUBLICHEADERS}" PUBLIC_HEADER "${PUBLICHEADERS}"
) )
list(APPEND SUPPORT_LIBRARY_TARGETS slsSupportStatic) # list(APPEND SUPPORT_LIBRARY_TARGETS slsSupportStatic)
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE) if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE)
set_property(TARGET ${SUPPORT_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET ${SUPPORT_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)

View File

@ -8,46 +8,49 @@
#include <fstream> #include <fstream>
#include <string> #include <string>
namespace sls { /** (used by multi and sls)
* reads a short int raw data file
* @param infile input file stream
/**
* @param data array of data values * @param data array of data values
* @param nch number of channels * @param nch number of channels
* @param offset start channel value * @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 readDataFile(std::ifstream &infile, short int *data, int nch,
int offset = 0); 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 data array of data value
* @param nch number of channels * @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); int readDataFile(std::string fname, short int *data, int nch);
/** (used by multi and sls)
std::vector<char> readBinaryFile(const std::string &fname, * writes a short int raw data file
const std::string &errorPrefix); * @param outfile output file stream
/**
* @param nch number of channels * @param nch number of channels
* @param data array of data values * @param data array of data values
* @param offset start channel number * @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 writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset = 0); 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 nch number of channels
* @param data array of data values * @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); int writeDataFile(std::string fname, int nch, short int *data);
// mkdir -p path implemented by recursive calls // mkdir -p path implemented by recursive calls
void mkdir_p(const std::string &path, std::string dir = ""); void mkdir_p(const std::string &path, std::string dir = "");
namespace sls {
int getFileSize(std::ifstream &ifs); int getFileSize(std::ifstream &ifs);
ssize_t getFileSize(FILE* fd, const std::string &prependErrorString);
std::string getFileNameFromFilePath(const std::string &fpath);
} }

View File

@ -55,8 +55,9 @@
/** maximum trim en */ /** maximum trim en */
#define MAX_TRIMEN 100 #define MAX_TRIMEN 100
/** maximum unit size of program sent to blackfin */ /** maximum unit size of program sent to detector */
#define MAX_BLACKFIN_PROGRAM_SIZE (128 * 1024) //#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024)
#define MAX_FPGAPROGRAMSIZE (128 * 1024)
#define GET_FLAG -1 #define GET_FLAG -1

View File

@ -253,11 +253,6 @@ enum detFuncs {
F_SET_UDP_FIRST_DEST, F_SET_UDP_FIRST_DEST,
F_GET_READOUT_SPEED, F_GET_READOUT_SPEED,
F_SET_READOUT_SPEED, F_SET_READOUT_SPEED,
F_GET_KERNEL_VERSION,
F_UPDATE_KERNEL,
F_UPDATE_DETECTOR_SERVER,
F_GET_UPDATE_MODE,
F_SET_UPDATE_MODE,
NUM_DET_FUNCTIONS, NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
@ -613,15 +608,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_UDP_FIRST_DEST: return "F_SET_UDP_FIRST_DEST"; case F_SET_UDP_FIRST_DEST: return "F_SET_UDP_FIRST_DEST";
case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED"; case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED";
case F_SET_READOUT_SPEED: return "F_SET_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 F_GET_UPDATE_MODE: return "F_GET_UPDATE_MODE";
case F_SET_UPDATE_MODE: return "F_SET_UPDATE_MODE";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND"; case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER"; case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER";
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP"; case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";

View File

@ -1,15 +1,15 @@
// SPDX-License-Identifier: LGPL-3.0-or-other // SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package // Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */ /** API versions */
#define GITBRANCH "6.1.0" #define GITBRANCH "6.0.0"
#define APILIB 0x211125 #define APILIB 0x211021
#define APIRECEIVER 0x211125 #define APIRECEIVER 0x211020
#define APIGUI 0x211125 #define APIGUI 0x211021
#define APICTB 0x211125 #define APICTB 0x211021
#define APIGOTTHARD 0x211125 #define APIGOTTHARD 0x211021
#define APIGOTTHARD2 0x211125 #define APIGOTTHARD2 0x211021
#define APIJUNGFRAU 0x211125 #define APIJUNGFRAU 0x211021
#define APIMYTHEN3 0x211125 #define APIMYTHEN3 0x211021
#define APIMOENCH 0x211124 #define APIMOENCH 0x211021
#define APIEIGER 0x211125 #define APIEIGER 0x211021

View File

@ -10,249 +10,249 @@
#include <string.h> #include <string.h>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <zmq.h> // #include <zmq.h>
using namespace rapidjson; using namespace rapidjson;
ZmqSocket::ZmqSocket(const char *const hostname_or_ip, ZmqSocket::ZmqSocket(const char *const hostname_or_ip,
const uint32_t portnumber) const uint32_t portnumber)
: portno(portnumber), sockfd(false) { : portno(portnumber), sockfd(false) {
// Extra check that throws if conversion fails, could be removed // Extra check that throws if conversion fails, could be removed
auto ipstr = sls::HostnameToIp(hostname_or_ip).str(); // auto ipstr = sls::HostnameToIp(hostname_or_ip).str();
std::ostringstream oss; // std::ostringstream oss;
oss << "tcp://" << ipstr << ":" << portno; // oss << "tcp://" << ipstr << ":" << portno;
sockfd.serverAddress = oss.str(); // sockfd.serverAddress = oss.str();
LOG(logDEBUG) << "zmq address: " << sockfd.serverAddress; // LOG(logDEBUG) << "zmq address: " << sockfd.serverAddress;
// create context // // create context
sockfd.contextDescriptor = zmq_ctx_new(); // sockfd.contextDescriptor = zmq_ctx_new();
if (sockfd.contextDescriptor == nullptr) // if (sockfd.contextDescriptor == nullptr)
throw sls::ZmqSocketError("Could not create contextDescriptor"); // throw sls::ZmqSocketError("Could not create contextDescriptor");
// create subscriber // // create subscriber
sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_SUB); // sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_SUB);
if (sockfd.socketDescriptor == nullptr) { // if (sockfd.socketDescriptor == nullptr) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not create socket"); // throw sls::ZmqSocketError("Could not create socket");
} // }
// Socket Options provided above // // Socket Options provided above
// an empty string implies receiving any messages // // an empty string implies receiving any messages
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SUBSCRIBE, "", 0)) { // if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SUBSCRIBE, "", 0)) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could set socket opt"); // throw sls::ZmqSocketError("Could set socket opt");
} // }
// ZMQ_LINGER default is already -1 means no messages discarded. use this // // ZMQ_LINGER default is already -1 means no messages discarded. use this
// options if optimizing required ZMQ_SNDHWM default is 0 means no limit. // // options if optimizing required ZMQ_SNDHWM default is 0 means no limit.
// use this to optimize if optimizing required eg. int value = -1; // // use this to optimize if optimizing required eg. int value = -1;
const int value = 0; // const int value = 0;
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_LINGER, &value, // if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_LINGER, &value,
sizeof(value))) { // sizeof(value))) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not set ZMQ_LINGER"); // throw sls::ZmqSocketError("Could not set ZMQ_LINGER");
} // }
LOG(logDEBUG) << "Default receive high water mark:" // LOG(logDEBUG) << "Default receive high water mark:"
<< GetReceiveHighWaterMark(); // << GetReceiveHighWaterMark();
} }
ZmqSocket::ZmqSocket(const uint32_t portnumber, const char *ethip) ZmqSocket::ZmqSocket(const uint32_t portnumber, const char *ethip)
: portno(portnumber), sockfd(true) { : portno(portnumber), sockfd(true) {
// create context // create context
sockfd.contextDescriptor = zmq_ctx_new(); // sockfd.contextDescriptor = zmq_ctx_new();
if (sockfd.contextDescriptor == nullptr) // if (sockfd.contextDescriptor == nullptr)
throw sls::ZmqSocketError("Could not create contextDescriptor"); // throw sls::ZmqSocketError("Could not create contextDescriptor");
// create publisher // // create publisher
sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_PUB); // sockfd.socketDescriptor = zmq_socket(sockfd.contextDescriptor, ZMQ_PUB);
if (sockfd.socketDescriptor == nullptr) { // if (sockfd.socketDescriptor == nullptr) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not create socket"); // throw sls::ZmqSocketError("Could not create socket");
} // }
LOG(logDEBUG) << "Default send high water mark:" << GetSendHighWaterMark(); // LOG(logDEBUG) << "Default send high water mark:" << GetSendHighWaterMark();
// construct address, can be refactored with libfmt // // construct address, can be refactored with libfmt
std::ostringstream oss; // std::ostringstream oss;
oss << "tcp://" << ethip << ":" << portno; // oss << "tcp://" << ethip << ":" << portno;
sockfd.serverAddress = oss.str(); // sockfd.serverAddress = oss.str();
LOG(logDEBUG) << "zmq address: " << sockfd.serverAddress; // LOG(logDEBUG) << "zmq address: " << sockfd.serverAddress;
// bind address // // bind address
if (zmq_bind(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) { // if (zmq_bind(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not bind socket"); // throw sls::ZmqSocketError("Could not bind socket");
} // }
// sleep to allow a slow-joiner // // sleep to allow a slow-joiner
std::this_thread::sleep_for(std::chrono::milliseconds(200)); // std::this_thread::sleep_for(std::chrono::milliseconds(200));
}; };
int ZmqSocket::GetSendHighWaterMark() { int ZmqSocket::GetSendHighWaterMark() {
int value = 0; int value = 0;
size_t value_size = sizeof(value); // size_t value_size = sizeof(value);
if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_SNDHWM, &value, // if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_SNDHWM, &value,
&value_size)) { // &value_size)) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not get ZMQ_SNDHWM"); // throw sls::ZmqSocketError("Could not get ZMQ_SNDHWM");
} // }
return value; return value;
} }
void ZmqSocket::SetSendHighWaterMark(int limit) { void ZmqSocket::SetSendHighWaterMark(int limit) {
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SNDHWM, &limit, // if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_SNDHWM, &limit,
sizeof(limit))) { // sizeof(limit))) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not set ZMQ_SNDHWM"); // throw sls::ZmqSocketError("Could not set ZMQ_SNDHWM");
} // }
} }
int ZmqSocket::GetReceiveHighWaterMark() { int ZmqSocket::GetReceiveHighWaterMark() {
int value = 0; int value = 0;
size_t value_size = sizeof(value); // size_t value_size = sizeof(value);
if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &value, // if (zmq_getsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &value,
&value_size)) { // &value_size)) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not get ZMQ_SNDHWM"); // throw sls::ZmqSocketError("Could not get ZMQ_SNDHWM");
} // }
return value; return value;
} }
void ZmqSocket::SetReceiveHighWaterMark(int limit) { void ZmqSocket::SetReceiveHighWaterMark(int limit) {
if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &limit, // if (zmq_setsockopt(sockfd.socketDescriptor, ZMQ_RCVHWM, &limit,
sizeof(limit))) { // sizeof(limit))) {
PrintError(); // PrintError();
throw sls::ZmqSocketError("Could not set ZMQ_SNDHWM"); // throw sls::ZmqSocketError("Could not set ZMQ_SNDHWM");
} // }
} }
int ZmqSocket::Connect() { int ZmqSocket::Connect() {
if (zmq_connect(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) { // if (zmq_connect(sockfd.socketDescriptor, sockfd.serverAddress.c_str())) {
PrintError(); // PrintError();
return 1; // return 1;
} // }
return 0; return 0;
} }
int ZmqSocket::SendHeader(int index, zmqHeader header) { int ZmqSocket::SendHeader(int index, zmqHeader header) {
/** Json Header Format */ // /** Json Header Format */
const char jsonHeaderFormat[] = "{" // const char jsonHeaderFormat[] = "{"
"\"jsonversion\":%u, " // "\"jsonversion\":%u, "
"\"bitmode\":%u, " // "\"bitmode\":%u, "
"\"fileIndex\":%lu, " // "\"fileIndex\":%lu, "
"\"detshape\":[%u, %u], " // "\"detshape\":[%u, %u], "
"\"shape\":[%u, %u], " // "\"shape\":[%u, %u], "
"\"size\":%u, " // "\"size\":%u, "
"\"acqIndex\":%lu, " // "\"acqIndex\":%lu, "
"\"frameIndex\":%lu, " // "\"frameIndex\":%lu, "
"\"progress\":%lf, " // "\"progress\":%lf, "
"\"fname\":\"%s\", " // "\"fname\":\"%s\", "
"\"data\": %d, " // "\"data\": %d, "
"\"completeImage\": %d, " // "\"completeImage\": %d, "
"\"frameNumber\":%lu, " // "\"frameNumber\":%lu, "
"\"expLength\":%u, " // "\"expLength\":%u, "
"\"packetNumber\":%u, " // "\"packetNumber\":%u, "
"\"bunchId\":%lu, " // "\"bunchId\":%lu, "
"\"timestamp\":%lu, " // "\"timestamp\":%lu, "
"\"modId\":%u, " // "\"modId\":%u, "
"\"row\":%u, " // "\"row\":%u, "
"\"column\":%u, " // "\"column\":%u, "
"\"reserved\":%u, " // "\"reserved\":%u, "
"\"debug\":%u, " // "\"debug\":%u, "
"\"roundRNumber\":%u, " // "\"roundRNumber\":%u, "
"\"detType\":%u, " // "\"detType\":%u, "
"\"version\":%u, " // "\"version\":%u, "
// additional stuff // // additional stuff
"\"flipRows\":%u, " // "\"flipRows\":%u, "
"\"quad\":%u" // "\"quad\":%u"
; //"}\n"; // ; //"}\n";
memset(header_buffer.get(), '\0', MAX_STR_LENGTH); // TODO! Do we need this // memset(header_buffer.get(), '\0', MAX_STR_LENGTH); // TODO! Do we need this
sprintf(header_buffer.get(), jsonHeaderFormat, header.jsonversion, // sprintf(header_buffer.get(), jsonHeaderFormat, header.jsonversion,
header.dynamicRange, header.fileIndex, header.ndetx, header.ndety, // header.dynamicRange, header.fileIndex, header.ndetx, header.ndety,
header.npixelsx, header.npixelsy, header.imageSize, header.acqIndex, // header.npixelsx, header.npixelsy, header.imageSize, header.acqIndex,
header.frameIndex, header.progress, header.fname.c_str(), // header.frameIndex, header.progress, header.fname.c_str(),
header.data ? 1 : 0, header.completeImage ? 1 : 0, // header.data ? 1 : 0, header.completeImage ? 1 : 0,
header.frameNumber, header.expLength, header.packetNumber, // header.frameNumber, header.expLength, header.packetNumber,
header.bunchId, header.timestamp, header.modId, header.row, // header.bunchId, header.timestamp, header.modId, header.row,
header.column, header.reserved, header.debug, header.roundRNumber, // header.column, header.reserved, header.debug, header.roundRNumber,
header.detType, header.version, // header.detType, header.version,
// additional stuff // // additional stuff
header.flipRows, header.quad); // header.flipRows, header.quad);
if (!header.addJsonHeader.empty()) { // if (!header.addJsonHeader.empty()) {
strcat(header_buffer.get(), ", "); // strcat(header_buffer.get(), ", ");
strcat(header_buffer.get(), "\"addJsonHeader\": {"); // strcat(header_buffer.get(), "\"addJsonHeader\": {");
for (auto it = header.addJsonHeader.begin(); // for (auto it = header.addJsonHeader.begin();
it != header.addJsonHeader.end(); ++it) { // it != header.addJsonHeader.end(); ++it) {
if (it != header.addJsonHeader.begin()) { // if (it != header.addJsonHeader.begin()) {
strcat(header_buffer.get(), ", "); // strcat(header_buffer.get(), ", ");
} // }
strcat(header_buffer.get(), "\""); // strcat(header_buffer.get(), "\"");
strcat(header_buffer.get(), it->first.c_str()); // strcat(header_buffer.get(), it->first.c_str());
strcat(header_buffer.get(), "\":\""); // strcat(header_buffer.get(), "\":\"");
strcat(header_buffer.get(), it->second.c_str()); // strcat(header_buffer.get(), it->second.c_str());
strcat(header_buffer.get(), "\""); // strcat(header_buffer.get(), "\"");
} // }
strcat(header_buffer.get(), " } "); // strcat(header_buffer.get(), " } ");
} // }
strcat(header_buffer.get(), "}\n"); // strcat(header_buffer.get(), "}\n");
int length = strlen(header_buffer.get()); // int length = strlen(header_buffer.get());
#ifdef VERBOSE // #ifdef VERBOSE
// if(!index) // // if(!index)
cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf); // cprintf(BLUE, "%d : Streamer: buf: %s\n", index, buf);
#endif // #endif
if (zmq_send(sockfd.socketDescriptor, header_buffer.get(), length, // if (zmq_send(sockfd.socketDescriptor, header_buffer.get(), length,
header.data ? ZMQ_SNDMORE : 0) < 0) { // header.data ? ZMQ_SNDMORE : 0) < 0) {
PrintError(); // PrintError();
return 0; // return 0;
} // }
#ifdef VERBOSE // #ifdef VERBOSE
cprintf(GREEN, "[%u] send header data\n", portno); // cprintf(GREEN, "[%u] send header data\n", portno);
#endif // #endif
return 1; return 1;
} }
int ZmqSocket::SendData(char *buf, int length) { int ZmqSocket::SendData(char *buf, int length) {
if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) { // if (zmq_send(sockfd.socketDescriptor, buf, length, 0) < 0) {
PrintError(); // PrintError();
return 0; // return 0;
} // }
return 1; return 1;
} }
int ZmqSocket::ReceiveHeader(const int index, zmqHeader &zHeader, int ZmqSocket::ReceiveHeader(const int index, zmqHeader &zHeader,
uint32_t version) { uint32_t version) {
const int bytes_received = zmq_recv(sockfd.socketDescriptor, // const int bytes_received = zmq_recv(sockfd.socketDescriptor,
header_buffer.get(), MAX_STR_LENGTH, 0); // header_buffer.get(), MAX_STR_LENGTH, 0);
if (bytes_received > 0) { // if (bytes_received > 0) {
#ifdef ZMQ_DETAIL // #ifdef ZMQ_DETAIL
cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno, // cprintf(BLUE, "Header %d [%d] Length: %d Header:%s \n", index, portno,
bytes_received, buffer.data()); // bytes_received, buffer.data());
#endif // #endif
if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader, // if (ParseHeader(index, bytes_received, header_buffer.get(), zHeader,
version)) { // version)) {
#ifdef ZMQ_DETAIL // #ifdef ZMQ_DETAIL
cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index, // cprintf(RED, "Parsed Header %d [%d] Length: %d Header:%s \n", index,
portno, bytes_received, buffer.data()); // portno, bytes_received, buffer.data());
#endif // #endif
if (!zHeader.data) { // if (!zHeader.data) {
#ifdef ZMQ_DETAIL // #ifdef ZMQ_DETAIL
cprintf(RED, "%d [%d] Received end of acquisition\n", index, // cprintf(RED, "%d [%d] Received end of acquisition\n", index,
portno); // portno);
#endif // #endif
return 0; // return 0;
} // }
#ifdef ZMQ_DETAIL // #ifdef ZMQ_DETAIL
cprintf(GREEN, "%d [%d] data\n", index, portno); // cprintf(GREEN, "%d [%d] data\n", index, portno);
#endif // #endif
return 1; // return 1;
} // }
} // }
return 0; return 0;
}; };
@ -323,96 +323,96 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
} }
int ZmqSocket::ReceiveData(const int index, char *buf, const int size) { int ZmqSocket::ReceiveData(const int index, char *buf, const int size) {
zmq_msg_t message; // zmq_msg_t message;
zmq_msg_init(&message); // zmq_msg_init(&message);
int length = ReceiveMessage(index, message); // int length = ReceiveMessage(index, message);
if (length == size) { // if (length == size) {
memcpy(buf, (char *)zmq_msg_data(&message), size); // memcpy(buf, (char *)zmq_msg_data(&message), size);
} else if (length < size) { // } else if (length < size) {
memcpy(buf, (char *)zmq_msg_data(&message), length); // memcpy(buf, (char *)zmq_msg_data(&message), length);
memset(buf + length, 0xFF, size - length); // memset(buf + length, 0xFF, size - length);
} else { // } else {
LOG(logERROR) << "Received weird packet size " << length // LOG(logERROR) << "Received weird packet size " << length
<< " for socket " << index; // << " for socket " << index;
memset(buf, 0xFF, size); // memset(buf, 0xFF, size);
} // }
zmq_msg_close(&message); // zmq_msg_close(&message);
return length; return 1;
} }
int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) { int ZmqSocket::ReceiveMessage(const int index, zmq_msg_t &message) {
int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0); // int length = zmq_msg_recv(&message, sockfd.socketDescriptor, 0);
if (length == -1) { // if (length == -1) {
PrintError(); // PrintError();
LOG(logERROR) << "Could not read header for socket " << index; // LOG(logERROR) << "Could not read header for socket " << index;
} // }
return length; return 1;
} }
void ZmqSocket::PrintError() { void ZmqSocket::PrintError() {
switch (errno) { // switch (errno) {
case EINVAL: // case EINVAL:
LOG(logERROR) << "The socket type/option or value/endpoint supplied is " // LOG(logERROR) << "The socket type/option or value/endpoint supplied is "
"invalid (zmq)"; // "invalid (zmq)";
break; // break;
case EAGAIN: // case EAGAIN:
LOG(logERROR) << "Non-blocking mode was requested and the message " // LOG(logERROR) << "Non-blocking mode was requested and the message "
"cannot be sent/available at the moment (zmq)"; // "cannot be sent/available at the moment (zmq)";
break; // break;
case ENOTSUP: // case ENOTSUP:
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() operation is not " // LOG(logERROR) << "The zmq_send()/zmq_msg_recv() operation is not "
"supported by this socket type (zmq)"; // "supported by this socket type (zmq)";
break; // break;
case EFSM: // case EFSM:
LOG(logERROR) << "The zmq_send()/zmq_msg_recv() unavailable now as " // LOG(logERROR) << "The zmq_send()/zmq_msg_recv() unavailable now as "
"socket in inappropriate state (eg. ZMQ_REP). Look up " // "socket in inappropriate state (eg. ZMQ_REP). Look up "
"messaging patterns (zmq)"; // "messaging patterns (zmq)";
break; // break;
case EFAULT: // case EFAULT:
LOG(logERROR) << "The provided context/message is invalid (zmq)"; // LOG(logERROR) << "The provided context/message is invalid (zmq)";
break; // break;
case EMFILE: // case EMFILE:
LOG(logERROR) << "The limit on the total number of open ØMQ sockets " // LOG(logERROR) << "The limit on the total number of open ØMQ sockets "
"has been reached (zmq)"; // "has been reached (zmq)";
break; // break;
case EPROTONOSUPPORT: // case EPROTONOSUPPORT:
LOG(logERROR) // LOG(logERROR)
<< "The requested transport protocol is not supported (zmq)"; // << "The requested transport protocol is not supported (zmq)";
break; // break;
case ENOCOMPATPROTO: // case ENOCOMPATPROTO:
LOG(logERROR) << "The requested transport protocol is not compatible " // LOG(logERROR) << "The requested transport protocol is not compatible "
"with the socket type (zmq)"; // "with the socket type (zmq)";
break; // break;
case EADDRINUSE: // case EADDRINUSE:
LOG(logERROR) << "The requested address is already in use (zmq)"; // LOG(logERROR) << "The requested address is already in use (zmq)";
break; // break;
case EADDRNOTAVAIL: // case EADDRNOTAVAIL:
LOG(logERROR) << "The requested address was not local (zmq)"; // LOG(logERROR) << "The requested address was not local (zmq)";
break; // break;
case ENODEV: // case ENODEV:
LOG(logERROR) // LOG(logERROR)
<< "The requested address specifies a nonexistent interface (zmq)"; // << "The requested address specifies a nonexistent interface (zmq)";
break; // break;
case ETERM: // case ETERM:
LOG(logERROR) << "The ØMQ context associated with the specified socket " // LOG(logERROR) << "The ØMQ context associated with the specified socket "
"was terminated (zmq)"; // "was terminated (zmq)";
break; // break;
case ENOTSOCK: // case ENOTSOCK:
LOG(logERROR) << "The provided socket was invalid (zmq)"; // LOG(logERROR) << "The provided socket was invalid (zmq)";
break; // break;
case EINTR: // case EINTR:
LOG(logERROR) // LOG(logERROR)
<< "The operation was interrupted by delivery of a signal (zmq)"; // << "The operation was interrupted by delivery of a signal (zmq)";
break; // break;
case EMTHREAD: // case EMTHREAD:
LOG(logERROR) // LOG(logERROR)
<< "No I/O thread is available to accomplish the task (zmq)"; // << "No I/O thread is available to accomplish the task (zmq)";
break; // break;
default: // default:
LOG(logERROR) << "Unknown socket error (zmq)"; // LOG(logERROR) << "Unknown socket error (zmq)";
break; // break;
} // }
} }
// Nested class to do RAII handling of socket descriptors // Nested class to do RAII handling of socket descriptors
@ -423,19 +423,19 @@ ZmqSocket::mySocketDescriptors::~mySocketDescriptors() {
Close(); Close();
} }
void ZmqSocket::mySocketDescriptors::Disconnect() { void ZmqSocket::mySocketDescriptors::Disconnect() {
if (server) // if (server)
zmq_unbind(socketDescriptor, serverAddress.c_str()); // zmq_unbind(socketDescriptor, serverAddress.c_str());
else // else
zmq_disconnect(socketDescriptor, serverAddress.c_str()); // zmq_disconnect(socketDescriptor, serverAddress.c_str());
}; };
void ZmqSocket::mySocketDescriptors::Close() { void ZmqSocket::mySocketDescriptors::Close() {
if (socketDescriptor != nullptr) { // if (socketDescriptor != nullptr) {
zmq_close(socketDescriptor); // zmq_close(socketDescriptor);
socketDescriptor = nullptr; // socketDescriptor = nullptr;
} // }
if (contextDescriptor != nullptr) { // if (contextDescriptor != nullptr) {
zmq_ctx_destroy(contextDescriptor); // zmq_ctx_destroy(contextDescriptor);
contextDescriptor = nullptr; // contextDescriptor = nullptr;
} // }
}; };

View File

@ -11,8 +11,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
namespace sls {
int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) { int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) {
int ichan, iline = 0; int ichan, iline = 0;
short int idata; short int idata;
@ -55,39 +53,6 @@ int readDataFile(std::string fname, short int *data, int nch) {
return iline; 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 writeDataFile(std::ofstream &outfile, int nch, short int *data,
int offset) { int offset) {
if (data == nullptr) if (data == nullptr)
@ -131,6 +96,7 @@ void mkdir_p(const std::string &path, std::string dir) {
mkdir_p(path.substr(i + 1), dir); mkdir_p(path.substr(i + 1), dir);
} }
namespace sls {
int getFileSize(std::ifstream &ifs) { int getFileSize(std::ifstream &ifs) {
auto current_pos = ifs.tellg(); auto current_pos = ifs.tellg();
ifs.seekg(0, std::ios::end); ifs.seekg(0, std::ios::end);
@ -138,27 +104,4 @@ int getFileSize(std::ifstream &ifs) {
ifs.seekg(current_pos); ifs.seekg(current_pos);
return file_size; 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 } // namespace sls

Some files were not shown because too many files have changed in this diff Show More