22 #ifndef LELY_COCPP_MASTER_HPP_
23 #define LELY_COCPP_MASTER_HPP_
82 Write(::std::forward<T>(value));
113 return id_ ? master_->
TpdoRead<T>(id_, idx_, subidx_)
114 : master_->
Read<T>(idx_, subidx_);
130 Read(::std::error_code& ec)
const {
131 return id_ ? master_->
TpdoRead<T>(id_, idx_, subidx_, ec)
132 : master_->
Read<T>(idx_, subidx_, ec);
150 master_->
TpdoWrite(id_, idx_, subidx_, ::std::forward<T>(value));
152 master_->
Write(idx_, subidx_, ::std::forward<T>(value));
170 Write(T&& value, ::std::error_code& ec) {
172 master_->
TpdoWrite(id_, idx_, subidx_, ::std::forward<T>(value), ec);
174 master_->
Write(idx_, subidx_, ::std::forward<T>(value), ec);
189 Write(
const void* p, ::std::size_t n) {
190 if (!id_) master_->
Write(idx_, subidx_, p, n);
204 Write(
const void* p, ::std::size_t n, ::std::error_code& ec) {
205 if (!id_) master_->
Write(idx_, subidx_, p, n, ec);
248 SubObject(
BasicMaster* master, uint8_t
id, uint16_t idx,
249 uint8_t subidx) noexcept
250 : master_(master), idx_(idx), subidx_(subidx), id_(
id) {}
295 return id_ ? (is_rpdo_ ? master_->
RpdoRead<T>(id_, idx_, subidx_)
296 : master_->
TpdoRead<T>(id_, idx_, subidx_))
297 : master_->
Read<T>(idx_, subidx_);
314 Read(::std::error_code& ec)
const {
315 return id_ ? (is_rpdo_ ? master_->
RpdoRead<T>(id_, idx_, subidx_, ec)
316 : master_->
TpdoRead<T>(id_, idx_, subidx_, ec))
317 : master_->
Read<T>(idx_, subidx_, ec);
322 uint8_t subidx) noexcept
325 ConstSubObject(
const BasicMaster* master, uint8_t
id, uint16_t idx,
326 uint8_t subidx,
bool is_rpdo) noexcept
337 uint8_t is_rpdo_ : 1;
364 return SubObject(master_, id_, idx_, subidx);
384 :
Object(master, 0, idx) {}
386 Object(
BasicMaster* master, uint8_t
id, uint16_t idx) noexcept
387 : master_(master), idx_(idx), id_(
id) {}
389 BasicMaster* master_;
423 ConstObject(
const BasicMaster* master, uint8_t
id, uint16_t idx,
424 bool is_rpdo) noexcept
425 : master_(master), idx_(idx), id_(
id), is_rpdo_(is_rpdo) {}
427 const BasicMaster* master_;
430 uint8_t is_rpdo_ : 1;
457 : master_(master), id_(
id) {}
482 return Object(master_, id_, idx);
501 : master_(master), id_(
id) {}
512 void lock()
override;
516 using Node::TpdoEventMutex::TpdoEventMutex;
534 ::std::error_code ec, T value);
549 ::std::error_code ec);
573 const ::std::string& dcf_bin =
"", uint8_t
id = 0xff);
577 const ::std::string& dcf_txt,
578 const ::std::string& dcf_bin =
"", uint8_t
id = 0xff)
637 bool Boot(uint8_t
id);
650 bool IsReady(uint8_t
id)
const;
683 void Error(uint8_t
id);
694 void Error(uint16_t eec, uint8_t er,
695 const uint8_t msef[5] =
nullptr) noexcept;
706 void RpdoRtr(
int num = 0) noexcept;
717 ::std::chrono::milliseconds
GetTimeout() const;
725 void SetTimeout(const ::std::chrono::milliseconds& timeout);
735 ::std::error_code ec;
737 if (ec)
throw SdoError(
id, req.idx, req.subidx, ec,
"SubmitRead");
751 ::std::lock_guard<BasicLockable>
lock(*
this);
757 sdo->SubmitUpload(req);
768 template <
class T,
class F>
772 SubmitRead<T>(exec,
id, idx, subidx, ::std::forward<F>(con),
GetTimeout());
780 template <
class T,
class F>
783 ::std::error_code& ec) {
784 SubmitRead<T>(exec,
id, idx, subidx, ::std::forward<F>(con),
GetTimeout(),
793 template <
class T,
class F>
796 const ::std::chrono::milliseconds& timeout) {
797 ::std::error_code ec;
798 SubmitRead<T>(exec,
id, idx, subidx, ::std::forward<F>(con), timeout, ec);
799 if (ec)
throw SdoError(
id, idx, subidx, ec,
"SubmitRead");
819 template <
class T,
class F>
822 const ::std::chrono::milliseconds& timeout,
823 ::std::error_code& ec) {
824 ::std::lock_guard<BasicLockable>
lock(*
this);
830 sdo->SubmitUpload<T>(exec, idx, subidx, ::std::forward<F>(con), timeout);
844 ::std::error_code ec;
860 ::std::lock_guard<BasicLockable>
lock(*
this);
866 sdo->SubmitDownload(req);
877 template <
class T,
class F>
880 T&& value, F&& con) {
881 SubmitWrite(exec,
id, idx, subidx, ::std::forward<T>(value),
890 template <
class T,
class F>
893 T&& value, F&& con, ::std::error_code& ec) {
894 SubmitWrite(exec,
id, idx, subidx, ::std::forward<T>(value),
903 template <
class T,
class F>
906 T&& value, F&& con, const ::std::chrono::milliseconds& timeout) {
907 ::std::error_code ec;
908 SubmitWrite(exec,
id, idx, subidx, ::std::forward<T>(value),
909 ::std::forward<F>(con), timeout, ec);
910 if (ec)
throw SdoError(
id, idx, subidx, ec,
"SubmitWrite");
931 template <
class T,
class F>
934 T&& value, F&& con, const ::std::chrono::milliseconds& timeout,
935 ::std::error_code& ec) {
936 ::std::lock_guard<BasicLockable>
lock(*
this);
942 sdo->SubmitDownload(exec, idx, subidx, ::std::forward<T>(value),
943 ::std::forward<F>(con), timeout);
957 return AsyncRead<T>(exec,
id, idx, subidx,
GetTimeout());
979 const ::std::chrono::milliseconds& timeout) {
982 ::std::lock_guard<BasicLockable>
lock(*
this);
987 return sdo->AsyncUpload<T>(exec, idx, subidx, timeout);
1003 return AsyncWrite(exec,
id, idx, subidx, ::std::forward<T>(value),
1026 T&& value, const ::std::chrono::milliseconds& timeout) {
1029 ::std::lock_guard<BasicLockable>
lock(*
this);
1034 return sdo->AsyncDownload<T>(exec, idx, subidx, ::std::forward<T>(value),
1066 void OnNodeGuarding(::std::function<
void(uint8_t,
bool)> on_node_guarding);
1075 ::std::function<
void(uint8_t,
NmtState,
char, const ::std::string&)>
1082 using MapType = ::std::map<uint8_t, DriverBase*>;
1089 void IsReady(uint8_t
id,
bool ready) noexcept;
1113 void OnRpdoWrite(uint8_t
id, uint16_t idx, uint8_t subidx) noexcept
override;
1148 void OnHeartbeat(uint8_t
id,
bool occurred) noexcept
override;
1205 const ::std::string& what) noexcept;
1219 virtual void OnConfig(uint8_t
id) noexcept;
1227 void ConfigResult(uint8_t
id, ::std::error_code ec) noexcept;
1234 void OnSync(uint8_t cnt,
const time_point& t) noexcept
override;
1241 void OnSyncError(uint16_t eec, uint8_t er) noexcept
override;
1248 void OnTime(const ::std::chrono::system_clock::time_point&
1249 abs_time) noexcept
override;
1257 void OnEmcy(uint8_t
id, uint16_t eec, uint8_t er,
1258 uint8_t msef[5]) noexcept
override;
1288 ::std::unique_ptr<Impl_> impl_;
1324 void OnRpdoWrite(uint8_t
id, uint16_t idx, uint8_t subidx) noexcept
override;
1341 void OnNodeGuarding(uint8_t
id,
bool occurred) noexcept
override;
1349 void OnHeartbeat(uint8_t
id,
bool occurred) noexcept
override;
1367 const ::std::string& what) noexcept
override;
1375 void OnConfig(uint8_t
id) noexcept
override;
1383 void OnSync(uint8_t cnt,
const time_point& t) noexcept
override;
1391 void OnSyncError(uint16_t eec, uint8_t er) noexcept
override;
1399 void OnTime(const ::std::chrono::system_clock::time_point&
1400 abs_time) noexcept
override;
1408 void OnEmcy(uint8_t
id, uint16_t eec, uint8_t er,
1409 uint8_t msef[5]) noexcept
override;
An asynchronous CANopen master.
void OnEmcy(uint8_t id, uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnConfig(uint8_t id) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnBoot(uint8_t id, NmtState st, char es, const ::std::string &what) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnNodeGuarding(uint8_t id, bool occurred) noexcept override
The default implementation queues a notification for all registered drivers.
void OnSync(uint8_t cnt, const time_point &t) noexcept override
The default implementation queues a notification for all registered drivers.
void OnCanState(io::CanState new_state, io::CanState old_state) noexcept override
The default implementation invokes lely::canopen::Node::OnCanState() and queues a notification for ea...
void OnHeartbeat(uint8_t id, bool occurred) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnSyncError(uint16_t eec, uint8_t er) noexcept override
The default implementation queues a notification for all registered drivers.
void OnRpdoWrite(uint8_t id, uint16_t idx, uint8_t subidx) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnCommand(NmtCommand cs) noexcept override
The default implementation queues a notification for all registered drivers.
void OnState(uint8_t id, NmtState st) noexcept override
The default implementation queues a notification for the driver registered for node id.
void OnTime(const ::std::chrono::system_clock::time_point &abs_time) noexcept override
The default implementation queues a notification for all registered drivers.
void OnCanError(io::CanError error) noexcept override
The default implementation queues a notification for all registered drivers.
An accessor providing read-only access to a CANopen object in a local object dictionary.
ConstSubObject operator[](uint8_t subidx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen sub-object in the ...
An accessor providing read-only access to a CANopen sub-object in a local object dictionary.
T Read(::std::error_code &ec) const
Reads the value of the sub-object by submitting an SDO upload request to the local object dictionary.
T Read() const
Reads the value of the sub-object by submitting an SDO upload request to the local object dictionary.
A mutator providing read/write access to a CANopen object in a local object dictionary.
SubObject operator[](uint8_t subidx) noexcept
Returns a mutator object that provides read/write access to the specified CANopen sub-object in the l...
ConstSubObject operator[](uint8_t subidx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen sub-object in the ...
An accessor providing read-only access to TPDO-mapped objects in a remote object dictionary.
ConstObject operator[](uint16_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified RPDO-mapped object in the ...
A mutator providing read/write access to a CANopen sub-object in a local object dictionary.
void Write(const void *p, ::std::size_t n, ::std::error_code &ec)
Writes an OCTET_STRING or DOMAIN value to the sub-object by submitting an SDO download request to the...
void Write(T &&value, ::std::error_code &ec)
Writes a value to the sub-object by submitting an SDO download request to the local object dictionary...
void Write(const void *p, ::std::size_t n)
Writes an OCTET_STRING or DOMAIN value to the sub-object by submitting an SDO download request to the...
void WriteEvent()
Checks if the sub-object can be mapped into a PDO and, if so, triggers the transmission of every acyc...
void WriteEvent(::std::error_code &ec) noexcept
Checks if the sub-object can be mapped into a PDO and, if so, triggers the transmission of every acyc...
T Read() const
Reads the value of the sub-object by submitting an SDO upload request to the local object dictionary.
void Write(T &&value)
Writes a value to the sub-object by submitting an SDO download request to the local object dictionary...
SubObject & operator=(T &&value)
Sets the value of the sub-object.
T Read(::std::error_code &ec) const
Reads the value of the sub-object by submitting an SDO upload request to the local object dictionary.
void lock() override
Blocks until a lock can be obtained for the current execution agent (thread, process,...
void unlock() override
Releases the lock held by the execution agent. Throws no exceptions.
A mutator providing read/write access to TPDO-mapped objects in a remote object dictionary.
ConstObject operator[](uint16_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified TPDO-mapped object in the ...
Object operator[](uint16_t idx) noexcept
Returns a mutator object that provides read/write access to the specified PDO-mapped object in the re...
SdoFuture< T > AsyncRead(ev_exec_t *exec, uint8_t id, 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 ...
void OnSyncError(uint16_t eec, uint8_t er) noexcept override
The default implementation notifies all registered drivers.
bool IsConfig(uint8_t id) const
Returns true if the remote node is configuring (i.e., the 'update configuration' step of the NMT 'boo...
void TpdoEvent(int num=0) noexcept
void(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec) WriteSignature
The signature of the callback function invoked on completion of an asynchronous write (SDO download) ...
void SubmitWrite(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitWrite(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
ev::Future<::std::size_t, void > AsyncDeconfig()
Queues the DriverBase::OnDeconfig() method for all registered drivers and creates a future which beco...
void SubmitRead(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout)
Equivalent to SubmitRead(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
virtual void OnConfig(uint8_t id) noexcept
The function invoked when the 'update configuration' step is reached during the NMT 'boot slave' proc...
void(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec, T value) ReadSignature
The signature of the callback function invoked on completion of an asynchronous read (SDO upload) ope...
Object operator[](::std::ptrdiff_t idx) noexcept
Returns a mutator object that provides read/write access to the specified CANopen object in the local...
void OnTime(const ::std::chrono::system_clock::time_point &abs_time) noexcept override
The default implementation notifies all registered drivers.
void SubmitRead(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation.
RpdoMapped RpdoMapped(uint8_t id) const noexcept
Returns an accessor object that provides read-only access to RPDO-mapped objects in the remote object...
void OnEmcy(uint8_t id, uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept override
The default implementation notifies the driver registered for node id.
void OnHeartbeat(uint8_t id, bool occurred) noexcept override
The default implementation notifies the driver registered for node id.
void RpdoRtr(int num=0) noexcept
void Command(NmtCommand cs, uint8_t id=0)
Issues an NMT command to a slave.
BasicMaster(io::TimerBase &timer, io::CanChannelBase &chan, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen master.
BasicMaster(ev_exec_t *exec, io::TimerBase &timer, io::CanChannelBase &chan, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen master.
void Erase(DriverBase &driver)
Unregisters a driver for a remote CANopen node.
void OnCanError(io::CanError error) noexcept override
The default implementation notifies all registered drivers.
SdoFuture< void > AsyncWrite(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
void OnRpdoWrite(uint8_t id, uint16_t idx, uint8_t subidx) noexcept override
The default implementation notifies the driver registered for node id.
void OnBoot(::std::function< void(uint8_t, NmtState, char, const ::std::string &)> on_boot)
Registers the function invoked when the NMT 'boot slave' process completes.
void OnSync(uint8_t cnt, const time_point &t) noexcept override
The default implementation notifies all registered drivers.
void SubmitWrite(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, T &&value, F &&con)
Equivalent to SubmitWrite(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
SdoFuture< T > AsyncRead(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx)
Equivalent to AsyncRead(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
void Insert(DriverBase &driver)
Registers a driver for a remote CANopen node.
void Error(uint8_t id)
Indicates the occurrence of an error event on a remote node and triggers the error handling process (...
bool Boot(uint8_t id)
Requests the NMT 'boot slave' process for the specified node.
void SubmitWrite(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, T &&value, F &&con, ::std::error_code &ec)
Equivalent to SubmitWrite(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
void OnNodeGuarding(::std::function< void(uint8_t, bool)> on_node_guarding)
Registers the function invoked when a node guarding timeout event occurs or is resolved.
void SubmitWrite(ev_exec_t *exec, uint8_t id, 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 SubmitRead(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, F &&con, ::std::error_code &ec)
Equivalent to SubmitRead(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
bool IsReady(uint8_t id) const
Returns true if the remote node is ready (i.e., the NMT 'boot slave' process has successfully complet...
::std::chrono::milliseconds GetTimeout() const
Returns the SDO timeout used during the NMT 'boot slave' and 'check configuration' processes.
TpdoMapped TpdoMapped(uint8_t id) noexcept
Returns a mutator object that provides read/write access to TPDO-mapped objects in the remote object ...
void OnState(uint8_t id, NmtState st) noexcept override
The default implementation notifies the driver registered for node id.
void OnCommand(NmtCommand cs) noexcept override
The default implementation notifies all registered drivers.
void SubmitRead(uint8_t id, SdoUploadRequest< T > &req)
Equivalent to SubmitRead(uint8_t id, SdoUploadRequest<T>& req, ::std::error_code& ec),...
void SubmitRead(ev_exec_t *exec, uint8_t id, uint16_t idx, uint8_t subidx, F &&con)
Equivalent to SubmitRead(ev_exec_t* exec, uint8_t id, uint16_t idx, uint8_t subidx,...
void SetTimeout(const ::std::chrono::milliseconds &timeout)
Sets the SDO timeout used during the NMT 'boot slave' and 'check configuration' processes.
TpdoEventMutex tpdo_event_mutex
void ConfigResult(uint8_t id, ::std::error_code ec) noexcept
Reports the result of the 'update configuration' step to the NMT service.
void SubmitWrite(uint8_t id, SdoDownloadRequest< T > &req)
Equivalent to SubmitWrite(uint8_t id, SdoDownloadRequest<T>& req, ::std::error_code& ec),...
void CancelSdo(uint8_t id=0)
Aborts any ongoing or pending SDO requests for the specified slave.
void OnCanState(io::CanState new_state, io::CanState old_state) noexcept override
The default implementation invokes lely::canopen::Node::OnCanState() and notifies each registered dri...
void SubmitRead(uint8_t id, SdoUploadRequest< T > &req, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation.
ConstObject operator[](::std::ptrdiff_t idx) const noexcept
Returns an accessor object that provides read-only access to the specified CANopen object in the loca...
void SubmitWrite(uint8_t id, SdoDownloadRequest< T > &req, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation.
Sdo * GetSdo(uint8_t id)
Returns a pointer to the default client-SDO service for the given node.
SdoFuture< void > AsyncWrite(ev_exec_t *exec, uint8_t id, 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...
typename ::std::enable_if< detail::is_canopen_type< T >::value, T >::type Read(uint16_t idx, uint8_t subidx) const
Submits an SDO upload request to the local object dictionary.
void TpdoWriteEvent(uint8_t id, uint16_t idx, uint8_t subidx)
Triggers the transmission of every event-driven, asynchronous Transmit-PDO which is mapped into the s...
typename ::std::enable_if< detail::is_canopen_basic< T >::value, T >::type RpdoRead(uint8_t id, uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object in a remote object dictionary by submitting an SDO upload request to ...
typename ::std::enable_if< detail::is_canopen_basic< T >::value >::type TpdoWrite(uint8_t id, uint16_t idx, uint8_t subidx, T value)
Writes a value to a sub-object in a remote object dictionary by submitting an SDO download request to...
typename ::std::enable_if< detail::is_canopen_basic< T >::value, T >::type TpdoRead(uint8_t id, uint16_t idx, uint8_t subidx) const
Submits an SDO upload request to a TPDO-mapped sub-object in the local object dictionary,...
typename ::std::enable_if< detail::is_canopen_basic< T >::value >::type Write(uint16_t idx, uint8_t subidx, T value)
Submits an SDO download request to the local object dictionary.
void WriteEvent(uint16_t idx, uint8_t subidx)
Checks if the specified sub-object in the local object dictionary can be mapped into a PDO and,...
uint8_t id() const noexcept
Returns the node-ID.
The abstract driver interface for a remote CANopen node.
A mutex-like object that can be used to postpone the transmission of acyclic and event-driven Transmi...
The base class for CANopen nodes.
void SetTime()
Updates the CAN network time.
ev::Executor GetExecutor() const noexcept
Returns the executor used to process I/O and CANopen events.
An SDO download (i.e., write) request.
The type of exception thrown when an SDO abort code is received.
An SDO upload (i.e., read) request.
uint16_t idx
The object index.
uint8_t subidx
The object sub-index.
The type of objects thrown as exceptions to report a system error with an associated error code.
A reference to an abstract CAN channel.
void lock() final
Blocks until a lock can be obtained for the current execution agent (thread, process,...
A reference to an abstract timer.
CanError
The error flags of a CAN bus, which are not mutually exclusive.
CanState
The states of a CAN node, depending on the TX/RX error count.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
@ NO_SDO
Resource not available: SDO connection.
NmtCommand
The NMT command specifiers.
This header file is part of the C++ CANopen application library; it contains the CANopen node declara...
This header file is part of the C++ CANopen master library; it contains the Client-SDO queue declarat...
The internal implementation of the CANopen master.