Skip to content
Snippets Groups Projects
Commit 2d17a361 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

added skeleton for TecDummy

parent 3a52728c
No related branches found
No related tags found
No related merge requests found
# name n_words address n_bytes BAR n_bits n_fractionalBits signed access
UNIO0.BIT_TEC1091_ENABLE 1 4576 4 1 1 0 0 RW
UNIO0.BIT_TEC1091_CMD_LOOP_START 1 4580 4 1 1 0 0 RW
UNIO0.BIT_TEC1091_CMD_LOOP_DONE 1 4584 4 1 1 0 0 RO
UNIO0.AREA_TEC1091_CMD 256 5120 1024 1 32 0 0 RW
# note: addresses are hardcoded in the TecDummy!
UNIO0.BIT_TEC1091_ENABLE 1 0 4 0 1 0 0 RW
UNIO0.BIT_TEC1091_CMD_LOOP_START 1 4 4 0 1 0 0 RW
UNIO0.BIT_TEC1091_CMD_LOOP_DONE 1 8 4 0 1 0 0 RO
UNIO0.AREA_TEC1091_CMD 256 12 1024 0 32 0 0 RW
......@@ -5,11 +5,16 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.5.1)
# Add BOOST dependencies
FIND_PACKAGE(Boost COMPONENTS thread system unit_test_framework REQUIRED)
# The tests also require the server headers (TODO Potentially, module includes are also needed)
# The tests also require the server headers
include_directories(${CMAKE_SOURCE_DIR}/server/include)
# build library with dummy device etc.
include_directories(include)
aux_source_directory(src testlibrary_sources)
add_library(${PROJECT_NAME}testlib ${testlibrary_sources})
# Add all tests residing in the "tests" directory
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} testExecutables)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/executable_src testExecutables)
foreach( testExecutableSrcFile ${testExecutables})
#NAME_WE means the base name without path and (longest) extension
get_filename_component(excutableName ${testExecutableSrcFile} NAME_WE)
......@@ -19,7 +24,7 @@ foreach( testExecutableSrcFile ${testExecutables})
PROPERTIES
LINK_FLAGS "${CMAKE_LINK_FLAGS}"
)
target_link_libraries(${excutableName} ${PROJECT_NAME}lib ${ChimeraTK-ApplicationCore_LIBRARIES} ${Adapter_LIBRARIES} )
target_link_libraries(${excutableName} ${PROJECT_NAME}lib ${ChimeraTK-ApplicationCore_LIBRARIES} ${Adapter_LIBRARIES} ${PROJECT_NAME}testlib)
add_test(
NAME ${excutableName}
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${excutableName}
......
File moved
#pragma once
#include <ChimeraTK/DummyBackend.h>
#include <ChimeraTK/BackendFactory.h>
#include <ChimeraTK/DummyRegisterAccessor.h>
struct TecDummy : ChimeraTK::DummyBackend {
TecDummy(std::string mapFileName) : DummyBackend(mapFileName) {}
~TecDummy() override;
// hardcoded addresses used by the dummy, need to match addresses of map file
constexpr static uint8_t TecDummy_bar{0};
constexpr static uint32_t TecDummy_address_loopDone{8};
// Accessors for the registers
ChimeraTK::DummyRegisterAccessor<uint32_t> reg_loopStart{this, "UNIO0", "BIT_TEC1091_CMD_LOOP_START"};
ChimeraTK::DummyRegisterAccessor<uint32_t> reg_loopDone{this, "UNIO0", "BIT_TEC1091_CMD_LOOP_DONE"};
ChimeraTK::DummyRegisterAccessor<uint32_t> reg_command{this, "UNIO0", "AREA_TEC1091_CMD"};
static boost::shared_ptr<DeviceBackend> createInstance(std::string, std::map<std::string, std::string> parameters) {
return boost::shared_ptr<DeviceBackend>(new TecDummy(parameters["map"]));
}
void read(uint8_t bar, uint32_t address, int32_t* data, size_t sizeInBytes) override;
// In this function the TEC device is actually simulated.
std::string dataProcessing(const std::string& command);
class BackendRegisterer {
public:
BackendRegisterer();
};
static BackendRegisterer backendRegisterer;
};
TecDummy::BackendRegisterer TecDummy::backendRegisterer;
#include "TecDummy.h"
/*********************************************************************************************************************/
TecDummy::BackendRegisterer::BackendRegisterer() {
std::cout << "TecDummy::BackendRegisterer: registering backend type TecDummy" << std::endl;
ChimeraTK::BackendFactory::getInstance().registerBackendType("TecDummy", &TecDummy::createInstance);
}
/*********************************************************************************************************************/
void TecDummy::read(uint8_t bar, uint32_t address, int32_t* data, size_t sizeInBytes) {
DummyBackend::read(bar, address, data, sizeInBytes);
if(bar != TecDummy_bar || address != TecDummy_address_loopDone) return;
if(reg_loopStart != 1) return;
// convert command into string
// FIXME: this can be done better if the DummyRegisterRawAccessor would allow us to use the raw pointer to this...
std::string commandString(reg_command.getNumberOfElements() * 4, 0);
for(size_t i = 0; i < reg_command.getNumberOfElements(); ++i) {
uint32_t word = reg_command[i];
std::memcpy(&(commandString[4 * i]), &word, 4);
}
// perform data processing
auto reply = dataProcessing(commandString);
// convert reply back into byte stream
for(size_t i = 0; i < reply.length(); ++i) {
uint32_t word;
std::memcpy(&word, &(reply[4 * i]), 4);
reg_command[i] = word;
}
reg_loopDone = 1;
}
/*********************************************************************************************************************/
std::string TecDummy::dataProcessing(const std::string& command) {
// Place data processing code here. Parse data from the "command" dummy accessor and place the reply on the same
// accessor. Just return this function, the done flag is automatically set by the caller. Remove this comment after
// implementation.
std::cout << "TecDummy::dataProcessing() command = " << command << std::endl;
return "MY REPLY";
}
/*********************************************************************************************************************/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment