ChimeraTK-DeviceAccess  03.18.00
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 
8 namespace ChimeraTK {
9 
13  namespace proxies {
14  /******************************************************************************************************************/
19  template<typename T>
21  public:
22  DummyRegisterElement(FixedPointConverter* _fpc, int _nbytes, int32_t* _buffer)
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:
83  DummyRegisterSequence(FixedPointConverter* _fpc, int _nbytes, int _pitch, int32_t* _buffer)
84  : fpcptr(_fpc), nbytes(_nbytes), pitch(_pitch), buffer(_buffer) {}
85 
87  inline DummyRegisterElement<T> operator[](unsigned int sample) {
88  // todo: Probably ranges are the correct tool in cpp22. In cpp17 this is not available yet. We turn off the
89  // warning not to use reinterpret_cast for the time being
90  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
91  auto* basePtr = reinterpret_cast<std::byte*>(buffer);
92  auto* startAddress = basePtr + static_cast<size_t>(pitch) * sample;
93  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
94  return DummyRegisterElement<T>(fpcptr, nbytes, reinterpret_cast<int32_t*>(startAddress));
95  }
96 
98  void operator=(const DummyRegisterSequence& rightHandSide) const = delete;
99 
100  protected:
103 
105  int nbytes;
106 
108  int pitch;
109 
111  int32_t* buffer;
112  };
113  } // namespace proxies
114 
115  /********************************************************************************************************************/
131  template<typename T>
133  public:
138  DummyRegisterAccessor(DummyBackend* dev, std::string const& module, std::string const& name)
139  : _dev(dev), _path(module + "/" + name), fpc(module + "/" + name) {
141  fpc = FixedPointConverter(module + "/" + name, registerInfo.channels.front().width,
142  registerInfo.channels.front().nFractionalBits, registerInfo.channels.front().signedFlag);
143  // initialise the base DummyRegisterElement
147  }
148  // declare that we want the default copy constructor. Needed because we have a custom = operator
150 
152  void operator=(const DummyRegisterAccessor& rightHandSide) const = delete;
153 
155  inline proxies::DummyRegisterElement<T> operator[](unsigned int index) { return getProxy(index); }
156 
158  unsigned int getNumberOfElements() { return registerInfo.nElements; }
159 
162 
164  [[nodiscard]] DummyBackend& getBackend() const { return *_dev; }
165 
167  [[nodiscard]] const RegisterPath& getRegisterPath() const { return _path; }
168 
170  void setWriteCallback(const std::function<void()>& writeCallback) {
171  assert(registerInfo.elementPitchBits % 8 == 0);
173  {static_cast<uint8_t>(registerInfo.bar), static_cast<uint32_t>(registerInfo.address),
175  writeCallback);
176  }
177 
179 
183  std::unique_lock<std::mutex> getBufferLock() { return std::unique_lock<std::mutex>(_dev->mutex); }
184 
185  protected:
188 
191 
194 
197 
199  inline int32_t* getElement(unsigned int index) {
200  return &(_dev->_barContents[registerInfo.bar][registerInfo.address / sizeof(int32_t) + index]);
201  }
202 
205  return proxies::DummyRegisterElement<T>(&fpc, sizeof(int32_t), getElement(index));
206  }
207  };
208 
209  /********************************************************************************************************************/
220  template<typename T>
221  class DummyMultiplexedRegisterAccessor {
222  public:
229  DummyMultiplexedRegisterAccessor(DummyBackend* dev, std::string const& module, std::string const& name)
230  : _dev(dev), _path(module + "/" + name) {
231  registerInfo = _dev->_registerMap.getBackendRegister(module + "." + name);
232 
233  // create fixed point converters for each channel
234  for(auto& c : registerInfo.channels) {
235  // create fixed point converter for sequence
236  fpc.emplace_back(registerInfo.pathName, c.width, c.nFractionalBits, c.signedFlag);
237  // store offsets and number of bytes per word
238  assert(c.bitOffset % 8 == 0);
239  offsets.push_back(registerInfo.address + c.bitOffset / 8);
240  nbytes.push_back((c.width - 1) / 8 + 1); // width/8 rounded up
241  }
242 
243  if(fpc.empty()) {
244  throw ChimeraTK::logic_error("No sequences found for name \"" + name + "\".");
245  }
246 
247  // cache some information
249  assert(registerInfo.elementPitchBits % 8 == 0);
251  }
252 
254  void operator=(const DummyMultiplexedRegisterAccessor& rightHandSide) const = delete;
255 
256  // declare that we want the default copy constructor. Needed because we have a custom = operator
258 
260  unsigned int getNumberOfElements() { return nElements; }
261 
263  unsigned int getNumberOfSequences() { return fpc.size(); }
264 
270  inline proxies::DummyRegisterSequence<T> operator[](unsigned int sequence) {
271  // todo: Probably ranges are the correct tool in cpp22. In cpp17 this is not available yet. We turn off the
272  // warning not to use reinterpret_cast for the time being
273  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
274  auto* basePtr = reinterpret_cast<std::byte*>(_dev->_barContents[registerInfo.bar].data());
275  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
276  auto* seq = reinterpret_cast<int32_t*>(basePtr + offsets[sequence]);
277  return proxies::DummyRegisterSequence<T>(&(fpc[sequence]), nbytes[sequence], pitch, seq);
278  }
279 
281  [[nodiscard]] DummyBackend& getBackend() const { return *_dev; }
282 
284  [[nodiscard]] const RegisterPath& getRegisterPath() const { return _path; }
285 
286  [[nodiscard]] const NumericAddressedRegisterInfo& getRegisterInfo() { return registerInfo; }
287 
288  protected:
291 
294 
297 
299  std::vector<FixedPointConverter> fpc;
300 
302  std::vector<uint32_t> offsets;
303 
305  std::vector<uint32_t> nbytes;
306 
308  int pitch = {0};
309 
311  unsigned int nElements;
312  };
313 
325  public:
328  // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
329  operator int32_t&() { return *buffer; }
330 
332  boost::shared_ptr<DeviceBackend> const& backend, std::string const& module, std::string const& name)
333  : _backend(boost::dynamic_pointer_cast<DummyBackend>(backend)) {
334  assert(_backend);
335  registerInfo = _backend->_registerMap.getBackendRegister(module + "." + name);
336  buffer = &(_backend->_barContents[registerInfo.bar][registerInfo.address / sizeof(int32_t)]);
337  }
338 
339  // declare that we want the default copy constructor. Needed because we have a custom = operator
340  // The default copy/move constructor is fine. It will copy the raw pointer to the buffer,
341  // together with the shared pointer which holds the corresponding backend with the
342  // memory. So it is a consistent copy because the shared pointer is pointing to the
343  // same backend instance.
345 
347  void operator=(const DummyRegisterRawAccessor& rightHandSide) const = delete;
348 
350  buffer[0] = rhs;
351  return *this;
352  }
353 
355  int32_t& operator[](unsigned int index) { return buffer[index]; }
356 
358  [[nodiscard]] unsigned int getNumberOfElements() const { return registerInfo.nElements; }
359 
363  std::unique_lock<std::mutex> getBufferLock() { return std::unique_lock<std::mutex>(_backend->mutex); }
364 
365  protected:
367  boost::shared_ptr<DummyBackend> _backend;
368 
371 
373  int32_t* buffer;
374  };
375 
376 } // namespace ChimeraTK
ChimeraTK::DummyRegisterAccessor::getBackend
DummyBackend & getBackend() const
Return the backend.
Definition: DummyRegisterAccessor.h:164
ChimeraTK::DummyRegisterRawAccessor::getNumberOfElements
unsigned int getNumberOfElements() const
return number of elements
Definition: DummyRegisterAccessor.h:358
ChimeraTK::NumericAddressedRegisterInfo::address
uint64_t address
Lower part of the address relative to BAR, in bytes.
Definition: NumericAddressedRegisterCatalogue.h:114
ChimeraTK::proxies::DummyRegisterSequence::nbytes
int nbytes
number of bytes per word
Definition: DummyRegisterAccessor.h:105
ChimeraTK::DummyMultiplexedRegisterAccessor::getNumberOfElements
unsigned int getNumberOfElements()
return number of elements per sequence
Definition: DummyRegisterAccessor.h:260
ChimeraTK::proxies::DummyRegisterElement::operator++
T operator++(int)
post-increment operator
Definition: DummyRegisterAccessor.h:50
ChimeraTK::proxies::DummyRegisterSequence::operator=
void operator=(const DummyRegisterSequence &rightHandSide) const =delete
remove assignment operator since it will be confusing *‍/
ChimeraTK::DummyRegisterAccessor::getElement
int32_t * getElement(unsigned int index)
return element
Definition: DummyRegisterAccessor.h:199
ChimeraTK::DummyRegisterAccessor::getProxy
proxies::DummyRegisterElement< T > getProxy(int index)
return a proxy object
Definition: DummyRegisterAccessor.h:204
ChimeraTK::AccessMode::raw
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
ChimeraTK::DummyRegisterAccessor::_path
RegisterPath _path
path of the register
Definition: DummyRegisterAccessor.h:193
ChimeraTK::NumericAddressedRegisterCatalogue::getBackendRegister
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...
Definition: NumericAddressedRegisterCatalogue.cc:209
ChimeraTK::DummyMultiplexedRegisterAccessor::operator=
void operator=(const DummyMultiplexedRegisterAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing
ChimeraTK::DummyRegisterRawAccessor::_backend
boost::shared_ptr< DummyBackend > _backend
pointer to dummy backend
Definition: DummyRegisterAccessor.h:367
ChimeraTK::proxies::DummyRegisterSequence
Temporary proxy class for sequences, used in the DummyMultiplexedRegister class.
Definition: DummyRegisterAccessor.h:81
ChimeraTK::DummyRegisterRawAccessor::buffer
int32_t * buffer
raw buffer of this accessor
Definition: DummyRegisterAccessor.h:373
ChimeraTK::DummyRegisterAccessor
Register accessor for accessing single word or 1D array registers internally of a DummyBackend implem...
Definition: DummyBackend.h:20
ChimeraTK::DummyRegisterAccessor::registerInfo
NumericAddressedRegisterInfo registerInfo
register map information
Definition: DummyRegisterAccessor.h:190
ChimeraTK::NumericAddressedRegisterInfo::nElements
uint32_t nElements
Number of elements in register.
Definition: NumericAddressedRegisterCatalogue.h:110
ChimeraTK::NumericAddressedRegisterInfo
Definition: NumericAddressedRegisterCatalogue.h:15
ChimeraTK::DummyMultiplexedRegisterAccessor
Register accessor for accessing multiplexed 2D array registers internally of a DummyBackend implement...
Definition: DummyBackend.h:23
DummyBackend.h
ChimeraTK::DummyMultiplexedRegisterAccessor::getBackend
DummyBackend & getBackend() const
Return the backend.
Definition: DummyRegisterAccessor.h:281
ChimeraTK::DummyRegisterRawAccessor::registerInfo
NumericAddressedRegisterInfo registerInfo
register map information
Definition: DummyRegisterAccessor.h:370
ChimeraTK::DummyBackend::setWriteCallbackFunction
void setWriteCallbackFunction(AddressRange addressRange, boost::function< void(void)> const &writeCallbackFunction)
Definition: DummyBackend.cc:100
ChimeraTK::DummyBackend::mutex
std::mutex mutex
Definition: DummyBackend.h:106
ChimeraTK::proxies::DummyRegisterElement::operator--
T operator--(int)
post-decrement operator
Definition: DummyRegisterAccessor.h:57
ChimeraTK::proxies::DummyRegisterElement::fpcptr
FixedPointConverter * fpcptr
fixed point converter to be used for this element
Definition: DummyRegisterAccessor.h:68
ChimeraTK::DummyRegisterRawAccessor::operator[]
int32_t & operator[](unsigned int index)
Get or set register content by [] operator.
Definition: DummyRegisterAccessor.h:355
ChimeraTK::DummyRegisterRawAccessor::operator=
DummyRegisterRawAccessor & operator=(int32_t rhs)
Definition: DummyRegisterAccessor.h:349
ChimeraTK::DummyMultiplexedRegisterAccessor::_path
RegisterPath _path
path of the register
Definition: DummyRegisterAccessor.h:296
ChimeraTK::DummyRegisterAccessor::operator=
void operator=(const DummyRegisterAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing *‍/
ChimeraTK::proxies::DummyRegisterElement::DummyRegisterElement
DummyRegisterElement(FixedPointConverter *_fpc, int _nbytes, int32_t *_buffer)
Definition: DummyRegisterAccessor.h:22
ChimeraTK::DummyMultiplexedRegisterAccessor::nElements
unsigned int nElements
number of elements per sequence
Definition: DummyRegisterAccessor.h:311
ChimeraTK::DummyRegisterAccessor::getBufferLock
std::unique_lock< std::mutex > getBufferLock()
Get a lock to safely modify the buffer in a multi-treaded environment.
Definition: DummyRegisterAccessor.h:183
ChimeraTK::DummyMultiplexedRegisterAccessor::nbytes
std::vector< uint32_t > nbytes
number of bytes per word for sequences
Definition: DummyRegisterAccessor.h:305
ChimeraTK::proxies::DummyRegisterElement::DummyRegisterElement
DummyRegisterElement()
constructor when used as a base class in DummyRegister
Definition: DummyRegisterAccessor.h:65
ChimeraTK::proxies::DummyRegisterElement::nbytes
int nbytes
number of bytes per word
Definition: DummyRegisterAccessor.h:71
ChimeraTK::proxies::DummyRegisterSequence::fpcptr
FixedPointConverter * fpcptr
fixed point converter to be used for this sequence
Definition: DummyRegisterAccessor.h:102
ChimeraTK::NumericAddressedBackend::_registerMap
NumericAddressedRegisterCatalogue & _registerMap
Definition: NumericAddressedBackend.h:153
ChimeraTK::NumericAddressedRegisterInfo::pathName
RegisterPath pathName
Definition: NumericAddressedRegisterCatalogue.h:108
ChimeraTK::DummyMultiplexedRegisterAccessor::operator[]
proxies::DummyRegisterSequence< T > operator[](unsigned int sequence)
Get or set register content by [] operators.
Definition: DummyRegisterAccessor.h:270
ChimeraTK::DummyRegisterAccessor::getRegisterInfo
const NumericAddressedRegisterInfo & getRegisterInfo()
Definition: DummyRegisterAccessor.h:178
ChimeraTK::DummyMultiplexedRegisterAccessor::getNumberOfSequences
unsigned int getNumberOfSequences()
return number of sequences
Definition: DummyRegisterAccessor.h:263
ChimeraTK::DummyRegisterRawAccessor::operator=
void operator=(const DummyRegisterRawAccessor &rightHandSide) const =delete
remove assignment operator since it will be confusing
ChimeraTK::DummyRegisterAccessor::operator[]
proxies::DummyRegisterElement< T > operator[](unsigned int index)
Get or set register content by [] operator.
Definition: DummyRegisterAccessor.h:155
ChimeraTK::NumericAddressedRegisterInfo::bar
uint64_t bar
Upper part of the address (name originally from PCIe, meaning now generalised)
Definition: NumericAddressedRegisterCatalogue.h:113
ChimeraTK::DummyRegisterRawAccessor::DummyRegisterRawAccessor
DummyRegisterRawAccessor(boost::shared_ptr< DeviceBackend > const &backend, std::string const &module, std::string const &name)
Definition: DummyRegisterAccessor.h:331
ChimeraTK::proxies::DummyRegisterSequence::buffer
int32_t * buffer
reference to the raw buffer (first word of the sequence)
Definition: DummyRegisterAccessor.h:111
ChimeraTK::DummyBackend::_barContents
std::map< uint64_t, std::vector< int32_t > > _barContents
Definition: DummyBackend.h:103
ChimeraTK::proxies::DummyRegisterElement::operator++
DummyRegisterElement< T > operator++()
pre-increment operator
Definition: DummyRegisterAccessor.h:38
ChimeraTK::proxies::DummyRegisterSequence::pitch
int pitch
pitch in bytes (distance between samples of the same sequence)
Definition: DummyRegisterAccessor.h:108
ChimeraTK::DummyRegisterAccessor::getRegisterPath
const RegisterPath & getRegisterPath() const
Return the register path.
Definition: DummyRegisterAccessor.h:167
ChimeraTK::DummyRegisterRawAccessor
Accessor for raw 32 bit integer access to the underlying memory space.
Definition: DummyRegisterAccessor.h:324
ChimeraTK::DummyRegisterAccessor::getNumberOfElements
unsigned int getNumberOfElements()
return number of elements
Definition: DummyRegisterAccessor.h:158
ChimeraTK::proxies::DummyRegisterSequence::operator[]
DummyRegisterElement< T > operator[](unsigned int sample)
Get or set register content by [] operator.
Definition: DummyRegisterAccessor.h:87
ChimeraTK::DummyRegisterAccessor::DummyRegisterAccessor
DummyRegisterAccessor(DummyBackend *dev, std::string const &module, std::string const &name)
Constructor should normally be called in the constructor of the DummyBackend implementation.
Definition: DummyRegisterAccessor.h:138
ChimeraTK::NumericAddressedRegisterInfo::channels
std::vector< ChannelInfo > channels
Define per-channel information (bit interpretation etc.), 1D/scalars have exactly one entry.
Definition: NumericAddressedRegisterCatalogue.h:120
ChimeraTK::proxies::DummyRegisterElement
Temporary proxy class for use in the DummyRegister and DummyMultiplexedRegister classes.
Definition: DummyRegisterAccessor.h:20
ChimeraTK::DummyMultiplexedRegisterAccessor::getRegisterInfo
const NumericAddressedRegisterInfo & getRegisterInfo()
Definition: DummyRegisterAccessor.h:286
ChimeraTK::DummyMultiplexedRegisterAccessor::registerInfo
NumericAddressedRegisterInfo registerInfo
register map information
Definition: DummyRegisterAccessor.h:293
ChimeraTK::DummyMultiplexedRegisterAccessor::offsets
std::vector< uint32_t > offsets
offsets in bytes for sequences
Definition: DummyRegisterAccessor.h:302
ChimeraTK::NumericAddressedRegisterInfo::elementPitchBits
uint32_t elementPitchBits
Distance in bits (!) between two elements (of the same channel)
Definition: NumericAddressedRegisterCatalogue.h:111
ChimeraTK::DummyMultiplexedRegisterAccessor::fpc
std::vector< FixedPointConverter > fpc
pointer to fixed point converter
Definition: DummyRegisterAccessor.h:299
ChimeraTK::RegisterPath
Class to store a register path name.
Definition: RegisterPath.h:16
ChimeraTK::DummyMultiplexedRegisterAccessor::DummyMultiplexedRegisterAccessor
DummyMultiplexedRegisterAccessor(DummyBackend *dev, std::string const &module, std::string const &name)
Constructor should normally be called in the constructor of the DummyBackend implementation.
Definition: DummyRegisterAccessor.h:229
ChimeraTK::proxies::DummyRegisterSequence::DummyRegisterSequence
DummyRegisterSequence(FixedPointConverter *_fpc, int _nbytes, int _pitch, int32_t *_buffer)
Definition: DummyRegisterAccessor.h:83
NumericAddressedBackendMuxedRegisterAccessor.h
ChimeraTK::FixedPointConverter
The fixed point converter provides conversion functions between a user type and up to 32 bit fixed po...
Definition: FixedPointConverter.h:28
ChimeraTK::DummyMultiplexedRegisterAccessor::pitch
int pitch
pitch in bytes (distance between samples of the same sequence)
Definition: DummyRegisterAccessor.h:308
ChimeraTK::DummyBackend
The dummy device opens a mapping file instead of a device, and implements all registers defined in th...
Definition: DummyBackend.h:45
ChimeraTK::proxies::DummyRegisterElement::operator--
DummyRegisterElement< T > operator--()
pre-decrement operator
Definition: DummyRegisterAccessor.h:44
ChimeraTK::FixedPointConverter::toRaw
uint32_t toRaw(UserType cookedValue) const
Conversion function from type T to fixed point.
Definition: FixedPointConverter.h:336
ChimeraTK::DummyMultiplexedRegisterAccessor::getRegisterPath
const RegisterPath & getRegisterPath() const
Return the register path.
Definition: DummyRegisterAccessor.h:284
ChimeraTK::DummyMultiplexedRegisterAccessor::_dev
DummyBackend * _dev
pointer to VirtualDevice
Definition: DummyRegisterAccessor.h:290
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::DummyRegisterAccessor::fpc
FixedPointConverter fpc
fixed point converter
Definition: DummyRegisterAccessor.h:196
ChimeraTK::DummyRegisterAccessor::setWriteCallback
void setWriteCallback(const std::function< void()> &writeCallback)
Set callback function which is called when the register is written to (through the normal Device inte...
Definition: DummyRegisterAccessor.h:170
ChimeraTK::DummyRegisterAccessor::_dev
DummyBackend * _dev
pointer to VirtualDevice
Definition: DummyRegisterAccessor.h:187
ChimeraTK::proxies::DummyRegisterElement::operator=
DummyRegisterElement< T > & operator=(T rhs)
assignment operator
Definition: DummyRegisterAccessor.h:31
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
ChimeraTK::DummyRegisterRawAccessor::getBufferLock
std::unique_lock< std::mutex > getBufferLock()
Get a lock to safely modify the buffer.
Definition: DummyRegisterAccessor.h:363
ChimeraTK::proxies::DummyRegisterElement::buffer
int32_t * buffer
raw buffer of this element
Definition: DummyRegisterAccessor.h:74