Lely core libraries 2.3.4
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
30namespace lely {
31
32namespace canopen {
33
34template <class = BasicDriver>
35class BasicLogicalDriver;
36
38template <>
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
51 return driver.GetExecutor();
52 }
53
56 return driver.netid();
57 }
58
61 return driver.id();
62 }
63
64 int
66 return num_;
67 }
68
72 return dev_;
73 }
74
79 int
81 return DeviceType() & 0xffff;
82 }
83
91 bool
92 IsReady() const {
93 return driver.IsReady();
94 }
95
102 void
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 SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con) {
229 driver.SubmitBlockRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con));
230 }
231
238 template <class T, class F>
239 void
240 SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con,
241 ::std::error_code& ec) {
242 driver.SubmitBlockRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con),
243 ec);
244 }
245
251 template <class T, class F>
252 void
253 SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con,
254 const ::std::chrono::milliseconds& timeout) {
255 driver.SubmitBlockRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con),
256 timeout);
257 }
258
278 template <class T, class F>
279 void
280 SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con,
281 const ::std::chrono::milliseconds& timeout,
282 ::std::error_code& ec) {
283 driver.SubmitBlockRead<T>(ObjectIndex(idx), subidx, ::std::forward<F>(con),
284 timeout, ec);
285 }
286
293 template <class T, class F>
294 void
295 SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con) {
296 driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
297 ::std::forward<F>(con));
298 }
299
306 template <class T, class F>
307 void
308 SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
309 ::std::error_code& ec) {
310 driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
311 ::std::forward<F>(con), ec);
312 }
313
319 template <class T, class F>
320 void
321 SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
322 const ::std::chrono::milliseconds& timeout) {
323 driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
324 ::std::forward<F>(con), timeout);
325 }
326
343 template <class T, class F>
344 void
345 SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
346 const ::std::chrono::milliseconds& timeout,
347 ::std::error_code& ec) {
348 driver.SubmitWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
349 ::std::forward<F>(con), timeout, ec);
350 }
351
358 template <class T, class F>
359 void
360 SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con) {
361 driver.SubmitBlockWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
362 ::std::forward<F>(con));
363 }
364
371 template <class T, class F>
372 void
373 SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
374 ::std::error_code& ec) {
375 driver.SubmitBlockWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
376 ::std::forward<F>(con), ec);
377 }
378
384 template <class T, class F>
385 void
386 SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
387 const ::std::chrono::milliseconds& timeout) {
388 driver.SubmitBlockWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
389 ::std::forward<F>(con), timeout);
390 }
391
412 template <class T, class F>
413 void
414 SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con,
415 const ::std::chrono::milliseconds& timeout,
416 ::std::error_code& ec) {
417 driver.SubmitBlockWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
418 ::std::forward<F>(con), timeout, ec);
419 }
420
427 template <class T>
430 return driver.AsyncRead<T>(ObjectIndex(idx), subidx);
431 }
432
447 template <class T>
450 const ::std::chrono::milliseconds& timeout) {
451 return driver.AsyncRead<T>(ObjectIndex(idx), subidx, timeout);
452 }
453
460 template <class T>
463 return driver.AsyncBlockRead<T>(ObjectIndex(idx), subidx);
464 }
465
484 template <class T>
487 const ::std::chrono::milliseconds& timeout) {
488 return driver.AsyncBlockRead<T>(ObjectIndex(idx), subidx, timeout);
489 }
490
497 template <class T>
499 AsyncWrite(uint16_t idx, uint8_t subidx, T&& value) {
500 return driver.AsyncWrite(ObjectIndex(idx), subidx,
501 ::std::forward<T>(value));
502 }
503
518 template <class T>
520 AsyncWrite(uint16_t idx, uint8_t subidx, T&& value,
521 const ::std::chrono::milliseconds& timeout) {
522 return driver.AsyncWrite(ObjectIndex(idx), subidx, ::std::forward<T>(value),
523 timeout);
524 }
525
532 template <class T>
534 AsyncBlockWrite(uint16_t idx, uint8_t subidx, T&& value) {
535 return driver.AsyncBlockWrite(ObjectIndex(idx), subidx,
536 ::std::forward<T>(value));
537 }
538
557 template <class T>
559 AsyncBlockWrite(uint16_t idx, uint8_t subidx, T&& value,
560 const ::std::chrono::milliseconds& timeout) {
561 return driver.AsyncBlockWrite(ObjectIndex(idx), subidx,
562 ::std::forward<T>(value), timeout);
563 }
564
571 template <class F, class... Args>
572 void
573 Post(F&& f, Args&&... args) {
574 GetExecutor().post(::std::forward<F>(f), ::std::forward<Args>(args)...);
575 }
576
579
585
586 class RpdoMapped {
587 friend class BasicLogicalDriver;
588
589 public:
591 operator[](uint16_t idx) const {
592 return self_.driver.rpdo_mapped[self_.ObjectIndex(idx)];
593 }
594
595 private:
596 explicit RpdoMapped(BasicLogicalDriver& self) noexcept : self_(self) {}
597
598 BasicLogicalDriver& self_;
599 } rpdo_mapped;
600
601 class TpdoMapped {
602 friend class BasicLogicalDriver;
603
604 public:
606 operator[](uint16_t idx) {
607 return self_.driver.tpdo_mapped[self_.ObjectIndex(idx)];
608 }
609
611 operator[](uint16_t idx) const {
612 const auto& tpdo_mapped = self_.driver.tpdo_mapped;
613 return tpdo_mapped[self_.ObjectIndex(idx)];
614 }
615
616 private:
617 explicit TpdoMapped(BasicLogicalDriver& self) noexcept : self_(self) {}
618
619 BasicLogicalDriver& self_;
620 } tpdo_mapped;
621
624
625 protected:
626 void
628 io::CanState /*old_state*/) noexcept override {}
629
630 void
631 OnCanError(io::CanError /*error*/) noexcept override {}
632
633 void
634 OnRpdoWrite(uint16_t /*idx*/, uint8_t /*subidx*/) noexcept override {}
635
636 void
637 OnCommand(NmtCommand /*cs*/) noexcept override {}
638
639 void
640 // NOLINTNEXTLINE(readability/casting)
641 OnHeartbeat(bool /*occurred*/) noexcept override {}
642
643 void
644 OnState(NmtState /*st*/) noexcept override {}
645
646 void
647 OnSync(uint8_t /*cnt*/, const time_point& /*t*/) noexcept override {}
648
649 void
650 OnSyncError(uint16_t /*eec*/, uint8_t /*er*/) noexcept override {}
651
652 void
653 OnTime(const ::std::chrono::system_clock::time_point& /*abs_time*/) noexcept
654 override {}
655
656 void
657 OnEmcy(uint16_t /*eec*/, uint8_t /*er*/,
658 uint8_t /*msef*/[5]) noexcept override {}
659
660 void
661 // NOLINTNEXTLINE(readability/casting)
662 OnNodeGuarding(bool /*occurred*/) noexcept override {}
663
664 void
665 OnBoot(NmtState /*st*/, char /*es*/,
666 const ::std::string& /*what*/) noexcept override {}
667
668 void
669 OnConfig(::std::function<void(::std::error_code ec)> res) noexcept override {
670 res(::std::error_code{});
671 }
672
673 void
675 ::std::function<void(::std::error_code ec)> res) noexcept override {
676 res(::std::error_code{});
677 }
678
686 ObjectIndex(uint16_t idx) const noexcept {
687 return (idx >= 0x6000 && idx <= 0x67ff) ? idx + (num_ - 1) * 0x800 : idx;
688 }
689
690 private:
691 SdoFuture<void> AsyncConfig() final;
692 SdoFuture<void> AsyncDeconfig() final;
693
694 int num_{1};
695 uint32_t dev_{0};
696};
697
699template <class Driver>
700class BasicLogicalDriver : public BasicLogicalDriver<BasicDriver> {
701 public:
702 BasicLogicalDriver(Driver& driver_, int num = 1, uint32_t dev = 0)
704
710};
711
712} // namespace canopen
713
714} // namespace lely
715
716#endif // LELY_COAPP_LOGICAL_DRIVER_HPP_
A CANopen value.
Definition val.hpp:42
The base class for drivers for remote CANopen nodes.
Definition driver.hpp:279
SdoFuture< void > AsyncBlockWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout)
Queues an asynchronous write (SDO block download) operation and creates a future which becomes ready ...
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.
void SubmitBlockWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con)
Equivalent to SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono:...
bool IsReady() const
Returns true if the remote node is ready (i.e., the NMT boot slave process has successfully completed...
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.
SdoFuture< T > AsyncRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout),...
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...
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 OnSyncError(uint16_t, uint8_t) noexcept override
The function invoked when the data length of a received SYNC message does not match.
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< void > AsyncWait(const duration &d)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
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.
SdoFuture< void > AsyncBlockWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncBlockWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseco...
void SubmitBlockWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO block download) operation.
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 SubmitBlockRead(uint16_t idx, uint8_t subidx, F &&con)
Equivalent to SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::millisecond...
void SubmitBlockRead(uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::millisecond...
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 > AsyncBlockRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout)
Queues an asynchronous read (SDO block upload) operation and creates a future which becomes ready onc...
void SubmitBlockWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono:...
void Post(F &&f, Args &&... args)
Schedules the specified Callable object for execution by the executor for this driver.
void SubmitBlockRead(uint16_t idx, uint8_t subidx, F &&con, ::std::error_code &ec)
Equivalent to SubmitBlockRead(uint16_t idx, uint8_t subidx, F&& con, const ::std::chrono::millisecond...
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.
SdoFuture< T > AsyncBlockRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncBlockRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout...
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.
SdoFuture< void > AsyncWait(const time_point &t)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
void SubmitBlockRead(uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO block upload) operation.
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 SubmitBlockWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, ::std::error_code &ec)
Equivalent to SubmitBlockWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const ::std::chrono:...
void OnHeartbeat(bool) noexcept override
The function invoked when a heartbeat timeout event occurs or is resolved for the remote node.
ev::Executor GetExecutor() const noexcept final
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
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 ...
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 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.
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:411
A mutator providing read/write access to a CANopen object in a local object dictionary.
Definition master.hpp:358
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