Lely core libraries  2.2.5
logical_driver.hpp
Go to the documentation of this file.
1 
22 #ifndef LELY_COAPP_LOGICAL_DRIVER_HPP_
23 #define LELY_COAPP_LOGICAL_DRIVER_HPP_
24 
25 #include <lely/coapp/driver.hpp>
26 
27 #include <string>
28 #include <utility>
29 
30 namespace lely {
31 
32 namespace canopen {
33 
34 template <class = BasicDriver>
36 
38 template <>
40  public:
41  using DriverBase::time_point;
42  using duration = BasicMaster::duration;
44 
45  BasicLogicalDriver(BasicDriver& driver, int num = 1, uint32_t dev = 0);
46 
47  virtual ~BasicLogicalDriver();
48 
50  GetExecutor() const noexcept final {
51  return driver.GetExecutor();
52  }
53 
54  uint8_t
55  netid() const noexcept final {
56  return driver.netid();
57  }
58 
59  uint8_t
60  id() const noexcept final {
61  return driver.id();
62  }
63 
64  int
65  Number() const noexcept final {
66  return num_;
67  }
68 
70  uint32_t
71  DeviceType() const noexcept {
72  return dev_;
73  }
74 
79  int
80  Profile() const noexcept {
81  return DeviceType() & 0xffff;
82  }
83 
91  bool
92  IsReady() const {
93  return driver.IsReady();
94  }
95 
102  void
103  Error() {
104  driver.Error();
105  }
106 
114  template <class F>
115  void
116  SubmitWait(const time_point& t, F&& f) {
117  return driver.SubmitWait(t, ::std::forward<F>(f));
118  }
119 
127  template <class F>
128  void
129  SubmitWait(const duration& d, F&& f) {
130  return driver.SubmitWait(d, ::std::forward<F>(f));
131  }
132 
142  AsyncWait(const time_point& t) {
143  return driver.AsyncWait(t);
144  }
145 
155  AsyncWait(const duration& d) {
156  return driver.AsyncWait(d);
157  }
158 
165  template <class T, class F>
166  void
167  SubmitRead(uint16_t idx, uint8_t subidx, F&& con) {
168  driver.SubmitRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con));
169  }
170 
177  template <class T, class F>
178  void
179  SubmitRead(uint16_t idx, uint8_t subidx, F&& con, ::std::error_code& ec) {
180  driver.SubmitRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con), ec);
181  }
182 
188  template <class T, class F>
189  void
190  SubmitRead(uint16_t idx, uint8_t subidx, F&& con,
191  const ::std::chrono::milliseconds& timeout) {
192  driver.SubmitRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con),
193  timeout);
194  }
195 
211  template <class T, class F>
212  void
213  SubmitRead(uint16_t idx, uint8_t subidx, F&& con,
214  const ::std::chrono::milliseconds& timeout,
215  ::std::error_code& ec) {
216  driver.SubmitRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con),
217  timeout, ec);
218  }
219 
226  template <class T, class F>
227  void
228  SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con) {
229  driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
230  ::std::forward<F>(con));
231  }
232 
239  template <class T, class F>
240  void
241  SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
242  ::std::error_code& ec) {
243  driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
244  ::std::forward<F>(con), ec);
245  }
246 
252  template <class T, class F>
253  void
254  SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
255  const ::std::chrono::milliseconds& timeout) {
256  driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
257  ::std::forward<F>(con), timeout);
258  }
259 
276  template <class T, class F>
277  void
278  SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
279  const ::std::chrono::milliseconds& timeout,
280  ::std::error_code& ec) {
281  driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
282  ::std::forward<F>(con), timeout, ec);
283  }
284 
291  template <class T>
293  AsyncRead(uint16_t idx, uint8_t subidx) {
294  return driver.AsyncRead<T>(ObjectIndex(idx), subidx);
295  }
296 
311  template <class T>
313  AsyncRead(uint16_t idx, uint8_t subidx,
314  const ::std::chrono::milliseconds& timeout) {
315  return driver.AsyncRead<T>(ObjectIndex(idx), subidx, timeout);
316  }
317 
324  template <class T>
326  AsyncWrite(uint16_t idx, uint8_t subidx, T&& value) {
327  return driver.AsyncWrite(ObjectIndex(idx), subidx,
328  ::std::forward<T>(value));
329  }
330 
345  template <class T>
347  AsyncWrite(uint16_t idx, uint8_t subidx, T&& value,
348  const ::std::chrono::milliseconds& timeout) {
349  return driver.AsyncWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
350  timeout);
351  }
352 
359  template <class F, class... Args>
360  void
361  Post(F&& f, Args&&... args) {
362  GetExecutor().post(::std::forward<F>(f), ::std::forward<Args>(args)...);
363  }
364 
367 
373 
374  class RpdoMapped {
375  friend class BasicLogicalDriver;
376 
377  public:
378  BasicMaster::ConstObject operator[](uint16_t idx) const {
379  return self_.driver.rpdo_mapped[self_.ObjectIndex(idx)];
380  }
381 
382  private:
383  explicit RpdoMapped(BasicLogicalDriver& self) noexcept
384  : self_(self) {}
385 
386  BasicLogicalDriver& self_;
387  } rpdo_mapped;
388 
389  class TpdoMapped {
390  friend class BasicLogicalDriver;
391 
392  public:
393  BasicMaster::Object operator[](uint16_t idx) {
394  return self_.driver.tpdo_mapped[self_.ObjectIndex(idx)];
395  }
396 
397  BasicMaster::ConstObject operator[](uint16_t idx) const {
398  const auto& tpdo_mapped = self_.driver.tpdo_mapped;
399  return tpdo_mapped[self_.ObjectIndex(idx)];
400  }
401 
402  private:
403  explicit TpdoMapped(BasicLogicalDriver& self) noexcept : self_(self) {}
404 
405  BasicLogicalDriver& self_;
406  } tpdo_mapped;
407 
410 
411  protected:
412  void
413  OnCanState(io::CanState /*new_state*/,
414  io::CanState /*old_state*/) noexcept override {}
415 
416  void
417  OnCanError(io::CanError /*error*/) noexcept override {}
418 
419  void
420  OnRpdoWrite(uint16_t /*idx*/, uint8_t /*subidx*/) noexcept override {}
421 
422  void
423  OnCommand(NmtCommand /*cs*/) noexcept override {}
424 
425  void
426  // NOLINTNEXTLINE(readability/casting)
427  OnNodeGuarding(bool /*occurred*/) noexcept override {}
428 
429  void
430  // NOLINTNEXTLINE(readability/casting)
431  OnHeartbeat(bool /*occurred*/) noexcept override {}
432 
433  void
434  OnState(NmtState /*st*/) noexcept override {}
435 
436  void
437  OnBoot(NmtState /*st*/, char /*es*/,
438  const ::std::string& /*what*/) noexcept override {}
439 
440  void
441  OnConfig(::std::function<void(::std::error_code ec)> res) noexcept override {
442  res(::std::error_code{});
443  }
444 
445  void
447  ::std::function<void(::std::error_code ec)> res) noexcept override {
448  res(::std::error_code{});
449  }
450 
451  void
452  OnSync(uint8_t /*cnt*/, const time_point& /*t*/) noexcept override {}
453 
454  void
455  OnSyncError(uint16_t /*eec*/, uint8_t /*er*/) noexcept override {}
456 
457  void
458  OnTime(const ::std::chrono::system_clock::
459  time_point& /*abs_time*/) noexcept override {}
460 
461  void
462  OnEmcy(uint16_t /*eec*/, uint8_t /*er*/,
463  uint8_t /*msef*/[5]) noexcept override {}
464 
471  uint16_t
472  ObjectIndex(uint16_t idx) const noexcept {
473  return (idx >= 0x6000 && idx <= 0x67ff) ? idx + (num_ - 1) * 0x800 : idx;
474  }
475 
476  private:
477  SdoFuture<void> AsyncConfig() final;
478  SdoFuture<void> AsyncDeconfig() final;
479 
480  int num_{1};
481  uint32_t dev_{0};
482 };
483 
485 template <class Driver>
486 class BasicLogicalDriver : public BasicLogicalDriver<BasicDriver> {
487  public:
488  BasicLogicalDriver(Driver& driver_, int num = 1, uint32_t dev = 0)
489  : BasicLogicalDriver<BasicDriver>(driver_, num, dev), driver(driver_) {}
490 
495  Driver& driver;
496 };
497 
498 } // namespace canopen
499 
500 } // namespace lely
501 
502 #endif // LELY_COAPP_LOGICAL_DRIVER_HPP_
lely::canopen::BasicLogicalDriver< BasicDriver >::Profile
int Profile() const noexcept
Returns the device profile number of the logical device on the remote node, or 0 if the device does n...
Definition: logical_driver.hpp:80
lely::canopen::BasicLogicalDriver< BasicDriver >::OnSyncError
void OnSyncError(uint16_t, uint8_t) noexcept override
The function invoked when the data length of a received SYNC message does not match.
Definition: logical_driver.hpp:455
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitRead
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con)
Equivalent to SubmitRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::milliseconds& ti...
Definition: logical_driver.hpp:167
lely::canopen::NmtCommand
NmtCommand
The NMT command specifiers.
Definition: node.hpp:42
lely::canopen::BasicMaster
The CANopen master.
Definition: master.hpp:50
lely::canopen::BasicLogicalDriver< BasicDriver >::OnConfig
void OnConfig(::std::function< void(::std::error_code ec)> res) noexcept override
The function invoked when the 'update configuration' step is reached during the NMT 'boot slave' proc...
Definition: logical_driver.hpp:441
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWrite
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono::mill...
Definition: logical_driver.hpp:254
lely::canopen::BasicDriver
The base class for drivers for remote CANopen nodes.
Definition: driver.hpp:278
lely::canopen::BasicLogicalDriver< BasicDriver >::tpdo_event_mutex
TpdoEventMutex & tpdo_event_mutex
Definition: logical_driver.hpp:409
lely::canopen::BasicLogicalDriver< BasicDriver >::OnNodeGuarding
void OnNodeGuarding(bool) noexcept override
The function invoked when a node guarding timeout event occurs or is resolved for the remote node.
Definition: logical_driver.hpp:427
lely::canopen::BasicMaster::TpdoEventMutex
Definition: master.hpp:508
lely::canopen::BasicLogicalDriver< BasicDriver >::OnEmcy
void OnEmcy(uint16_t, uint8_t, uint8_t[5]) noexcept override
The function invoked when an EMCY message is received from the remote node.
Definition: logical_driver.hpp:462
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWrite
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, ::std::error_code &ec)
Equivalent to SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono::mill...
Definition: logical_driver.hpp:241
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitRead
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con, ::std::error_code &ec)
Equivalent to SubmitRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::milliseconds& ti...
Definition: logical_driver.hpp:179
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitRead
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation.
Definition: logical_driver.hpp:213
lely::canopen::BasicLogicalDriver< BasicDriver >::OnDeconfig
void OnDeconfig(::std::function< void(::std::error_code ec)> res) noexcept override
The function invoked by BasicMaster::AsyncDeconfig() to start the deconfiguration process.
Definition: logical_driver.hpp:446
lely::canopen::BasicLogicalDriver
The base class for drivers for logical devices on remote CANopen nodes.
Definition: logical_driver.hpp:35
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWrite
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation.
Definition: logical_driver.hpp:278
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWait
void SubmitWait(const time_point &t, F &&f)
Submits a wait operation.
Definition: logical_driver.hpp:116
lely::io::CanError
CanError
The error flags of a CAN bus, which are not mutually exclusive.
Definition: err.hpp:47
lely::canopen::BasicLogicalDriver< BasicDriver >::driver
BasicDriver & driver
A reference to the driver with which this logical device driver is registered.
Definition: logical_driver.hpp:372
lely::io::CanState
CanState
The states of a CAN node, depending on the TX/RX error count.
Definition: err.hpp:33
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitRead
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::milliseconds& ti...
Definition: logical_driver.hpp:190
lely::canopen::BasicLogicalDriver< BasicDriver >::OnSync
void OnSync(uint8_t, const time_point &) noexcept override
The function invoked when a SYNC message is sent/received by the master.
Definition: logical_driver.hpp:452
lely::canopen::BasicLogicalDriver< BasicDriver >::IsReady
bool IsReady() const
Returns true if the remote node is ready (i.e., the NMT boot slave process has successfully completed...
Definition: logical_driver.hpp:92
lely::canopen::BasicLogicalDriver< BasicDriver >::OnTime
void OnTime(const ::std::chrono::system_clock::time_point &) noexcept override
The function invoked when a TIME message is received by the master.
Definition: logical_driver.hpp:458
lely::canopen::BasicLogicalDriver< BasicDriver >::Error
void Error()
Indicates the occurrence of an error event on the remote node and triggers the error handling process...
Definition: logical_driver.hpp:103
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWait
void SubmitWait(const duration &d, F &&f)
Submits a wait operation.
Definition: logical_driver.hpp:129
lely::canopen::BasicLogicalDriver< BasicDriver >::DeviceType
uint32_t DeviceType() const noexcept
Returns the device type of the logical device on the remote node.
Definition: logical_driver.hpp:71
lely::ev::Executor
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
lely::canopen::BasicLogicalDriver< BasicDriver >::OnCanState
void OnCanState(io::CanState, io::CanState) noexcept override
The function invoked when a CAN bus state change is detected.
Definition: logical_driver.hpp:413
lely::canopen::BasicLogicalDriver< BasicDriver >::SubmitWrite
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con)
Equivalent to SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono::mill...
Definition: logical_driver.hpp:228
lely::canopen::BasicLogicalDriver< BasicDriver >::OnCommand
void OnCommand(NmtCommand) noexcept override
The function invoked when an NMT state change occurs on the master.
Definition: logical_driver.hpp:423
lely::canopen::BasicLogicalDriver< BasicDriver >::GetExecutor
ev::Executor GetExecutor() const noexcept final
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
Definition: logical_driver.hpp:50
lely::ev::Future
A future.
Definition: future.hpp:50
lely::canopen::BasicLogicalDriver< BasicDriver >::OnCanError
void OnCanError(io::CanError) noexcept override
The function invoked when an error is detected on the CAN bus.
Definition: logical_driver.hpp:417
lely::canopen::BasicLogicalDriver< BasicDriver >::master
BasicMaster & master
A reference to the master with which driver is registered.
Definition: logical_driver.hpp:366
driver.hpp
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncRead
SdoFuture< T > AsyncRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout)
Queues an asynchronous read (SDO upload) operation and creates a future which becomes ready once the ...
Definition: logical_driver.hpp:313
lely::canopen::BasicMaster::ConstObject
An accessor providing read-only access to a CANopen object in a local object dictionary.
Definition: master.hpp:398
lely::canopen::BasicLogicalDriver< BasicDriver >::OnState
void OnState(NmtState) noexcept override
The function invoked when an NMT state change or boot-up event is detected for the remote node by the...
Definition: logical_driver.hpp:434
lely::canopen::BasicLogicalDriver::driver
Driver & driver
A reference to the driver with which this logical device driver is registered.
Definition: logical_driver.hpp:495
lely::canopen::NmtState
NmtState
The NMT states.
Definition: node.hpp:56
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncRead
SdoFuture< T > AsyncRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout),...
Definition: logical_driver.hpp:293
lely::canopen::BasicLogicalDriver< BasicDriver >::OnBoot
void OnBoot(NmtState, char, const ::std::string &) noexcept override
The function invoked when the NMT 'boot slave' process completes for the remote node.
Definition: logical_driver.hpp:437
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncWrite
SdoFuture< void > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout)
Queues an asynchronous write (SDO download) operation and creates a future which becomes ready once t...
Definition: logical_driver.hpp:347
lely::canopen::LogicalDriverBase
The abstract driver interface for a logical device on a remote CANopen node.
Definition: driver.hpp:258
lely::canopen::BasicLogicalDriver< BasicDriver >::OnHeartbeat
void OnHeartbeat(bool) noexcept override
The function invoked when a heartbeat timeout event occurs or is resolved for the remote node.
Definition: logical_driver.hpp:431
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncWrite
SdoFuture< void > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ...
Definition: logical_driver.hpp:326
lely::canopen::BasicLogicalDriver< BasicDriver >::ObjectIndex
uint16_t ObjectIndex(uint16_t idx) const noexcept
Converts an object index, if it is part of the standardized profile area, from the first logical devi...
Definition: logical_driver.hpp:472
lely::canopen::BasicLogicalDriver< BasicDriver >::id
uint8_t id() const noexcept final
Returns the node-ID.
Definition: logical_driver.hpp:60
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncWait
SdoFuture< void > AsyncWait(const duration &d)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
Definition: logical_driver.hpp:155
lely::canopen::BasicMaster::Object
A mutator providing read/write access to a CANopen object in a local object dictionary.
Definition: master.hpp:347
lely::canopen::BasicLogicalDriver< BasicDriver >::Post
void Post(F &&f, Args &&... args)
Schedules the specified Callable object for execution by the executor for this driver.
Definition: logical_driver.hpp:361
lely::canopen::BasicLogicalDriver< BasicDriver >::Number
int Number() const noexcept final
Returns the number of the logical device on the remote node.
Definition: logical_driver.hpp:65
lely::canopen::BasicLogicalDriver< BasicDriver >::netid
uint8_t netid() const noexcept final
Returns the network-ID.
Definition: logical_driver.hpp:55
lely::canopen::BasicLogicalDriver< BasicDriver >::AsyncWait
SdoFuture< void > AsyncWait(const time_point &t)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
Definition: logical_driver.hpp:142