ChimeraTK-DeviceAccess  03.18.00
SubdeviceBackend.cc
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 
4 #include "SubdeviceBackend.h"
5 
6 #include "BackendFactory.h"
7 #include "Exception.h"
8 #include "FixedPointConverter.h"
9 #include "MapFileParser.h"
12 #include "TransferElement.h"
13 
14 #include <boost/algorithm/string.hpp>
15 #include <boost/algorithm/string/predicate.hpp>
16 
17 #include <utility>
18 
19 using namespace std::string_literals;
20 
21 namespace ChimeraTK {
22 
23  boost::shared_ptr<DeviceBackend> SubdeviceBackend::createInstance(
24  std::string address, std::map<std::string, std::string> parameters) {
25  if(parameters["map"].empty()) {
26  throw ChimeraTK::logic_error("Map file name not specified.");
27  }
28 
29  if(!address.empty()) {
30  if(parameters.size() > 1) {
31  throw ChimeraTK::logic_error("SubdeviceBackend: You cannot specify both the address string and "
32  "parameters "
33  "other than the map file in the device descriptor.");
34  }
35  // decode target information from the instance
36  std::vector<std::string> tokens;
37  boost::split(tokens, address, boost::is_any_of(","));
38  if(tokens.size() != 3) {
39  throw ChimeraTK::logic_error("SubdeviceBackend: There must be exactly 3 "
40  "parameters in the address string.");
41  }
42  parameters["type"] = tokens[0];
43  parameters["device"] = tokens[1];
44  parameters["area"] = tokens[2];
45  }
46 
47  return boost::shared_ptr<DeviceBackend>(new SubdeviceBackend(parameters));
48  }
49 
50  /********************************************************************************************************************/
51 
52  SubdeviceBackend::SubdeviceBackend(std::map<std::string, std::string> parameters) {
53  FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(getRegisterAccessor_impl);
54 
55  // check if type is specified
56  if(parameters["type"].empty()) {
57  throw ChimeraTK::logic_error("SubdeviceBackend: Type must be specified in the device descriptor.");
58  }
59 
60  // check if target device is specified and open the target device
61  if(parameters["device"].empty()) {
62  throw ChimeraTK::logic_error("SubdeviceBackend: Target device name must be "
63  "specified in the device descriptor.");
64  }
65  targetAlias = parameters["device"];
66 
67  // type "area":
68  if(parameters["type"] == "area") {
69  type = Type::area;
70  }
71  else if(parameters["type"] == "areaHandshake") {
72  type = Type::areaHandshake;
73  }
74  // type "3regs":
75  else if(parameters["type"] == "3regs") {
76  type = Type::threeRegisters;
77  }
78  else if(parameters["type"] == "2regs") {
79  type = Type::twoRegisters;
80 
81  if(parameters["sleep"].empty()) {
82  throw ChimeraTK::logic_error("SubdeviceBackend: Target sleep time must be specified in the device "
83  "descriptor for type '2regs'.");
84  }
85  }
86  // unknown type
87  else {
88  throw ChimeraTK::logic_error("SubdeviceBackend: Unknown type '" + parameters["type"] + "' specified.");
89  }
90 
91  if(needAreaParam()) {
92  // check if target register name is specified
93  if(parameters["area"].empty()) {
94  throw ChimeraTK::logic_error("SubdeviceBackend: Target register name "
95  "must be specified in the device "
96  "descriptor for types 'area' and 'areaHandshake'.");
97  }
98  targetArea = parameters["area"];
99  }
100  else {
101  // if area is not given, data and address are required
102  if(parameters["data"].empty()) {
103  throw ChimeraTK::logic_error("SubdeviceBackend: Target data register "
104  "name must be specified in the device "
105  "descriptor for types '2regs' and '3regs'.");
106  }
107  targetData = parameters["data"];
108 
109  // check if all target register names are specified
110  if(parameters["address"].empty()) {
111  throw ChimeraTK::logic_error("SubdeviceBackend: Target address register "
112  "name must be specified in the device "
113  "descriptor for type '2regs' and '3regs'.");
114  }
115  targetAddress = parameters["address"];
116  // optional parameter for delay between address write and data write
117  if(!parameters["dataDelay"].empty()) {
118  try {
119  addressToDataDelay = std::stoul(parameters["dataDelay"]);
120  }
121  catch(std::exception& e) {
122  throw ChimeraTK::logic_error("SubdeviceBackend: Invalid value for parameter 'dataDelay': '" +
123  parameters["dataDelay"] + "': " + e.what());
124  }
125  }
126  }
127  if(needStatusParam()) {
128  if(parameters["status"].empty()) {
129  throw ChimeraTK::logic_error("SubdeviceBackend: Target status register "
130  "name must be specified in the device "
131  "descriptor for types '3regs' and 'areaHandshake'.");
132  }
133  targetControl = parameters["status"];
134  if(!parameters["timeout"].empty()) {
135  try {
136  timeout = std::stoul(parameters["timeout"]);
137  }
138  catch(std::exception& e) {
140  "SubdeviceBackend: Invalid value for parameter 'timeout': '" + parameters["timeout"] + "': " + e.what());
141  }
142  }
143  }
144  // sleep parameter for 2regs, 3regs or areaHandshake case
145  if(!parameters["sleep"].empty()) {
146  try {
147  sleepTime = std::stoul(parameters["sleep"]);
148  }
149  catch(std::exception& e) {
151  "SubdeviceBackend: Invalid value for parameter 'sleep': '" + parameters["sleep"] + "': " + e.what());
152  }
153  }
154  // parse map file
155  if(parameters["map"].empty()) {
156  throw ChimeraTK::logic_error("SubdeviceBackend: Map file must be specified.");
157  }
158  MapFileParser parser;
159  std::tie(_registerMap, _metadataCatalogue) = parser.parse(parameters["map"]);
160  if(type == Type::twoRegisters || type == Type::threeRegisters) {
161  // FIXME: Turn off readable flag in 2reg/3reg mode
162  for(auto info : _registerMap) {
163  // we are modifying a copy here
164  info.registerAccess = NumericAddressedRegisterInfo::Access::WRITE_ONLY;
165  _registerMap.modifyRegister(info); // Should be OK. Should not change the iterator
166  }
167  }
168  }
169 
170  /********************************************************************************************************************/
171 
172  void SubdeviceBackend::obtainTargetBackend() {
173  if(targetDevice != nullptr) return;
174  BackendFactory& factoryInstance = BackendFactory::getInstance();
175  targetDevice = factoryInstance.createBackend(targetAlias);
176  }
177 
178  /********************************************************************************************************************/
179 
180  void SubdeviceBackend::open() {
181  obtainTargetBackend();
182  // open target backend, unconditionally as it is also used for recovery
183  targetDevice->open();
184  setOpenedAndClearException();
185  }
186 
187  /********************************************************************************************************************/
188 
189  void SubdeviceBackend::close() {
190  obtainTargetBackend();
191  targetDevice->close();
192  _opened = false;
193  }
194 
195  /********************************************************************************************************************/
196 
197  RegisterCatalogue SubdeviceBackend::getRegisterCatalogue() const {
198  return RegisterCatalogue(_registerMap.clone());
199  }
200 
201  /********************************************************************************************************************/
202 
203  MetadataCatalogue SubdeviceBackend::getMetadataCatalogue() const {
204  return _metadataCatalogue;
205  }
206 
207  /********************************************************************************************************************/
208 
209  template<typename UserType, typename TargetUserType>
210  class FixedPointConvertingDecorator : public NDRegisterAccessorDecorator<UserType, TargetUserType> {
211  public:
213  FixedPointConverter fixedPointConverter)
214  : NDRegisterAccessorDecorator<UserType, TargetUserType>(target),
215  _fixedPointConverter(std::move(fixedPointConverter)) {}
216 
217  void doPreRead(TransferType type) override { _target->preRead(type); }
218 
219  void doPostRead(TransferType type, bool hasNewData) override {
220  _target->postRead(type, hasNewData);
221  if(!hasNewData) return;
222  for(size_t i = 0; i < this->buffer_2D.size(); ++i) {
223  _fixedPointConverter.template vectorToCooked<UserType>(
224  _target->accessChannel(i).begin(), _target->accessChannel(i).end(), buffer_2D[i].begin());
225  }
226  this->_dataValidity = _target->dataValidity();
227  this->_versionNumber = _target->getVersionNumber();
228  }
229 
230  void doPreWrite(TransferType type, VersionNumber versionNumber) override {
231  for(size_t i = 0; i < this->buffer_2D.size(); ++i) {
232  for(size_t j = 0; j < this->buffer_2D[i].size(); ++j) {
233  _target->accessChannel(i)[j] = _fixedPointConverter.toRaw<UserType>(buffer_2D[i][j]);
234  }
235  }
236  _target->setDataValidity(this->_dataValidity);
237  _target->preWrite(type, versionNumber);
238  }
239 
240  void doPostWrite(TransferType type, VersionNumber versionNumber) override {
241  _target->postWrite(type, versionNumber);
242  }
243 
244  [[nodiscard]] bool mayReplaceOther(
245  const boost::shared_ptr<ChimeraTK::TransferElement const>& other) const override {
246  auto casted = boost::dynamic_pointer_cast<FixedPointConvertingDecorator<UserType, TargetUserType> const>(other);
247  if(!casted) return false;
248  if(_fixedPointConverter != casted->_fixedPointConverter) return false;
249  return _target->mayReplaceOther(casted->_target);
250  }
251 
252  protected:
254 
257  };
258 
259  /********************************************************************************************************************/
260 
261  template<typename TargetUserType>
263  public:
265  FixedPointConverter fixedPointConverter)
266  : NDRegisterAccessorDecorator<TargetUserType>(target), _fixedPointConverter(std::move(fixedPointConverter)) {
267  FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(getAsCooked_impl);
268  FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(setAsCooked_impl);
269  }
270 
271  template<typename COOKED_TYPE>
272  COOKED_TYPE getAsCooked_impl(unsigned int channel, unsigned int sample) {
273  std::vector<int32_t> rawVector(1);
274  std::vector<COOKED_TYPE> cookedVector(1);
275  rawVector[0] = buffer_2D[channel][sample];
276  _fixedPointConverter.template vectorToCooked<COOKED_TYPE>(
277  rawVector.begin(), rawVector.end(), cookedVector.begin());
278  return cookedVector[0];
279  }
280 
281  template<typename COOKED_TYPE>
282  void setAsCooked_impl(unsigned int channel, unsigned int sample, COOKED_TYPE value) {
283  buffer_2D[channel][sample] = _fixedPointConverter.toRaw<COOKED_TYPE>(value);
284  }
285 
286  [[nodiscard]] bool mayReplaceOther(
287  const boost::shared_ptr<ChimeraTK::TransferElement const>& other) const override {
288  auto casted = boost::dynamic_pointer_cast<FixedPointConvertingRawDecorator<TargetUserType> const>(other);
289  if(!casted) return false;
290  if(_fixedPointConverter != casted->_fixedPointConverter) return false;
291  return _target->mayReplaceOther(casted->_target);
292  }
293 
294  protected:
296 
301 
304  };
305 
306  /********************************************************************************************************************/
307 
308  template<typename UserType>
309  boost::shared_ptr<NDRegisterAccessor<UserType>> SubdeviceBackend::getRegisterAccessor_impl(
310  const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags) {
311  obtainTargetBackend();
312  boost::shared_ptr<NDRegisterAccessor<UserType>> returnValue;
313  if(type == Type::area) {
314  returnValue = getRegisterAccessor_area<UserType>(registerPathName, numberOfWords, wordOffsetInRegister, flags);
315  }
316  else if(type == Type::threeRegisters || type == Type::twoRegisters || type == Type::areaHandshake) {
317  returnValue =
318  getRegisterAccessor_synchronized<UserType>(registerPathName, numberOfWords, wordOffsetInRegister, flags);
319  }
320  if(!returnValue) {
321  throw ChimeraTK::logic_error("Unknown type");
322  }
323  returnValue->setExceptionBackend(shared_from_this());
324 
325  return returnValue;
326  }
327 
328  /********************************************************************************************************************/
329 
330  void SubdeviceBackend::verifyRegisterAccessorSize(const NumericAddressedRegisterInfo& info, size_t& numberOfWords,
331  size_t wordOffsetInRegister, bool forceAlignment) {
332  // check that the bar is 0
333  if(info.bar != 0) {
334  // throw ChimeraTK::logic_error("SubdeviceBackend: BARs other then 0 are not supported. Register '" +
335  // registerPathName + "' is in BAR " + std::to_string(info->bar) + ".");
336  std::cout << "SubdeviceBackend: WARNING: BAR others then 0 detected. BAR 0 will be used instead. Register "
337  << info.pathName << " is in BAR " << std::to_string(info.bar) << "." << std::endl;
338  }
339 
340  // check that the register is not a 2D multiplexed register, which is not yet
341  // supported
342  if(info.channels.size() != 1) {
343  throw ChimeraTK::logic_error("SubdeviceBackend: 2D multiplexed registers are not yet supported.");
344  }
345 
346  // compute full offset (from map file and function arguments)
347  size_t byteOffset = info.address + sizeof(int32_t) * wordOffsetInRegister;
348  if(forceAlignment && (byteOffset % 4 != 0)) {
349  throw ChimeraTK::logic_error("SubdeviceBackend: Only addresses which are a "
350  "multiple of 4 are supported.");
351  }
352 
353  // compute effective length
354  if(numberOfWords == 0) {
355  numberOfWords = info.nElements;
356  }
357  else if(numberOfWords > info.nElements) {
358  throw ChimeraTK::logic_error("SubdeviceBackend: Requested " + std::to_string(numberOfWords) +
359  " elements from register '" + info.pathName + "', which only has a length of " +
360  std::to_string(info.nElements) + " elements.");
361  }
362 
363  // Check that the requested register fits in the register description. The downstream register might be larger
364  // so we cannot delegate the check
365  if(numberOfWords + wordOffsetInRegister > info.nElements) {
367  "SubdeviceBackend: Requested offset + number of words exceeds the size of the register '" + info.pathName +
368  "'!");
369  }
370  }
371 
372  /********************************************************************************************************************/
373 
374  template<typename UserType>
375  boost::shared_ptr<NDRegisterAccessor<UserType>> SubdeviceBackend::getRegisterAccessor_area(
376  const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags) {
377  assert(type == Type::area);
378 
379  // obtain register info
380  auto info = _registerMap.getBackendRegister(registerPathName);
381  verifyRegisterAccessorSize(info, numberOfWords, wordOffsetInRegister, true);
382 
383  // store raw flag for later (since we modify the flags)
384  bool isRaw = flags.has(AccessMode::raw);
385 
386  // obtain target accessor in raw mode
387  size_t wordOffset = (info.address + sizeof(int32_t) * wordOffsetInRegister) / 4;
388  flags.add(AccessMode::raw);
389  auto rawAcc = targetDevice->getRegisterAccessor<int32_t>(targetArea, numberOfWords, wordOffset, flags);
390 
391  // decorate with appropriate FixedPointConvertingDecorator. This is done even
392  // when in raw mode so we can properly implement getAsCooked()/setAsCooked().
393  if(!isRaw) {
394  return boost::make_shared<FixedPointConvertingDecorator<UserType, int32_t>>(rawAcc,
395  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
396  info.channels.front().signedFlag));
397  }
398  // this is handled by the template specialisation for int32_t
399  throw ChimeraTK::logic_error("Given UserType when obtaining the SubdeviceBackend in raw mode does not "s +
400  "match the expected type. Use an int32_t instead! (Register name: " + registerPathName + "')");
401  }
402 
403  /********************************************************************************************************************/
404 
405  boost::shared_ptr<SubdeviceRegisterAccessor> SubdeviceBackend::getRegisterAccessor_helper(
406  const NumericAddressedRegisterInfo& info, size_t numberOfWords, size_t wordOffsetInRegister,
407  AccessModeFlags flags) {
408  flags.checkForUnknownFlags({AccessMode::raw});
409 
410  verifyRegisterAccessorSize(info, numberOfWords, wordOffsetInRegister, false);
411 
412  // check if register access properly specified in map file
413  if(!info.isWriteable()) {
414  throw ChimeraTK::logic_error("SubdeviceBackend: Subdevices of type 3reg or "
415  "2reg or areaHandshake must have writeable registers only!");
416  }
417 
418  // obtain target accessors
419  boost::shared_ptr<NDRegisterAccessor<int32_t>> accAddress, accData;
420  if(!needAreaParam()) {
421  accAddress = targetDevice->getRegisterAccessor<int32_t>(targetAddress, 1, 0, {});
422  accData = targetDevice->getRegisterAccessor<int32_t>(targetData, 0, 0, {});
423  }
424  else {
425  // check alignment just like it is done in 'area' type subdevice which is based on raw int32 accessors to target
426  verifyRegisterAccessorSize(info, numberOfWords, wordOffsetInRegister, true);
427 
428  // obtain target accessor in raw mode
429  size_t wordOffset = (info.address + sizeof(int32_t) * wordOffsetInRegister) / 4;
430  flags.add(AccessMode::raw);
431  accData = targetDevice->getRegisterAccessor<int32_t>(targetArea, numberOfWords, wordOffset, flags);
432  }
433  boost::shared_ptr<NDRegisterAccessor<int32_t>> accStatus;
434  if(needStatusParam()) {
435  accStatus = targetDevice->getRegisterAccessor<int32_t>(targetControl, 1, 0, {});
436  }
437 
438  size_t byteOffset = info.address + sizeof(int32_t) * wordOffsetInRegister;
439  auto sharedThis = boost::enable_shared_from_this<DeviceBackend>::shared_from_this();
440 
441  return boost::make_shared<SubdeviceRegisterAccessor>(boost::dynamic_pointer_cast<SubdeviceBackend>(sharedThis),
442  info.pathName, accAddress, accData, accStatus, byteOffset, numberOfWords);
443  }
444 
445  /********************************************************************************************************************/
446 
447  template<typename UserType>
448  boost::shared_ptr<NDRegisterAccessor<UserType>> SubdeviceBackend::getRegisterAccessor_synchronized(
449  const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister,
450  const AccessModeFlags& flags) {
451  auto info = _registerMap.getBackendRegister(registerPathName);
452  boost::shared_ptr<SubdeviceRegisterAccessor> rawAcc =
453  getRegisterAccessor_helper(info, numberOfWords, wordOffsetInRegister, flags);
454 
455  // decorate with appropriate FixedPointConvertingDecorator. This is done even
456  // when in raw mode so we can properly implement getAsCooked()/setAsCooked().
457  if(!flags.has(AccessMode::raw)) {
458  return boost::make_shared<FixedPointConvertingDecorator<UserType, int32_t>>(rawAcc,
459  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
460  info.channels.front().signedFlag));
461  }
462  // this is handled by the template specialisation for int32_t
463  throw ChimeraTK::logic_error("Given UserType when obtaining the SubdeviceBackend in raw mode does not "s +
464  "match the expected type. Use an int32_t instead! (Register name: " + registerPathName + "')");
465  }
466 
467  /********************************************************************************************************************/
468 
469  template<>
470  boost::shared_ptr<NDRegisterAccessor<int32_t>> SubdeviceBackend::getRegisterAccessor_area<int32_t>(
471  const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister, AccessModeFlags flags) {
472  assert(type == Type::area);
473 
474  // obtain register info
475  auto info = _registerMap.getBackendRegister(registerPathName);
476  verifyRegisterAccessorSize(info, numberOfWords, wordOffsetInRegister, true);
477 
478  // store raw flag for later (since we modify the flags)
479  bool isRaw = flags.has(AccessMode::raw);
480 
481  // obtain target accessor in raw mode
482  size_t wordOffset = (info.address + sizeof(int32_t) * wordOffsetInRegister) / 4;
483  flags.add(AccessMode::raw);
484  auto rawAcc = targetDevice->getRegisterAccessor<int32_t>(targetArea, numberOfWords, wordOffset, flags);
485 
486  // decorate with appropriate FixedPointConvertingDecorator. This is done even
487  // when in raw mode so we can properly implement getAsCooked()/setAsCooked().
488  if(!isRaw) {
489  return boost::make_shared<FixedPointConvertingDecorator<int32_t, int32_t>>(rawAcc,
490  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
491  info.channels.front().signedFlag));
492  }
493  return boost::make_shared<FixedPointConvertingRawDecorator<int32_t>>(rawAcc,
494  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
495  info.channels.front().signedFlag));
496  }
497 
498  /********************************************************************************************************************/
499 
500  template<>
501  boost::shared_ptr<NDRegisterAccessor<int32_t>> SubdeviceBackend::getRegisterAccessor_synchronized<int32_t>(
502  const RegisterPath& registerPathName, size_t numberOfWords, size_t wordOffsetInRegister,
503  const AccessModeFlags& flags) {
504  auto info = _registerMap.getBackendRegister(registerPathName);
505  boost::shared_ptr<SubdeviceRegisterAccessor> rawAcc =
506  getRegisterAccessor_helper(info, numberOfWords, wordOffsetInRegister, flags);
507 
508  // decorate with appropriate FixedPointConvertingDecorator. This is done even
509  // when in raw mode so we can properly implement getAsCooked()/setAsCooked().
510  if(!flags.has(AccessMode::raw)) {
511  return boost::make_shared<FixedPointConvertingDecorator<int32_t, int32_t>>(rawAcc,
512  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
513  info.channels.front().signedFlag));
514  }
515  return boost::make_shared<FixedPointConvertingRawDecorator<int32_t>>(rawAcc,
516  FixedPointConverter(registerPathName, info.channels.front().width, info.channels.front().nFractionalBits,
517  info.channels.front().signedFlag));
518  }
519 
520  /********************************************************************************************************************/
521 
522  void SubdeviceBackend::setExceptionImpl() noexcept {
523  obtainTargetBackend();
524  targetDevice->setException(getActiveExceptionMessage());
525  }
526 
527  /********************************************************************************************************************/
528 
529  void SubdeviceBackend::activateAsyncRead() noexcept {
530  obtainTargetBackend();
531  targetDevice->activateAsyncRead();
532  }
533 
534 } // namespace ChimeraTK
ChimeraTK::FixedPointConvertingDecorator::_fixedPointConverter
FixedPointConverter _fixedPointConverter
Definition: SubdeviceBackend.cc:253
ChimeraTK::NumericAddressedRegisterInfo::address
uint64_t address
Lower part of the address relative to BAR, in bytes.
Definition: NumericAddressedRegisterCatalogue.h:114
ChimeraTK::FixedPointConvertingRawDecorator::setAsCooked_impl
void setAsCooked_impl(unsigned int channel, unsigned int sample, COOKED_TYPE value)
Definition: SubdeviceBackend.cc:282
ChimeraTK::BackendFactory::createBackend
boost::shared_ptr< DeviceBackend > createBackend(const std::string &aliasOrUri)
Create a new backend and return the instance as a shared pointer.
Definition: BackendFactory.cc:201
ChimeraTK::SubdeviceBackend
Backend for subdevices which are passed through some register or area of another device (subsequently...
Definition: SubdeviceBackend.h:57
MapFileParser.h
ChimeraTK::FixedPointConvertingDecorator::doPreWrite
void doPreWrite(TransferType type, VersionNumber versionNumber) override
Definition: SubdeviceBackend.cc:230
ChimeraTK::NumericAddressedRegisterInfo::nElements
uint32_t nElements
Number of elements in register.
Definition: NumericAddressedRegisterCatalogue.h:110
FixedPointConverter.h
ChimeraTK::NumericAddressedRegisterInfo
Definition: NumericAddressedRegisterCatalogue.h:15
TransferElement.h
ChimeraTK::FixedPointConvertingRawDecorator::FixedPointConvertingRawDecorator
FixedPointConvertingRawDecorator(const boost::shared_ptr< ChimeraTK::NDRegisterAccessor< TargetUserType >> &target, FixedPointConverter fixedPointConverter)
Definition: SubdeviceBackend.cc:264
ChimeraTK::MetadataCatalogue
Container for backend metadata.
Definition: MetadataCatalogue.h:17
ChimeraTK::FixedPointConvertingDecorator
Definition: SubdeviceBackend.cc:210
ChimeraTK::FixedPointConvertingDecorator::doPostRead
void doPostRead(TransferType type, bool hasNewData) override
Definition: SubdeviceBackend.cc:219
ChimeraTK::AccessModeFlags::add
void add(AccessMode flag)
Add the given flag to the set.
Definition: AccessMode.cc:62
ChimeraTK::FixedPointConvertingDecorator::FixedPointConvertingDecorator
FixedPointConvertingDecorator(const boost::shared_ptr< ChimeraTK::NDRegisterAccessor< TargetUserType >> &target, FixedPointConverter fixedPointConverter)
Definition: SubdeviceBackend.cc:212
FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE
#define FILL_VIRTUAL_FUNCTION_TEMPLATE_VTABLE(functionName)
Fill the vtable of a virtual function template defined with DEFINE_VIRTUAL_FUNCTION_TEMPLATE.
Definition: VirtualFunctionTemplate.h:84
ChimeraTK::MapFileParser
Provides method to parse MAP file.
Definition: MapFileParser.h:21
ChimeraTK::FixedPointConvertingDecorator::doPostWrite
void doPostWrite(TransferType type, VersionNumber versionNumber) override
Definition: SubdeviceBackend.cc:240
NDRegisterAccessorDecorator.h
ChimeraTK::RegisterCatalogue
Catalogue of register information.
Definition: RegisterCatalogue.h:20
ChimeraTK::FixedPointConvertingDecorator::mayReplaceOther
bool mayReplaceOther(const boost::shared_ptr< ChimeraTK::TransferElement const > &other) const override
Definition: SubdeviceBackend.cc:244
ChimeraTK::AccessModeFlags::has
bool has(AccessMode flag) const
Check if a certain flag is in the set.
Definition: AccessMode.cc:20
ChimeraTK::NumericAddressedRegisterInfo::pathName
RegisterPath pathName
Definition: NumericAddressedRegisterCatalogue.h:108
ChimeraTK::NumericAddressedRegisterInfo::bar
uint64_t bar
Upper part of the address (name originally from PCIe, meaning now generalised)
Definition: NumericAddressedRegisterCatalogue.h:113
ChimeraTK::BackendFactory
BackendFactory is a the factory class to create devices.
Definition: BackendFactory.h:26
SubdeviceRegisterAccessor.h
ChimeraTK::FixedPointConvertingRawDecorator::getAsCooked_impl
COOKED_TYPE getAsCooked_impl(unsigned int channel, unsigned int sample)
Definition: SubdeviceBackend.cc:272
ChimeraTK::TransferType
TransferType
Used to indicate the applicable operation on a Transferelement.
Definition: TransferElement.h:51
ChimeraTK::AccessModeFlags::checkForUnknownFlags
void checkForUnknownFlags(const std::set< AccessMode > &knownFlags) const
Check of any flag which is not in the given set "knownFlags" is set.
Definition: AccessMode.cc:32
ChimeraTK::NDRegisterAccessorDecorator
Base class for decorators of the NDRegisterAccessor.
Definition: NDRegisterAccessorDecorator.h:120
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::NumericAddressedRegisterInfo::isWriteable
bool isWriteable() const override
Return whether the register is writeable.
Definition: NumericAddressedRegisterCatalogue.h:90
ChimeraTK::FixedPointConvertingRawDecorator::mayReplaceOther
bool mayReplaceOther(const boost::shared_ptr< ChimeraTK::TransferElement const > &other) const override
Definition: SubdeviceBackend.cc:286
ChimeraTK::RegisterPath
Class to store a register path name.
Definition: RegisterPath.h:16
ChimeraTK::FixedPointConvertingRawDecorator
Definition: SubdeviceBackend.cc:262
BackendFactory.h
ChimeraTK::VersionNumber
Class for generating and holding version numbers without exposing a numeric representation.
Definition: VersionNumber.h:23
DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE_FILLER
#define DEFINE_VIRTUAL_FUNCTION_TEMPLATE_VTABLE_FILLER(className, functionName, numberOfArguments)
Compatibility, do not use.
Definition: VirtualFunctionTemplate.h:108
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::AccessModeFlags
Set of AccessMode flags with additional functionality for an easier handling.
Definition: AccessMode.h:48
Exception.h
ChimeraTK::FixedPointConvertingRawDecorator::_fixedPointConverter
FixedPointConverter _fixedPointConverter
Definition: SubdeviceBackend.cc:295
SubdeviceBackend.h
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::to_string
std::string to_string(Boolean &value)
Definition: SupportedUserTypes.h:59
ChimeraTK::NDRegisterAccessor< TargetUserType >
ChimeraTK::FixedPointConvertingDecorator::doPreRead
void doPreRead(TransferType type) override
Definition: SubdeviceBackend.cc:217
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
ChimeraTK::MapFileParser::parse
std::pair< NumericAddressedRegisterCatalogue, MetadataCatalogue > parse(const std::string &file_name)
Performs parsing of specified MAP file.
Definition: MapFileParser.cpp:19