ChimeraTK-DeviceAccess 03.19.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
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
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:283
bool isOpened() const
Check if the device is currently opened.
Definition Device.cc:73
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:255
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:263
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:273
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:293
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:314
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.