ChimeraTK-DeviceAccess 03.27.00
Loading...
Searching...
No Matches
SubdeviceBackend.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
5#include "DeviceBackendImpl.h"
7
8#include <mutex>
9#include <string>
10
11namespace ChimeraTK {
12 class SubdeviceRegisterAccessor;
13 template<typename RegisterRawType, typename WriteDataType>
14 class SubdeviceRegisterWindowAccessor;
15
71 public:
72 explicit SubdeviceBackend(std::map<std::string, std::string> parameters);
73
74 void open() override;
75
76 void close() override;
77
78 std::string readDeviceInfo() override {
79 return "Subdevice";
80 }
81
82 static boost::shared_ptr<DeviceBackend> createInstance(
83 std::string address, std::map<std::string, std::string> parameters);
84
86
88
89 std::set<DeviceBackend::BackendID> getInvolvedBackendIDs() override;
90
91 protected:
93 template<typename RegisterRawType, typename WriteDataType>
95
96 enum class Type {
97 area, //< address space is visible as an area in the target device
98 threeRegisters, //< use three registers (address, data and status) in target
99 //< device. status must be 0 when idle
100 twoRegisters, //< same as three registers but without status
101 areaHandshake, //< address space visible as an area in the target device, and wait on status 0
102 registerWindow //< Universal interface which allows write, read and multiple chips. Includes 3reg, 2reg (not
103 //< 100 % compatible)
104 };
105
106 using BusyRegisterKey = std::pair<DeviceBackend*, RegisterPath>;
107
111 static std::map<BusyRegisterKey, std::shared_ptr<std::mutex>> _mutexes;
112 static std::mutex _mutexMapMutex; // a mutex to proptext insertions into the map with mutexes.
113
114 std::shared_ptr<std::mutex> _mutex; // cache the mutex to avoid repeated lookup.
115
118
120 size_t _timeout{10000};
121
123 std::string _targetAlias;
124
127 boost::shared_ptr<ChimeraTK::DeviceBackend> _targetDevice;
128
130 std::string _targetArea;
131
134
136 std::map<std::string, std::string> _parameters;
137
140 size_t _sleepTime{100};
141
144
146 size_t _chipIndex{0};
147
151
154 void verifyRegisterAccessorSize(const NumericAddressedRegisterInfo& info, size_t& numberOfWords,
155 size_t wordOffsetInRegister, bool enforceAlignment);
156
157 template<typename UserType>
158 // NOLINTNEXTLINE(readability-identifier-naming)
159 boost::shared_ptr<NDRegisterAccessor<UserType>> getRegisterAccessor_impl(
160 const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags);
162
164 template<typename UserType>
165 boost::shared_ptr<NDRegisterAccessor<UserType>> getAreaRegisterAccessor(
166 const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags);
167
169 template<typename UserType>
170 boost::shared_ptr<NDRegisterAccessor<UserType>> getSynchronisedRegisterAccessor(
171 const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister,
172 const AccessModeFlags& flags);
173
174 template<typename UserType>
175 boost::shared_ptr<NDRegisterAccessor<UserType>> getRegisterWindowAccessor(const RegisterPath& registerPathName,
176 size_t numberOfWords, size_t wordOffsetInRegister, const AccessModeFlags& flags);
177
179 void obtainTargetBackend();
180
181 void setExceptionImpl() noexcept override;
182
183 void activateAsyncRead() noexcept override;
184
187
188 // helper for reducing code duplication among template specializations
189 boost::shared_ptr<SubdeviceRegisterAccessor> accessorCreationHelper(const NumericAddressedRegisterInfo& info,
190 size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags);
191 };
192
193} // namespace ChimeraTK
Set of AccessMode flags with additional functionality for an easier handling.
Definition AccessMode.h:48
DeviceBackendImpl implements some basic functionality which should be available for all backends.
Container for backend metadata.
Catalogue of register information.
Class to store a register path name.
Backend for subdevices which are passed through some register or area of another device (subsequently...
boost::shared_ptr< NDRegisterAccessor< UserType > > getAreaRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
getRegisterAccessor implementation for area types
std::shared_ptr< std::mutex > _mutex
NumericAddressedRegisterCatalogue _registerMap
map from register names to addresses
void open() override
Open the device.
Type _type
type of the subdevice
boost::shared_ptr< NDRegisterAccessor< UserType > > getRegisterWindowAccessor(const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, const AccessModeFlags &flags)
static boost::shared_ptr< DeviceBackend > createInstance(std::string address, std::map< std::string, std::string > parameters)
void close() override
Close the device.
MetadataCatalogue getMetadataCatalogue() const override
Return the device metadata catalogue.
std::pair< DeviceBackend *, RegisterPath > BusyRegisterKey
size_t _addressToDataDelay
for type == registerWindow, threeRegisters or twoRegisters: sleep time between address and data write
boost::shared_ptr< ChimeraTK::DeviceBackend > _targetDevice
The target device backend itself.
DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE_FILLER(SubdeviceBackend, getRegisterAccessor_impl, 4)
size_t _timeout
timeout (in milliseconds), used in threeRegisters to throw a runtime_error if status register stuck a...
size_t _chipIndex
for type == registerWindow: chip index
void setExceptionImpl() noexcept override
Function to be (optionally) implemented by backends if additional actions are needed when switching t...
boost::shared_ptr< NDRegisterAccessor< UserType > > getSynchronisedRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, const AccessModeFlags &flags)
getRegisterAccessor implementation for threeRegisters types
MetadataCatalogue _metadataCatalogue
void obtainTargetBackend()
obtain the target backend if not yet done
std::map< std::string, std::string > _parameters
currently only used for type == registerWindow: the whole set of parameters
size_t _sleepTime
for type == registerWindow, threeRegisters or twoRegisters: sleep time of polling loop resp.
boost::shared_ptr< NDRegisterAccessor< UserType > > getRegisterAccessor_impl(const RegisterPath &registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
std::string _targetAlias
the target device name
std::string _targetAddress
for type == registerWindow, threeRegisters or twoRegisters: the names of the basic target registers
std::string _targetArea
for type == area: the name of the target register
void verifyRegisterAccessorSize(const NumericAddressedRegisterInfo &info, size_t &numberOfWords, size_t wordOffsetInRegister, bool enforceAlignment)
Check consistency of the passed sizes and offsets against the information in the map file Will adjust...
std::string readDeviceInfo() override
Return a device information string containing hardware details like the firmware version number or th...
RegisterCatalogue getRegisterCatalogue() const override
Return the register catalogue with detailed information on all registers.
static std::map< BusyRegisterKey, std::shared_ptr< std::mutex > > _mutexes
Mutex to protext concurrent access to the target registers.
void activateAsyncRead() noexcept override
Activate asyncronous read for all transfer elements where AccessMode::wait_for_new_data is set.
std::set< DeviceBackend::BackendID > getInvolvedBackendIDs() override
Get the backend IDs of all involved backends.
boost::shared_ptr< SubdeviceRegisterAccessor > accessorCreationHelper(const NumericAddressedRegisterInfo &info, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags)
The RegisterRawType is determined by the number of bytes in the SubDevice mapfile The ReadWriteDataTy...