ChimeraTK-DeviceAccess  03.18.00
Device.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 "AccessMode.h"
6 #include "DeviceBackend.h"
7 #include "ForwardDeclarations.h"
8 #include "OneDRegisterAccessor.h"
10 #include "TwoDRegisterAccessor.h"
11 #include "VoidRegisterAccessor.h"
12 
13 #include <boost/algorithm/string.hpp>
14 #include <boost/shared_ptr.hpp>
15 
16 // These headers are added for convenience of application programmers:
17 #include "BackendFactory.h" // IWYU pragma: keep
18 #include "Exception.h" // IWYU pragma: keep
19 #include "Utilities.h" // IWYU pragma: keep (for setDMapFilePath())
20 
21 namespace ChimeraTK {
22 
39  class Device {
40  public:
53  Device() = default;
54 
68  explicit Device(const std::string& aliasName);
69 
73  void open(std::string const& aliasName);
74 
79  void open();
80 
85  void close();
86 
100  template<typename UserType>
101  [[nodiscard]] ScalarRegisterAccessor<UserType> getScalarRegisterAccessor(const RegisterPath& registerPathName,
102  size_t wordOffsetInRegister = 0, const AccessModeFlags& flags = AccessModeFlags({})) const;
103 
108  const RegisterPath& registerPathName, const AccessModeFlags& flags = AccessModeFlags({})) const;
109 
127  template<typename UserType>
128  [[nodiscard]] OneDRegisterAccessor<UserType> getOneDRegisterAccessor(const RegisterPath& registerPathName,
129  size_t numberOfWords = 0, size_t wordOffsetInRegister = 0,
130  const AccessModeFlags& flags = AccessModeFlags({})) const;
131 
145  template<typename UserType>
147  size_t numberOfElements = 0, size_t elementsOffset = 0,
148  const AccessModeFlags& flags = AccessModeFlags({})) const;
149 
153  [[nodiscard]] RegisterCatalogue getRegisterCatalogue() const;
154 
158  [[nodiscard]] MetadataCatalogue getMetadataCatalogue() const;
159 
163  [[nodiscard]] std::string readDeviceInfo() const;
164 
168  [[nodiscard]] bool isOpened() const;
169 
174  [[nodiscard]] bool isFunctional() const;
175 
184  void activateAsyncRead() noexcept;
185 
194  void setException(const std::string& message);
195 
201  [[nodiscard]] boost::shared_ptr<DeviceBackend> getBackend();
202 
211  template<typename UserType>
212  [[nodiscard]] UserType read(
213  const RegisterPath& registerPathName, const AccessModeFlags& flags = AccessModeFlags({})) const;
214 
226  template<typename UserType>
227  [[nodiscard]] std::vector<UserType> read(const RegisterPath& registerPathName, size_t numberOfWords,
228  size_t wordOffsetInRegister = 0, const AccessModeFlags& flags = AccessModeFlags({})) const;
229 
238  template<typename UserType>
239  void write(
240  const RegisterPath& registerPathName, UserType value, const AccessModeFlags& flags = AccessModeFlags({}));
241 
250  template<typename UserType>
251  void write(const RegisterPath& registerPathName, const std::vector<UserType>& vector,
252  size_t wordOffsetInRegister = 0, const AccessModeFlags& flags = AccessModeFlags({}));
253 
254  protected:
255  boost::shared_ptr<DeviceBackend> _deviceBackendPointer;
256 
257  void checkPointersAreNotNull() const;
258  };
259 
260  /********************************************************************************************************************/
261 
262  template<typename UserType>
264  const RegisterPath& registerPathName, size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
267  _deviceBackendPointer->getRegisterAccessor<UserType>(registerPathName, 1, wordOffsetInRegister, flags));
268  }
269 
270  /********************************************************************************************************************/
271 
272  template<typename UserType>
274  size_t numberOfWords, size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
276  return OneDRegisterAccessor<UserType>(_deviceBackendPointer->getRegisterAccessor<UserType>(
277  registerPathName, numberOfWords, wordOffsetInRegister, flags));
278  }
279 
280  /********************************************************************************************************************/
281 
282  template<typename UserType>
284  size_t numberOfElements, size_t elementsOffset, const AccessModeFlags& flags) const {
286  return TwoDRegisterAccessor<UserType>(_deviceBackendPointer->getRegisterAccessor<UserType>(
287  registerPathName, numberOfElements, elementsOffset, flags));
288  }
289 
290  /********************************************************************************************************************/
291 
292  template<typename UserType>
293  UserType Device::read(const RegisterPath& registerPathName, const AccessModeFlags& flags) const {
294  auto acc = getScalarRegisterAccessor<UserType>(registerPathName, 0, flags);
295  acc.read();
296  return acc;
297  }
298 
299  /********************************************************************************************************************/
300 
301  template<typename UserType>
302  std::vector<UserType> Device::read(const RegisterPath& registerPathName, size_t numberOfWords,
303  size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
304  auto acc = getOneDRegisterAccessor<UserType>(registerPathName, numberOfWords, wordOffsetInRegister, flags);
305  acc.read();
306  std::vector<UserType> vector(acc.getNElements());
307  acc.swap(vector);
308  return vector;
309  }
310 
311  /********************************************************************************************************************/
312 
313  template<typename UserType>
314  void Device::write(const RegisterPath& registerPathName, UserType value, const AccessModeFlags& flags) {
315  auto acc = getScalarRegisterAccessor<UserType>(registerPathName, 0, flags);
316  acc = value;
317  acc.write();
318  }
319 
320  /********************************************************************************************************************/
321 
322  template<typename UserType>
323  void Device::write(const RegisterPath& registerPathName, const std::vector<UserType>& vector,
324  size_t wordOffsetInRegister, const AccessModeFlags& flags) {
325  auto acc = getOneDRegisterAccessor<UserType>(registerPathName, vector.size(), wordOffsetInRegister, flags);
326  // the vector stays constant, but we have to work around so we can swap it and
327  // later swap it back...
328  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
329  auto& mutable_vector = const_cast<std::vector<UserType>&>(vector);
330  acc.swap(mutable_vector);
331  acc.write();
332  acc.swap(mutable_vector);
333  }
334 
335  /********************************************************************************************************************/
336 
337 } // namespace ChimeraTK
ChimeraTK::TwoDRegisterAccessor
Accessor class to read and write 2D registers.
Definition: ForwardDeclarations.h:20
VoidRegisterAccessor.h
ForwardDeclarations.h
DeviceBackend.h
ChimeraTK::Device::close
void close()
Close the device.
Definition: Device.cc:66
ChimeraTK::Device::getOneDRegisterAccessor
OneDRegisterAccessor< UserType > getOneDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords=0, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a OneDRegisterAccessor object for the given register.
Definition: Device.h:273
ChimeraTK::Device::getBackend
boost::shared_ptr< DeviceBackend > getBackend()
Obtain the backend.
Definition: Device.cc:111
ChimeraTK::Device::getVoidRegisterAccessor
VoidRegisterAccessor getVoidRegisterAccessor(const RegisterPath &registerPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a VoidRegisterAccessor object for the given register.
Definition: Device.cc:103
Utilities.h
ChimeraTK::Device::read
UserType read(const RegisterPath &registerPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Inefficient convenience function to read a single-word register without obtaining an accessor.
Definition: Device.h:293
TwoDRegisterAccessor.h
OneDRegisterAccessor.h
ChimeraTK::MetadataCatalogue
Container for backend metadata.
Definition: MetadataCatalogue.h:17
ChimeraTK::Device::Device
Device()=default
Create device instance without associating a backend yet.
ChimeraTK::ScalarRegisterAccessor
Accessor class to read and write scalar registers transparently by using the accessor object like a v...
Definition: ScalarRegisterAccessor.h:24
ChimeraTK::Device::readDeviceInfo
std::string readDeviceInfo() const
Return a device information string.
Definition: Device.cc:36
ChimeraTK::RegisterCatalogue
Catalogue of register information.
Definition: RegisterCatalogue.h:20
ScalarRegisterAccessor.h
ChimeraTK::OneDRegisterAccessor
Accessor class to read and write registers transparently by using the accessor object like a vector o...
Definition: OneDRegisterAccessor.h:20
ChimeraTK::Device::open
void open()
Re-open the device after previously closeing it by calling close(), or when it was constructed with a...
Definition: Device.cc:51
ChimeraTK::Device::activateAsyncRead
void activateAsyncRead() noexcept
Activate asyncronous read for all transfer elements where AccessMode::wait_for_new_data is set.
Definition: Device.cc:91
ChimeraTK::Device::_deviceBackendPointer
boost::shared_ptr< DeviceBackend > _deviceBackendPointer
Definition: Device.h:255
ChimeraTK::VoidRegisterAccessor
Accessor class to read and write void-typed registers.
Definition: VoidRegisterAccessor.h:14
ChimeraTK::Device::getRegisterCatalogue
RegisterCatalogue getRegisterCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition: Device.cc:22
ChimeraTK::Device
Class allows to read/write registers from device.
Definition: Device.h:39
ChimeraTK::RegisterPath
Class to store a register path name.
Definition: RegisterPath.h:16
ChimeraTK::Device::getTwoDRegisterAccessor
TwoDRegisterAccessor< UserType > getTwoDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfElements=0, size_t elementsOffset=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a TwoDRegisterAccessor object for the given register.
Definition: Device.h:283
ChimeraTK::Device::getScalarRegisterAccessor
ScalarRegisterAccessor< UserType > getScalarRegisterAccessor(const RegisterPath &registerPathName, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a ScalarRegisterObject object for the given register.
Definition: Device.h:263
BackendFactory.h
AccessMode.h
ChimeraTK::Device::isOpened
bool isOpened() const
Check if the device is currently opened.
Definition: Device.cc:73
ChimeraTK::Device::checkPointersAreNotNull
void checkPointersAreNotNull() const
Definition: Device.cc:43
ChimeraTK::Device::getMetadataCatalogue
MetadataCatalogue getMetadataCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition: Device.cc:29
ChimeraTK::AccessModeFlags
Set of AccessMode flags with additional functionality for an easier handling.
Definition: AccessMode.h:48
Exception.h
ChimeraTK::Device::write
void write(const RegisterPath &registerPathName, UserType value, const AccessModeFlags &flags=AccessModeFlags({}))
Inefficient convenience function to write a single-word register without obtaining an accessor.
Definition: Device.h:314
ChimeraTK::Device::isFunctional
bool isFunctional() const
Return wether a device is working as intended, usually this means it is opened and does not have any ...
Definition: Device.cc:82
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::Device::setException
void setException(const std::string &message)
Set the device into an exception state.
Definition: Device.cc:97