ChimeraTK-DeviceAccess 03.20.00
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
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
21namespace 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>
146 TwoDRegisterAccessor<UserType> getTwoDRegisterAccessor(const RegisterPath& registerPathName,
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
204 [[nodiscard]] std::set<DeviceBackend::BackendID> getInvolvedBackendIDs();
205
214 template<typename UserType>
215 [[nodiscard]] UserType read(
216 const RegisterPath& registerPathName, const AccessModeFlags& flags = AccessModeFlags({})) const;
217
229 template<typename UserType>
230 [[nodiscard]] std::vector<UserType> read(const RegisterPath& registerPathName, size_t numberOfWords,
231 size_t wordOffsetInRegister = 0, const AccessModeFlags& flags = AccessModeFlags({})) const;
232
241 template<typename UserType>
242 void write(
243 const RegisterPath& registerPathName, UserType value, const AccessModeFlags& flags = AccessModeFlags({}));
244
253 template<typename UserType>
254 void write(const RegisterPath& registerPathName, const std::vector<UserType>& vector,
255 size_t wordOffsetInRegister = 0, const AccessModeFlags& flags = AccessModeFlags({}));
256
257 protected:
258 boost::shared_ptr<DeviceBackend> _deviceBackendPointer;
259
260 void checkPointersAreNotNull() const;
261 };
262
263 /********************************************************************************************************************/
264
265 template<typename UserType>
267 const RegisterPath& registerPathName, size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
270 _deviceBackendPointer->getRegisterAccessor<UserType>(registerPathName, 1, wordOffsetInRegister, flags));
271 }
272
273 /********************************************************************************************************************/
274
275 template<typename UserType>
277 size_t numberOfWords, size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
279 return OneDRegisterAccessor<UserType>(_deviceBackendPointer->getRegisterAccessor<UserType>(
280 registerPathName, numberOfWords, wordOffsetInRegister, flags));
281 }
282
283 /********************************************************************************************************************/
284
285 template<typename UserType>
287 size_t numberOfElements, size_t elementsOffset, const AccessModeFlags& flags) const {
289 return TwoDRegisterAccessor<UserType>(_deviceBackendPointer->getRegisterAccessor<UserType>(
290 registerPathName, numberOfElements, elementsOffset, flags));
291 }
292
293 /********************************************************************************************************************/
294
295 template<typename UserType>
296 UserType Device::read(const RegisterPath& registerPathName, const AccessModeFlags& flags) const {
297 auto acc = getScalarRegisterAccessor<UserType>(registerPathName, 0, flags);
298 acc.read();
299 return acc;
300 }
301
302 /********************************************************************************************************************/
303
304 template<typename UserType>
305 std::vector<UserType> Device::read(const RegisterPath& registerPathName, size_t numberOfWords,
306 size_t wordOffsetInRegister, const AccessModeFlags& flags) const {
307 auto acc = getOneDRegisterAccessor<UserType>(registerPathName, numberOfWords, wordOffsetInRegister, flags);
308 acc.read();
309 std::vector<UserType> vector(acc.getNElements());
310 acc.swap(vector);
311 return vector;
312 }
313
314 /********************************************************************************************************************/
315
316 template<typename UserType>
317 void Device::write(const RegisterPath& registerPathName, UserType value, const AccessModeFlags& flags) {
318 auto acc = getScalarRegisterAccessor<UserType>(registerPathName, 0, flags);
319 acc = value;
320 acc.write();
321 }
322
323 /********************************************************************************************************************/
324
325 template<typename UserType>
326 void Device::write(const RegisterPath& registerPathName, const std::vector<UserType>& vector,
327 size_t wordOffsetInRegister, const AccessModeFlags& flags) {
328 auto acc = getOneDRegisterAccessor<UserType>(registerPathName, vector.size(), wordOffsetInRegister, flags);
329 // the vector stays constant, but we have to work around so we can swap it and
330 // later swap it back...
331 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
332 auto& mutable_vector = const_cast<std::vector<UserType>&>(vector);
333 acc.swap(mutable_vector);
334 acc.write();
335 acc.swap(mutable_vector);
336 }
337
338 /********************************************************************************************************************/
339
340} // namespace ChimeraTK
Set of AccessMode flags with additional functionality for an easier handling.
Definition AccessMode.h:48
Class allows to read/write registers from device.
Definition Device.h:39
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:286
bool isOpened() const
Check if the device is currently opened.
Definition Device.cc:73
std::set< DeviceBackend::BackendID > getInvolvedBackendIDs()
Recursively obtain the set of all backend IDs that are used withing the device.
Definition Device.cc:117
void open()
Re-open the device after previously closeing it by calling close(), or when it was constructed with a...
Definition Device.cc:51
MetadataCatalogue getMetadataCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition Device.cc:29
boost::shared_ptr< DeviceBackend > _deviceBackendPointer
Definition Device.h:258
void close()
Close the device.
Definition Device.cc:66
void setException(const std::string &message)
Set the device into an exception state.
Definition Device.cc:97
boost::shared_ptr< DeviceBackend > getBackend()
Obtain the backend.
Definition Device.cc:111
VoidRegisterAccessor getVoidRegisterAccessor(const RegisterPath &registerPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a VoidRegisterAccessor object for the given register.
Definition Device.cc:103
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:266
void checkPointersAreNotNull() const
Definition Device.cc:43
RegisterCatalogue getRegisterCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition Device.cc:22
std::string readDeviceInfo() const
Return a device information string.
Definition Device.cc:36
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:276
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
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:296
void activateAsyncRead() noexcept
Activate asyncronous read for all transfer elements where AccessMode::wait_for_new_data is set.
Definition Device.cc:91
Device()=default
Create device instance without associating a backend yet.
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:317
Accessor class to read and write registers transparently by using the accessor object like a vector o...
Class to store a register path name.
Accessor class to read and write scalar registers transparently by using the accessor object like a v...
Accessor class to read and write 2D registers.
Accessor class to read and write void-typed registers.
STL namespace.