39 Impl_(const ::std::string& dcf_txt, const ::std::string& dcf_bin, uint8_t
id,
44 if (mutex) mutex->lock();
48 if (mutex) mutex->unlock();
52 netid() const noexcept {
53 return dev->getNetid();
60 void Set(uint16_t idx, uint8_t subidx, const ::std::string& value,
61 ::std::error_code& ec);
63 void Set(uint16_t idx, uint8_t subidx, const ::std::vector<uint8_t>& value,
64 ::std::error_code& ec);
66 void Set(uint16_t idx, uint8_t subidx,
67 const ::std::basic_string<char16_t>& value, ::std::error_code& ec);
70 void Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n,
71 ::std::error_code& ec);
73 BasicLockable* mutex{
nullptr};
80 : impl_(new
Impl_(dcf_txt, dcf_bin,
id, mutex)) {}
84Device::~Device() =
default;
88 ::std::lock_guard<Impl_> lock(*impl_);
90 return impl_->netid();
95 ::std::lock_guard<Impl_> lock(*impl_);
103OnDnCon(
COCSDO*, uint16_t, uint8_t, uint32_t ac,
void* data)
noexcept {
104 *
static_cast<uint32_t*
>(data) = ac;
109OnUpCon(
COCSDO*, uint16_t, uint8_t, uint32_t ac, T value,
void* data)
noexcept {
110 auto* t =
static_cast<decltype(::std::tie(ac, value))*
>(data);
111 *t = ::std::forward_as_tuple(ac, ::std::move(value));
117typename ::std::enable_if<detail::IsCanopenType<T>::value, T>::type
119 ::std::error_code ec;
120 T value(
Read<T>(idx, subidx, ec));
121 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Read");
126typename ::std::enable_if<detail::IsCanopenType<T>::value, T>::type
127Device::Read(uint16_t idx, uint8_t subidx, ::std::error_code& ec)
const {
130 auto t = ::std::tie(ac, value);
132 ::std::lock_guard<Impl_> lock(*impl_);
133 if (upReq<T, &OnUpCon<T>>(*impl_->dev, idx, subidx, &t) == -1)
144typename ::std::enable_if<detail::IsCanopenBasic<T>::value>::type
146 ::std::error_code ec;
147 Write(idx, subidx, value, ec);
148 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Write");
152typename ::std::enable_if<detail::IsCanopenBasic<T>::value>::type
153Device::Write(uint16_t idx, uint8_t subidx, T value, ::std::error_code& ec) {
157 ::std::lock_guard<Impl_> lock(*impl_);
158 if (dnReq<N>(*impl_->dev, idx, subidx, value, &OnDnCon, &ac) == -1)
168typename ::std::enable_if<detail::IsCanopenArray<T>::value>::type
170 ::std::error_code ec;
171 Write(idx, subidx, value, ec);
172 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Write");
176typename ::std::enable_if<detail::IsCanopenArray<T>::value>::type
178 ::std::error_code& ec) {
182 ::std::lock_guard<Impl_> lock(*impl_);
183 if (dnReq<N>(*impl_->dev, idx, subidx, value, &OnDnCon, &ac) == -1)
192#ifndef DOXYGEN_SHOULD_SKIP_THIS
203 ::std::error_code&)
const;
211 ::std::error_code&)
const;
219 ::std::error_code&)
const;
227 ::std::error_code&)
const;
235 ::std::error_code&)
const;
243 ::std::error_code&)
const;
258 ::std::error_code&)
const;
260 const ::std::string&);
262 const ::std::string&,
267 uint16_t, uint8_t)
const;
269 uint16_t, uint8_t, ::std::error_code&)
const;
271 uint16_t, uint8_t, const ::std::vector<uint8_t>&);
273 uint16_t, uint8_t, const ::std::vector<uint8_t>&, ::std::error_code&);
276template ::std::basic_string<char16_t>
278template ::std::basic_string<char16_t>
280 ::std::error_code&)
const;
282 uint16_t, uint8_t, const ::std::basic_string<char16_t>&);
284 uint16_t, uint8_t, const ::std::basic_string<char16_t>&,
295 ::std::error_code&)
const;
307 ::std::error_code&)
const;
320 ::std::error_code&)
const;
329 ::std::error_code ec;
330 Write(idx, subidx, value, ec);
331 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Write");
336 ::std::error_code& ec) {
337 Write(idx, subidx, value, ::std::char_traits<char>::length(value), ec);
342 ::std::error_code ec;
343 Write(idx, subidx, value, ec);
344 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Write");
349 ::std::error_code& ec) {
353 ::std::lock_guard<Impl_> lock(*impl_);
355 if (dnReq<N>(*impl_->dev, idx, subidx, value, &OnDnCon, &ac) == -1)
365Device::Write(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n) {
366 ::std::error_code ec;
367 Write(idx, subidx, p, n, ec);
368 if (ec)
throw SdoError(
netid(),
id(), idx, subidx, ec,
"Write");
373 ::std::error_code& ec) {
376 ::std::lock_guard<Impl_> lock(*impl_);
377 if (dnReq(*impl_->dev, idx, subidx, p, n, &OnDnCon, &ac) == -1)
388 return impl_->dev.get();
391const ::std::type_info&
393 ::std::error_code ec;
394 auto& ti =
Type(idx, subidx, ec);
395 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Type");
399const ::std::type_info&
400Device::Type(uint16_t idx, uint8_t subidx, ::std::error_code& ec)
const {
401 auto obj = impl_->dev->find(idx);
407 auto sub = obj->find(subidx);
414 switch (sub->getType()) {
418 return typeid(int8_t);
420 return typeid(int16_t);
422 return typeid(int32_t);
424 return typeid(uint8_t);
426 return typeid(uint16_t);
428 return typeid(uint32_t);
430 return typeid(float);
432 return typeid(::std::string);
434 return typeid(::std::vector<uint8_t>);
436 return typeid(::std::basic_string<char16_t>);
440 return typeid(::std::vector<uint8_t>);
443 return typeid(double);
448 return typeid(int64_t);
454 return typeid(uint64_t);
461typename ::std::enable_if<detail::IsCanopenType<T>::value, T>::type
463 ::std::error_code ec;
464 auto value =
Get<T>(idx, subidx, ec);
465 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Get");
470typename ::std::enable_if<detail::IsCanopenType<T>::value, T>::type
471Device::Get(uint16_t idx, uint8_t subidx, ::std::error_code& ec)
const {
474 auto obj = impl_->dev->find(idx);
480 auto sub = obj->find(subidx);
494 return sub->getVal<N>();
498typename ::std::enable_if<detail::IsCanopenBasic<T>::value>::type
500 ::std::error_code ec;
501 Set(idx, subidx, value, ec);
502 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Set");
506typename ::std::enable_if<detail::IsCanopenBasic<T>::value>::type
507Device::Set(uint16_t idx, uint8_t subidx, T value, ::std::error_code& ec) {
510 impl_->Set<N>(idx, subidx, &value,
sizeof(value), ec);
514typename ::std::enable_if<detail::IsCanopenArray<T>::value>::type
516 ::std::error_code ec;
517 Set(idx, subidx, value, ec);
518 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Set");
522typename ::std::enable_if<detail::IsCanopenArray<T>::value>::type
524 ::std::error_code& ec) {
525 impl_->Set(idx, subidx, value, ec);
528#ifndef DOXYGEN_SHOULD_SKIP_THIS
539 ::std::error_code&)
const;
547 ::std::error_code&)
const;
555 ::std::error_code&)
const;
563 ::std::error_code&)
const;
571 ::std::error_code&)
const;
579 ::std::error_code&)
const;
593 ::std::error_code&)
const;
595 const ::std::string&);
597 const ::std::string&,
602 uint16_t, uint8_t)
const;
604 uint16_t, uint8_t, ::std::error_code&)
const;
606 uint16_t, uint8_t, const ::std::vector<uint8_t>&);
608 const ::std::vector<uint8_t>&,
612template ::std::basic_string<char16_t>
614template ::std::basic_string<char16_t>
616 ::std::error_code&)
const;
618 uint16_t, uint8_t, const ::std::basic_string<char16_t>&);
620 uint16_t, uint8_t, const ::std::basic_string<char16_t>&,
631 ::std::error_code&)
const;
643 ::std::error_code&)
const;
656 ::std::error_code&)
const;
665 ::std::error_code ec;
666 Set(idx, subidx, value, ec);
667 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Set");
672 ::std::error_code& ec) {
678 ::std::error_code ec;
679 Set(idx, subidx, value, ec);
680 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Set");
685 ::std::error_code& ec) {
690Device::Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n) {
691 ::std::error_code ec;
692 Set(idx, subidx, p, n, ec);
693 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec,
"Set");
697Device::Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n,
698 ::std::error_code& ec) {
702Device::Impl_::Impl_(const ::std::string& dcf_txt, const ::std::string& dcf_bin,
705 if (!dcf_bin.empty() &&
dev->readDCF(
nullptr,
nullptr, dcf_bin.c_str()) == -1)
706 throw_errc(
"Device");
708 if (
id != 0xff &&
dev->setId(
id) == -1) throw_errc(
"Device");
712Device::Impl_::Set(uint16_t idx, uint8_t subidx, const ::std::string& value,
713 ::std::error_code& ec) {
714 Set<CO_DEFTYPE_VISIBLE_STRING>(idx, subidx, value.c_str(), 0, ec);
718Device::Impl_::Set(uint16_t idx, uint8_t subidx,
719 const ::std::vector<uint8_t>& value, ::std::error_code& ec) {
724Device::Impl_::Set(uint16_t idx, uint8_t subidx,
725 const ::std::basic_string<char16_t>& value,
726 ::std::error_code& ec) {
732Device::Impl_::Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n,
733 ::std::error_code& ec) {
734 auto obj =
dev->find(idx);
740 auto sub = obj->find(subidx);
An opaque CANopen Client-SDO service type.
An opaque CANopen device type.
An abstract interface conforming to the BasicLockable concept.
The CANopen device description.
uint8_t netid() const noexcept
Returns the network-ID.
typename::std::enable_if< detail::IsCanopenType< T >::value, T >::type Get(uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object.
const ::std::type_info & Type(uint16_t idx, uint8_t subidx) const
Returns the type of a sub-object.
Device(const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff, BasicLockable *mutex=nullptr)
Creates a new CANopen device description.
typename::std::enable_if< detail::IsCanopenType< T >::value, T >::type Read(uint16_t idx, uint8_t subidx) const
Submits an SDO upload request to the local object dictionary.
CODev * dev() const noexcept
Returns a pointer to the internal CANopen device from <lely/co/dev.hpp>.
typename::std::enable_if< detail::IsCanopenBasic< T >::value >::type Set(uint16_t idx, uint8_t subidx, T value)
Writes a CANopen basic value to a sub-object.
typename::std::enable_if< detail::IsCanopenBasic< T >::value >::type Write(uint16_t idx, uint8_t subidx, T value)
Submits an SDO download request to the local object dictionary.
uint8_t id() const noexcept
Returns the node-ID.
The type of exception thrown when an SDO abort code is received.
This header file is part of the CANopen library; it contains the C++ interface of the Client-SDO decl...
This header file is part of the CANopen library; it contains the C++ interface of the Electronic Data...
This header file is part of the C++ CANopen application library; it contains the CANopen device descr...
bool IsCanopenSame(uint16_t t1, uint16_t t2)
Returns true if the CANopen data types t1 and t2 map to the same C++ type, and false if not.
Namespace for the C++ CANopen application library.
SdoErrc
The SDO abort codes.
@ NO_SUB
Sub-index does not exist.
@ TYPE_LEN
Data type does not match, length of service parameter does not match.
@ NO_OBJ
Object does not exist in the object dictionary.
Global namespace for the Lely Industries N.V. libraries.
unique_c_ptr< T > make_unique_c(Args &&... args)
Creates an instance of a trivial, standard layout or incomplete C type and wraps it in a lely::unique...
::std::unique_ptr< T, delete_c_type< T > > unique_c_ptr
A specialization of std::unique_ptr for trivial, standard layout or incomplete C types,...
This header file is part of the CANopen library; it contains the C++ interface of the object dictiona...
This is the internal header file of the C++ CANopen application library.
The internal implementation of the CANopen device description.
virtual void lock() override
Blocks until a lock can be obtained for the current execution agent (thread, process,...
virtual void unlock() override
Releases the lock held by the execution agent. Throws no exceptions.
A class template mapping CANopen types to C++ types.
#define CO_DEFTYPE_UNICODE_STRING
The data type (and object index) of an array of (16-bit) Unicode characters.
#define CO_DEFTYPE_UNSIGNED16
The data type (and object index) of a 16-bit unsigned integer.
#define CO_DEFTYPE_VISIBLE_STRING
The data type (and object index) of an array of visible characters.
#define CO_DEFTYPE_UNSIGNED64
The data type (and object index) of a 64-bit unsigned integer.
#define CO_DEFTYPE_INTEGER8
The data type (and object index) of an 8-bit signed integer.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
#define CO_DEFTYPE_UNSIGNED8
The data type (and object index) of an 8-bit unsigned integer.
#define CO_DEFTYPE_REAL64
The data type (and object index) of a 64-bit IEEE-754 floating-point number.
#define CO_DEFTYPE_BOOLEAN
The data type (and object index) of a boolean truth value.
#define CO_DEFTYPE_INTEGER32
The data type (and object index) of a 32-bit signed integer.
#define CO_DEFTYPE_INTEGER64
The data type (and object index) of a 64-bit signed integer.
#define CO_DEFTYPE_UNSIGNED32
The data type (and object index) of a 32-bit unsigned integer.
#define CO_DEFTYPE_INTEGER16
The data type (and object index) of a 16-bit signed integer.
#define CO_DEFTYPE_OCTET_STRING
The data type (and object index) of an array of octets.
#define CO_DEFTYPE_REAL32
The data type (and object index) of a 32-bit IEEE-754 floating-point number.