ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
DummyRegisterAccessor.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 "DummyBackend.h"
6#include "NumericAddressedBackendMuxedRegisterAccessor.h" // for the prefixes to the register names
7
8namespace ChimeraTK {
9
13 namespace proxies {
14 /******************************************************************************************************************/
19 template<typename T>
21 public:
23 : fpcptr(_fpc), nbytes(_nbytes), buffer(_buffer) {}
24
27 // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
28 inline operator T() const { return fpcptr->template scalarToCooked<T>(*buffer); }
29
32 int32_t raw = fpcptr->toRaw(rhs);
33 memcpy(buffer, &raw, nbytes);
34 return *this;
35 }
36
39 T cooked = fpcptr->template scalarToCooked<T>(*buffer);
40 return operator=(cooked + 1);
41 }
42
45 T cooked = fpcptr->template scalarToCooked<T>(*buffer);
46 return operator=(cooked - 1);
47 }
48
50 inline T operator++(int) {
51 T cooked = fpcptr->template scalarToCooked<T>(*buffer);
52 operator=(cooked + 1);
53 return cooked;
54 }
55
57 inline T operator--(int) {
58 T cooked = fpcptr->template scalarToCooked<T>(*buffer);
59 operator=(cooked - 1);
60 return cooked;
61 }
62
63 protected:
65 DummyRegisterElement() : fpcptr(nullptr), nbytes(0), buffer(nullptr) {}
66
69
71 int nbytes;
72
74 int32_t* buffer;
75 };
76
77 /******************************************************************************************************************/
80 template<typename T>
82 public:
84 FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT>* _fpc, int _nbytes, int _pitch, int32_t* _buffer)
85 : fpcptr(_fpc), nbytes(_nbytes), pitch(_pitch), buffer(_buffer) {}
86
88 inline DummyRegisterElement<T> operator[](unsigned int sample) {
89 // todo: Probably ranges are the correct tool in cpp22. In cpp17 this is not available yet. We turn off the
90 // warning not to use reinterpret_cast for the time being
91 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
92 auto* basePtr = reinterpret_cast<std::byte*>(buffer);
93 auto* startAddress = basePtr + static_cast<size_t>(pitch) * sample;
94 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
95 return DummyRegisterElement<T>(fpcptr, nbytes, reinterpret_cast<int32_t*>(startAddress));
96 }
97
99 void operator=(const DummyRegisterSequence& rightHandSide) const = delete;
100
101 protected:
104
107
109 int pitch;
110
112 int32_t* buffer;
113 };
114 } // namespace proxies
115
116 /********************************************************************************************************************/
132 template<typename T>
134 public:
139 DummyRegisterAccessor(DummyBackend* dev, std::string const& module, std::string const& name)
140 : _dev(dev), _path(module + "/" + name), fpc(module + "/" + name) {
143 registerInfo.channels.front().nFractionalBits, registerInfo.channels.front().signedFlag);
144 // initialise the base DummyRegisterElement
148 }
149 // declare that we want the default copy constructor. Needed because we have a custom = operator
151
153 void operator=(const DummyRegisterAccessor& rightHandSide) const = delete;
154
156 inline proxies::DummyRegisterElement<T> operator[](unsigned int index) { return getProxy(index); }
157
159 unsigned int getNumberOfElements() { return registerInfo.nElements; }
160
162 using proxies::DummyRegisterElement<T>::operator=;
163
165 [[nodiscard]] DummyBackend& getBackend() const { return *_dev; }
166
168 [[nodiscard]] const RegisterPath& getRegisterPath() const { return _path; }
169
171 void setWriteCallback(const std::function<void()>& writeCallback) {
172 assert(registerInfo.elementPitchBits % 8 == 0);
174 {static_cast<uint8_t>(registerInfo.bar), static_cast<uint32_t>(registerInfo.address),
176 writeCallback);
177 }
178
180
184 std::unique_lock<std::mutex> getBufferLock() { return std::unique_lock<std::mutex>(_dev->mutex); }
185
186 protected:
189
192
195
198
200 inline int32_t* getElement(unsigned int index) {
201 return &(_dev->_barContents[registerInfo.bar][registerInfo.address / sizeof(int32_t) + index]);
202 }
203
206 return proxies::DummyRegisterElement<T>(&fpc, sizeof(int32_t), getElement(index));
207 }
208 };
209
210 /********************************************************************************************************************/
221 template<typename T>
223 public:
230 DummyMultiplexedRegisterAccessor(DummyBackend* dev, std::string const& module, std::string const& name)
231 : _dev(dev), _path(module + "/" + name) {
232 registerInfo = _dev->_registerMap.getBackendRegister(module + "." + name);
233
234 // create fixed point converters for each channel
235 for(auto& c : registerInfo.channels) {
236 // create fixed point converter for sequence
237 fpc.emplace_back(registerInfo.pathName, c.width, c.nFractionalBits, c.signedFlag);
238 // store offsets and number of bytes per word
239 assert(c.bitOffset % 8 == 0);
240 offsets.push_back(registerInfo.address + c.bitOffset / 8);
241 nbytes.push_back((c.width - 1) / 8 + 1); // width/8 rounded up
242 }
243
244 if(fpc.empty()) {
245 throw ChimeraTK::logic_error("No sequences found for name \"" + name + "\".");
246 }
247
248 // cache some information
250 assert(registerInfo.elementPitchBits % 8 == 0);
252 }
253
255 void operator=(const DummyMultiplexedRegisterAccessor& rightHandSide) const = delete;
256
257 // declare that we want the default copy constructor. Needed because we have a custom = operator
259
261 unsigned int getNumberOfElements() { return nElements; }
262
264 unsigned int getNumberOfSequences() { return fpc.size(); }
265
271 inline proxies::DummyRegisterSequence<T> operator[](unsigned int sequence) {
272 // todo: Probably ranges are the correct tool in cpp22. In cpp17 this is not available yet. We turn off the
273 // warning not to use reinterpret_cast for the time being
274 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
275 auto* basePtr = reinterpret_cast<std::byte*>(_dev->_barContents[registerInfo.bar].data());
276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
277 auto* seq = reinterpret_cast<int32_t*>(basePtr + offsets[sequence]);
278 return proxies::DummyRegisterSequence<T>(&(fpc[sequence]), nbytes[sequence], pitch, seq);
279 }
280
282 [[nodiscard]] DummyBackend& getBackend() const { return *_dev; }
283
285 [[nodiscard]] const RegisterPath& getRegisterPath() const { return _path; }
286
288
289 protected:
292
295
298
300 std::vector<FixedPointConverter<DEPRECATED_FIXEDPOINT_DEFAULT>> fpc;
301
303 std::vector<uint32_t> offsets;
304
306 std::vector<uint32_t> nbytes;
307
309 int pitch = {0};
310
312 unsigned int nElements;
313 };
314
326 public:
329 // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
330 operator int32_t&() { return *buffer; }
331
333 boost::shared_ptr<DeviceBackend> const& backend, std::string const& module, std::string const& name)
334 : _backend(boost::dynamic_pointer_cast<DummyBackend>(backend)) {
335 assert(_backend);
336 registerInfo = _backend->_registerMap.getBackendRegister(module + "." + name);
337 buffer = &(_backend->_barContents[registerInfo.bar][registerInfo.address / sizeof(int32_t)]);
338 }
339
340 // declare that we want the default copy constructor. Needed because we have a custom = operator
341 // The default copy/move constructor is fine. It will copy the raw pointer to the buffer,
342 // together with the shared pointer which holds the corresponding backend with the
343 // memory. So it is a consistent copy because the shared pointer is pointing to the
344 // same backend instance.
346
348 void operator=(const DummyRegisterRawAccessor& rightHandSide) const = delete;
349
351 buffer[0] = rhs;
352 return *this;
353 }
354
356 int32_t& operator[](unsigned int index) { return buffer[index]; }
357
359 [[nodiscard]] unsigned int getNumberOfElements() const { return registerInfo.nElements; }
360
364 std::unique_lock<std::mutex> getBufferLock() { return std::unique_lock<std::mutex>(_backend->mutex); }
365
366 protected:
368 boost::shared_ptr<DummyBackend> _backend;
369
372
374 int32_t* buffer;
375 };
376
377} // namespace ChimeraTK
The dummy device opens a mapping file instead of a device, and implements all registers defined in th...
void setWriteCallbackFunction(AddressRange addressRange, boost::function< void(void)> const &writeCallbackFunction)
std::map< uint64_t, std::vector< int32_t > > _barContents
Register accessor for accessing multiplexed 2D array registers internally of a DummyBackend implement...
DummyMultiplexedRegisterAccessor(DummyBackend *dev, std::string const &module, std::string const &name)
Constructor should normally be called in the constructor of the DummyBackend implementation.
DummyBackend * _dev
pointer to VirtualDevice
int pitch
pitch in bytes (distance between samples of the same sequence)
DummyBackend & getBackend() const
Return the backend.
unsigned int getNumberOfSequences()
return number of sequences
const RegisterPath & getRegisterPath() const
Return the register path.
const NumericAddressedRegisterInfo & getRegisterInfo()
DummyMultiplexedRegisterAccessor(const DummyMultiplexedRegisterAccessor &)=default
std::vector< FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > > fpc
pointer to fixed point converter
void operator=(const DummyMultiplexedRegisterAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing
unsigned int nElements
number of elements per sequence
unsigned int getNumberOfElements()
return number of elements per sequence
std::vector< uint32_t > nbytes
number of bytes per word for sequences
proxies::DummyRegisterSequence< T > operator[](unsigned int sequence)
Get or set register content by [] operators.
std::vector< uint32_t > offsets
offsets in bytes for sequences
NumericAddressedRegisterInfo registerInfo
register map information
Register accessor for accessing single word or 1D array registers internally of a DummyBackend implem...
DummyBackend * _dev
pointer to VirtualDevice
DummyRegisterAccessor(const DummyRegisterAccessor &)=default
DummyBackend & getBackend() const
Return the backend.
void operator=(const DummyRegisterAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing *‍/
const RegisterPath & getRegisterPath() const
Return the register path.
int32_t * getElement(unsigned int index)
return element
unsigned int getNumberOfElements()
return number of elements
FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > fpc
fixed point converter
RegisterPath _path
path of the register
proxies::DummyRegisterElement< T > operator[](unsigned int index)
Get or set register content by [] operator.
proxies::DummyRegisterElement< T > getProxy(int index)
return a proxy object
DummyRegisterAccessor(DummyBackend *dev, std::string const &module, std::string const &name)
Constructor should normally be called in the constructor of the DummyBackend implementation.
const NumericAddressedRegisterInfo & getRegisterInfo()
void setWriteCallback(const std::function< void()> &writeCallback)
Set callback function which is called when the register is written to (through the normal Device inte...
std::unique_lock< std::mutex > getBufferLock()
Get a lock to safely modify the buffer in a multi-treaded environment.
NumericAddressedRegisterInfo registerInfo
register map information
Accessor for raw 32 bit integer access to the underlying memory space.
void operator=(const DummyRegisterRawAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing
DummyRegisterRawAccessor(boost::shared_ptr< DeviceBackend > const &backend, std::string const &module, std::string const &name)
int32_t * buffer
raw buffer of this accessor
unsigned int getNumberOfElements() const
return number of elements
boost::shared_ptr< DummyBackend > _backend
pointer to dummy backend
int32_t & operator[](unsigned int index)
Get or set register content by [] operator.
DummyRegisterRawAccessor(const DummyRegisterRawAccessor &)=default
NumericAddressedRegisterInfo registerInfo
register map information
std::unique_lock< std::mutex > getBufferLock()
Get a lock to safely modify the buffer.
DummyRegisterRawAccessor & operator=(int32_t rhs)
The fixed point converter provides conversion functions between a user type and up to 32 bit fixed po...
RawType toRaw(UserType cookedValue) const
Conversion function from type T to fixed point.
NumericAddressedRegisterCatalogue & _registerMap
NumericAddressedRegisterInfo getBackendRegister(const RegisterPath &registerPathName) const override
Note: Override this function if backend has "hidden" registers which are not added to the map and hen...
uint32_t nElements
Number of elements in register.
std::vector< ChannelInfo > channels
Define per-channel information (bit interpretation etc.), 1D/scalars have exactly one entry.
uint64_t bar
Upper part of the address (name originally from PCIe, meaning now generalised)
uint32_t elementPitchBits
Distance in bits (!) between two elements (of the same channel)
uint64_t address
Lower part of the address relative to BAR, in bytes.
Class to store a register path name.
Exception thrown when a logic error has occured.
Definition Exception.h:51
Temporary proxy class for use in the DummyRegister and DummyMultiplexedRegister classes.
DummyRegisterElement(FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > *_fpc, int _nbytes, int32_t *_buffer)
DummyRegisterElement< T > & operator=(T rhs)
assignment operator
DummyRegisterElement< T > operator++()
pre-increment operator
DummyRegisterElement()
constructor when used as a base class in DummyRegister
DummyRegisterElement< T > operator--()
pre-decrement operator
FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > * fpcptr
fixed point converter to be used for this element
int32_t * buffer
raw buffer of this element
Temporary proxy class for sequences, used in the DummyMultiplexedRegister class.
int32_t * buffer
reference to the raw buffer (first word of the sequence)
int pitch
pitch in bytes (distance between samples of the same sequence)
DummyRegisterElement< T > operator[](unsigned int sample)
Get or set register content by [] operator.
DummyRegisterSequence(FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > *_fpc, int _nbytes, int _pitch, int32_t *_buffer)
FixedPointConverter< DEPRECATED_FIXEDPOINT_DEFAULT > * fpcptr
fixed point converter to be used for this sequence
void operator=(const DummyRegisterSequence &rightHandSide) const =delete
remove assignment operator since it will be confusing *‍/
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...