22#ifndef LELY_COCPP_DRIVER_HPP_
23#define LELY_COCPP_DRIVER_HPP_
25#include <lely/aio/loop.hpp>
35 using CanState = BasicMaster::CanState;
36 using CanError = BasicMaster::CanError;
38 using time_point = BasicMaster::time_point;
55 virtual uint8_t
netid() const noexcept = 0;
58 virtual uint8_t
id() const noexcept = 0;
65 virtual
void OnCanState(CanState new_state, CanState old_state) noexcept = 0;
166 const ::
std::
string& what) noexcept = 0;
184 ::
std::function<
void(::
std::error_code ec)> res) noexcept = 0;
209 virtual
void OnRpdo(
int num, ::
std::error_code ec, const
void* p,
210 ::
std::
size_t n) noexcept = 0;
225 virtual
void OnRpdoError(
int num, uint16_t eec, uint8_t er) noexcept = 0;
249 virtual
void OnTpdo(
int num, ::
std::error_code ec, const
void* p,
250 ::
std::
size_t n) noexcept = 0;
262 virtual
void OnSync(uint8_t cnt, const
Node::time_point& t) noexcept = 0;
283 const ::
std::chrono::system_clock::time_point& abs_time) noexcept = 0;
294 virtual
void OnEmcy(uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept = 0;
302 using DriverBase::time_point;
333 uint8_t
netid() const noexcept final override;
336 id() const noexcept final
override {
356 template <
class T,
class F>
360 master.
SubmitRead<T>(
id(), idx, subidx, exec, ::std::forward<F>(con));
369 template <
class T,
class F>
371 SubmitRead(uint16_t idx, uint8_t subidx, F&& con, ::std::error_code& ec) {
373 master.
SubmitRead<T>(
id(), idx, subidx, exec, ::std::forward<F>(con), ec);
382 template <
class T,
class F>
387 master.
SubmitRead<T>(
id(), idx, subidx, exec, ::std::forward<F>(con),
406 template <
class T,
class F>
411 master.
SubmitRead<T>(
id(), idx, subidx, exec, ::std::forward<F>(con),
421 template <
class T,
class F>
425 master.
SubmitWrite<T>(
id(), idx, subidx, ::std::forward<T>(value), exec,
426 ::std::forward<F>(con));
435 template <
class T,
class F>
438 ::std::error_code& ec) {
440 master.
SubmitWrite<T>(
id(), idx, subidx, ::std::forward<T>(value), exec,
441 ::std::forward<F>(con), ec);
450 template <
class T,
class F>
455 master.
SubmitWrite<T>(
id(), idx, subidx, ::std::forward<T>(value), exec,
456 ::std::forward<F>(con), timeout);
475 template <
class T,
class F>
480 master.
SubmitWrite<T>(
id(), idx, subidx, ::std::forward<T>(value), exec,
481 ::std::forward<F>(con), timeout, ec);
491 aio::Future<::std::tuple<::std::error_code, T>>
493 auto loop = GetLoop();
495 return master.
AsyncRead<T>(loop, exec,
id(), idx, subidx);
513 aio::Future<::std::tuple<::std::error_code, T>>
515 auto loop = GetLoop();
517 return master.
AsyncRead<T>(loop, exec,
id(), idx, subidx, timeout);
527 aio::Future<::std::error_code>
529 auto loop = GetLoop();
531 return master.
AsyncWrite(loop, exec,
id(), idx, subidx,
532 ::std::forward<T>(value));
550 aio::Future<::std::error_code>
553 auto loop = GetLoop();
555 return master.
AsyncWrite(loop, exec,
id(), idx, subidx,
556 ::std::forward<T>(value), timeout);
567 ::std::error_code ec;
568 auto r = RunRead<T>(idx, subidx, ec);
569 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"RunRead");
581 RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec) {
583 auto future = AsyncRead<T>(idx, subidx);
585 auto t = future.Get();
586 ec = ::std::get<0>(t);
587 value = ::std::move(::std::get<1>(t));
603 ::std::error_code ec;
604 auto r = RunRead<T>(idx, subidx, timeout, ec);
605 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"RunRead");
627 ::std::error_code& ec) {
629 auto future = AsyncRead<T>(idx, subidx, timeout);
631 auto t = future.Get();
632 ec = ::std::get<0>(t);
633 value = ::std::move(::std::get<1>(t));
647 RunWrite(uint16_t idx, uint8_t subidx, T&& value) {
648 ::std::error_code ec;
649 RunWrite(idx, subidx, ::std::forward<T>(value), ec);
650 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"RunWrite");
661 RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec) {
662 auto future = AsyncWrite(idx, subidx, ::std::forward<T>(value));
676 ::std::error_code ec;
677 RunWrite(idx, subidx, ::std::forward<T>(value), timeout, ec);
678 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"RunWrite");
699 auto future = AsyncWrite(idx, subidx, ::std::forward<T>(value), timeout);
715 auto* op =
new aio::TaskWrapper([=](::std::error_code ec) {
723 OnCanState(CanState , CanState )
noexcept override {
743 const ::std::string& )
noexcept override {}
746 OnConfig(::std::function<
void(::std::error_code ec)> res)
noexcept override {
747 res(::std::error_code());
751 OnRpdo(
int , ::std::error_code ,
const void* ,
752 ::std::size_t )
noexcept override {}
755 OnRpdoError(
int , uint16_t , uint8_t )
noexcept override {
759 OnTpdo(
int , ::std::error_code ,
const void* ,
760 ::std::size_t )
noexcept override {}
763 OnSync(uint8_t ,
const time_point& )
noexcept override {}
766 OnSyncError(uint16_t , uint8_t )
noexcept override {}
769 OnTime(const ::std::chrono::system_clock::
770 time_point& )
noexcept override {}
773 OnEmcy(uint16_t , uint8_t ,
774 uint8_t [5])
noexcept override {}
776 aio_loop_t* loop_{
nullptr};
777 aio_exec_t* exec_{
nullptr};
790 aio::Executor exec{loop};
803 ::std::unique_ptr<Impl_> impl_;
The base class for drivers for remote CANopen nodes.
void RunWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec),...
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, ::std::error_code& ec),...
aio::Future<::std::error_code > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value, const Sdo::duration &timeout)
Queues an asynchronous write (SDO download) operation and returns a future.
T RunRead(uint16_t idx, uint8_t subidx, const Sdo::duration &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation and runs the event loop until the operation is com...
aio::Future<::std::tuple<::std::error_code, T > > AsyncRead(uint16_t idx, uint8_t subidx, const Sdo::duration &timeout)
Queues an asynchronous read (SDO upload) operation and returns a future.
T RunRead(uint16_t idx, uint8_t subidx)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec), except that it throws lel...
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const Sdo::duration &timeout)
Equivalent to SubmitWrite(uint16_t idx, uint8_t subidx, T&& value, F&& con, const Sdo::duration& time...
T RunRead(uint16_t idx, uint8_t subidx, const Sdo::duration &timeout)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const Sdo::duration& timeout, ::std::error_code& ...
aio::Future<::std::tuple<::std::error_code, T > > AsyncRead(uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(uint16_t idx, uint8_t subidx, const Sdo::duration& timeout),...
aio::Future<::std::error_code > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(uint16_t idx, uint8_t subidx, T&& value, const Sdo::duration& timeout),...
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const Sdo::duration &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation and runs the event loop until the operation is ...
T RunRead(uint16_t idx, uint8_t subidx, ::std::error_code &ec)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const Sdo::duration& timeout, ::std::error_code& ...
void Post(F &&f)
Schedules the specified Callable object for execution by the executor for this driver.
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const Sdo::duration &timeout)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const Sdo::duration& timeout,...
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 Sdo::duration& timeout,...
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 Sdo::duration& time...
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con, const Sdo::duration &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation.
void SubmitWrite(uint16_t idx, uint8_t subidx, T &&value, F &&con, const Sdo::duration &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation.
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con)
Equivalent to SubmitRead(uint16_t idx, uint8_t subidx, F&& con, ::std::error_code& ec),...
aio::ExecutorBase GetExecutor() const noexcept final override
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
void Error()
Indicates the occurrence of an error event on the remote node and triggers the error handling process...
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, ::std::error_code &ec)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const Sdo::duration& timeout,...
aio::LoopBase GetLoop() const noexcept
Returns the event loop used to create promises and futures.
void SubmitRead(uint16_t idx, uint8_t subidx, F &&con, const Sdo::duration &timeout)
Equivalent to SubmitRead(uint16_t idx, uint8_t subidx, F&& con, const Sdo::duration& timeout,...
BasicMaster & master
A reference to the master with which this driver is registered.
void SubmitRead(uint8_t id, Sdo::UploadRequest< T > &req)
Equivalent to SubmitRead(uint8_t id, Sdo::UploadRequest<T>& req, ::std::error_code& ec),...
aio::Future<::std::error_code > AsyncWrite(aio::LoopBase &loop, aio::ExecutorBase &exec, uint8_t id, uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(aio::LoopBase& loop, aio::ExecutorBase& exec, uint8_t id,...
void Error(uint8_t id)
Indicates the occurrence of an error event on a remote node and triggers the error handling process (...
aio::Future<::std::tuple<::std::error_code, T > > AsyncRead(aio::LoopBase &loop, aio::ExecutorBase &exec, uint8_t id, uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(aio::LoopBase& loop, aio::ExecutorBase& exec, uint8_t id, uint16_t idx,...
void SubmitWrite(uint8_t id, Sdo::DownloadRequest< T > &req)
Equivalent to SubmitWrite(uint8_t id, Sdo::DownloadRequest<T>& req, ::std::error_code& ec),...
The abstract driver interface for a remote CANopen node.
virtual void OnTpdo(int num, ::std::error_code ec, const void *p, ::std::size_t n) noexcept=0
The function invoked after a Transmit-PDO is sent by the master or an error occurs.
virtual void OnCommand(NmtCommand cs) noexcept=0
The function invoked when an NMT state change occurs on the master.
virtual uint8_t netid() const noexcept=0
Returns the network-ID.
virtual void OnNodeGuarding(bool occurred) noexcept=0
The function invoked when a node guarding timeout event occurs or is resolved for the remote node.
virtual void OnSync(uint8_t cnt, const Node::time_point &t) noexcept=0
The function invoked when a SYNC message is sent/received by the master.
virtual void OnHeartbeat(bool occurred) noexcept=0
The function invoked when a heartbeat timeout event occurs or is resolved for the remote node.
virtual void OnConfig(::std::function< void(::std::error_code ec)> res) noexcept=0
The function invoked when the 'update configuration' step is reached during the NMT 'boot slave' proc...
virtual void OnRpdoError(int num, uint16_t eec, uint8_t er) noexcept=0
The function invoked when a Receive-PDO length mismatch or timeout error occurs on the master.
virtual void OnCanError(CanError error) noexcept=0
The function invoked when an error is detected on the CAN bus.
virtual aio::ExecutorBase GetExecutor() const noexcept=0
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
virtual void OnTime(const ::std::chrono::system_clock::time_point &abs_time) noexcept=0
The function invoked when a TIME message is received by the master.
virtual void OnSyncError(uint16_t eec, uint8_t er) noexcept=0
The function invoked when the data length of a received SYNC message does not match.
virtual void OnState(NmtState st) noexcept=0
The function invoked when an NMT state change or boot-up event is detected for the remote node by the...
virtual uint8_t id() const noexcept=0
Returns the node-ID.
virtual void OnEmcy(uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept=0
The function invoked when an EMCY message is received from the remote node.
virtual void OnBoot(NmtState st, char es, const ::std::string &what) noexcept=0
The function invoked when the NMT 'boot slave' process completes for the remote node.
virtual void OnRpdo(int num, ::std::error_code ec, const void *p, ::std::size_t n) noexcept=0
The function invoked when a Receive-PDO is processed by the master.
virtual void OnCanState(CanState new_state, CanState old_state) noexcept=0
The function invoked when a CAN bus state change is detected.
A CANopen driver running its own dedicated event loop in a separate thread.
The base class for CANopen nodes.
The type of exception thrown when an SDO abort code is received.
::std::chrono::milliseconds duration
The type used to represent an SDO timeout duration.
A base class for lely::canopen::LoopDriver, containing an event loop and the associated executor.
The type of objects thrown as exceptions to report a system error with an associated error code.
This header file is part of the C++ CANopen application library; it contains the CANopen master decla...
@ NO_SDO
Resource not available: SDO connection.
NmtCommand
The NMT command specifiers.
Global namespace for the Lely Industries N.V. libraries.
The internal implementation of lely::canopen::LoopDriver.