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_
uint32_t DeviceType() const noexcept
Returns the device type of the logical device on the remote node.
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 ...
The CANopen master.
Definition: master.hpp:50
ev::Executor GetExecutor() const noexcept final
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
Definition: driver.hpp:311
void OnCanError(io::CanError) noexcept override
The function invoked when an error is detected on the CAN bus.
The base class for drivers for remote CANopen nodes.
Definition: driver.hpp:278
bool IsReady() const
Returns true if the remote node is ready (i.e., the NMT boot slave process has successfully completed...
Definition: driver.hpp:374
void OnTime(const ::std::chrono::system_clock::time_point &) noexcept override
The function invoked when a TIME message is received by the master.
bool IsReady() const
Returns true if the remote node is ready (i.e., the NMT boot slave process has successfully completed...
BasicDriver & driver
A reference to the driver with which this logical device driver is registered.
void Error()
Indicates the occurrence of an error event on the remote node and triggers the error handling process...
NmtCommand
The NMT command specifiers.
Definition: node.hpp:42
void OnDeconfig(::std::function< void(::std::error_code ec)> res) noexcept override
The function invoked by BasicMaster::AsyncDeconfig() to start the deconfiguration process...
Driver & driver
A reference to the driver with which this logical device driver is registered.
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& ...
void OnBoot(NmtState, char, const ::std::string &) noexcept override
The function invoked when the NMT &#39;boot slave&#39; process completes for the remote node.
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...
void OnHeartbeat(bool) noexcept override
The function invoked when a heartbeat timeout event occurs or is resolved for the remote node...
An accessor providing read-only access to a CANopen object in a local object dictionary.
Definition: master.hpp:398
SdoFuture< void > AsyncWait(const time_point &t)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
Definition: driver.hpp:424
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...
CanState
The states of a CAN node, depending on the TX/RX error count.
Definition: err.hpp:33
uint8_t id() const noexcept final
Returns the node-ID.
Definition: driver.hpp:321
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...
void OnCommand(NmtCommand) noexcept override
The function invoked when an NMT state change occurs on the master.
ev::Executor GetExecutor() const noexcept final
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
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...
SdoFuture< T > AsyncRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout)...
Definition: driver.hpp:579
void OnConfig(::std::function< void(::std::error_code ec)> res) noexcept override
The function invoked when the &#39;update configuration&#39; step is reached during the NMT &#39;boot slave&#39; proc...
CanError
The error flags of a CAN bus, which are not mutually exclusive.
Definition: err.hpp:47
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...
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: driver.hpp:449
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...
uint8_t id() const noexcept final
Returns the node-ID.
The base class for drivers for logical devices on remote CANopen nodes.
SdoFuture< void > AsyncWait(const duration &d)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
void OnSyncError(uint16_t, uint8_t) noexcept override
The function invoked when the data length of a received SYNC message does not match.
void SubmitWait(const time_point &t, F &&f)
Submits a wait operation.
Definition: driver.hpp:398
This header file is part of the C++ CANopen application library; it contains the remote node driver i...
int Number() const noexcept final
Returns the number of the logical device on the remote node.
The base class for drivers for logical devices on remote CANopen nodes.
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.
void SubmitWait(const duration &d, F &&f)
Submits a wait operation.
void OnEmcy(uint16_t, uint8_t, uint8_t [5]) noexcept override
The function invoked when an EMCY message is received from the remote node.
void OnNodeGuarding(bool) noexcept override
The function invoked when a node guarding timeout event occurs or is resolved for the remote node...
void OnSync(uint8_t, const time_point &) noexcept override
The function invoked when a SYNC message is sent/received by the master.
int Profile() const noexcept
Returns the device profile number of the logical device on the remote node, or 0 if the device does n...
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...
BasicMaster & master
A reference to the master with which driver is registered.
uint8_t netid() const noexcept final
Returns the network-ID.
An abstract task executor. This class is a wrapper around ev_exec_t*.
Definition: exec.hpp:38
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: driver.hpp:612
A mutator providing read/write access to a CANopen object in a local object dictionary.
Definition: master.hpp:347
void Post(F &&f, Args &&... args)
Schedules the specified Callable object for execution by the executor for this driver.
void Error()
Indicates the occurrence of an error event on the remote node and triggers the error handling process...
Definition: driver.hpp:385
uint8_t netid() const noexcept final
Returns the network-ID.
Definition: driver.hpp:316
NmtState
The NMT states.
Definition: node.hpp:56
void SubmitWait(const time_point &t, F &&f)
Submits a wait operation.
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: buf.hpp:32
SdoFuture< void > AsyncWait(const time_point &t)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
The abstract driver interface for a logical device on a remote CANopen node.
Definition: driver.hpp:258
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...
void OnCanState(io::CanState, io::CanState) noexcept override
The function invoked when a CAN bus state change is detected.
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: driver.hpp:512
SdoFuture< T > AsyncRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout)...
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.
A future.
Definition: future.hpp:50