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