34#if !LELY_NO_CO_RPDO && !LELY_NO_CO_MPDO
39#if !LELY_NO_CO_RPDO && !LELY_NO_CO_MPDO
42#if !LELY_NO_CO_RPDO || !LELY_NO_CO_TPDO
59 operator()(
co_dev_t* dev)
const noexcept {
68 virtual ~Impl_() =
default;
72 if (mutex) mutex->lock();
77 if (mutex) mutex->unlock();
81 netid() const noexcept {
90 void OnWrite(uint16_t idx, uint8_t subidx);
92 ::std::tuple<uint16_t, uint8_t>
93 RpdoMapping(uint8_t
id, uint16_t idx, uint8_t subidx,
94 ::std::error_code& ec)
const noexcept {
97 auto it = rpdo_mapping.find((
static_cast<uint32_t
>(
id) << 24) |
98 (
static_cast<uint32_t
>(idx) << 8) | subidx);
99 if (it != rpdo_mapping.end()) {
100 idx = (it->second >> 8) & 0xffff;
101 subidx = it->second & 0xff;
111 return ::std::make_tuple(idx, subidx);
114 ::std::tuple<uint8_t, uint16_t, uint8_t>
115 RpdoMapping(uint16_t idx, uint8_t subidx,
116 ::std::error_code& ec)
const noexcept {
119 auto it = rpdo_mapping.find((
static_cast<uint32_t
>(idx) << 8) | subidx);
120 if (it != rpdo_mapping.end()) {
121 id = (it->second >> 24) & 0xff;
122 idx = (it->second >> 8) & 0xffff;
123 subidx = it->second & 0xff;
133 return ::std::make_tuple(
id, idx, subidx);
136 ::std::tuple<uint16_t, uint8_t>
137 TpdoMapping(uint8_t
id, uint16_t idx, uint8_t subidx,
138 ::std::error_code& ec)
const noexcept {
141 auto it = tpdo_mapping.find((
static_cast<uint32_t
>(
id) << 24) |
142 (
static_cast<uint32_t
>(idx) << 8) | subidx);
143 if (it != tpdo_mapping.end()) {
144 idx = (it->second >> 8) & 0xffff;
145 subidx = it->second & 0xff;
155 return ::std::make_tuple(idx, subidx);
160 BasicLockable* mutex{
nullptr};
162 ::std::unique_ptr<co_dev_t, DeviceDeleter> dev;
165 ::std::map<uint32_t, uint32_t> rpdo_mapping;
168 ::std::map<uint32_t, uint32_t> tpdo_mapping;
171 ::std::function<void(uint16_t, uint8_t)> on_write;
173 ::std::function<void(uint8_t, uint16_t, uint8_t)> on_rpdo_write;
180 : impl_(new
Impl_(this, dcf_txt, dcf_bin, id, mutex)) {}
183Device::~Device() =
default;
187 ::std::lock_guard<Impl_> lock(*impl_);
189 return impl_->netid();
194 ::std::lock_guard<Impl_> lock(*impl_);
202OnDnCon(
co_csdo_t*, uint16_t, uint8_t, uint32_t ac,
void* data)
noexcept {
203 *
static_cast<uint32_t*
>(data) = ac;
208OnUpCon(
co_csdo_t*, uint16_t, uint8_t, uint32_t ac,
const void* ptr,
size_t n,
209 void* data)
noexcept {
210 using traits = canopen_traits<T>;
211 using c_type =
typename traits::c_type;
213 auto t =
static_cast<::std::tuple<uint32_t&, T&>*
>(data);
217 ::std::error_code ec;
218 val = traits::construct(ptr, n, ec);
219 if (ec) ac =
static_cast<uint32_t
>(
sdo_errc(ec));
222 *t = ::std::forward_as_tuple(ac, traits::from_c_type(val));
224 traits::destroy(val);
230typename ::std::enable_if<is_canopen<T>::value, T>::type
232 ::std::error_code ec;
233 T value(Read<T>(idx, subidx, ec));
239typename ::std::enable_if<is_canopen<T>::value, T>::type
240Device::Read(uint16_t idx, uint8_t subidx, ::std::error_code& ec)
const {
243 auto t = ::std::tie(ac, value);
245 ::std::lock_guard<Impl_> lock(*impl_);
261typename ::std::enable_if<is_canopen<T>::value>::type
263 ::std::error_code ec;
264 Write(idx, subidx, value, ec);
269typename ::std::enable_if<is_canopen<T>::value>::type
271 ::std::error_code& ec) {
274 auto val = traits::to_c_type(value, ec);
279 ::std::lock_guard<Impl_> lock(*impl_);
294 traits::destroy(val);
299Device::Write(uint16_t idx, uint8_t subidx, const ::std::string& value,
300 ::std::error_code& ec) {
301 Write(idx, subidx, value.c_str(), ec);
306Device::Write(uint16_t idx, uint8_t subidx, const ::std::vector<uint8_t>& value,
307 ::std::error_code& ec) {
308 Write(idx, subidx, value.data(), value.size(), ec);
311#ifndef DOXYGEN_SHOULD_SKIP_THIS
314template bool Device::Read<bool>(uint16_t, uint8_t)
const;
315template bool Device::Read<bool>(uint16_t, uint8_t, ::std::error_code&)
const;
316template void Device::Write<bool>(uint16_t, uint8_t,
const bool&);
317template void Device::Write<bool>(uint16_t, uint8_t,
const bool&,
321template int8_t Device::Read<int8_t>(uint16_t, uint8_t)
const;
322template int8_t Device::Read<int8_t>(uint16_t, uint8_t,
323 ::std::error_code&)
const;
324template void Device::Write<int8_t>(uint16_t, uint8_t,
const int8_t&);
325template void Device::Write<int8_t>(uint16_t, uint8_t,
const int8_t&,
329template int16_t Device::Read<int16_t>(uint16_t, uint8_t)
const;
330template int16_t Device::Read<int16_t>(uint16_t, uint8_t,
331 ::std::error_code&)
const;
332template void Device::Write<int16_t>(uint16_t, uint8_t,
const int16_t&);
333template void Device::Write<int16_t>(uint16_t, uint8_t,
const int16_t&,
337template int32_t Device::Read<int32_t>(uint16_t, uint8_t)
const;
338template int32_t Device::Read<int32_t>(uint16_t, uint8_t,
339 ::std::error_code&)
const;
340template void Device::Write<int32_t>(uint16_t, uint8_t,
const int32_t&);
341template void Device::Write<int32_t>(uint16_t, uint8_t,
const int32_t&,
345template uint8_t Device::Read<uint8_t>(uint16_t, uint8_t)
const;
346template uint8_t Device::Read<uint8_t>(uint16_t, uint8_t,
347 ::std::error_code&)
const;
348template void Device::Write<uint8_t>(uint16_t, uint8_t,
const uint8_t&);
349template void Device::Write<uint8_t>(uint16_t, uint8_t,
const uint8_t&,
353template uint16_t Device::Read<uint16_t>(uint16_t, uint8_t)
const;
354template uint16_t Device::Read<uint16_t>(uint16_t, uint8_t,
355 ::std::error_code&)
const;
356template void Device::Write<uint16_t>(uint16_t, uint8_t,
const uint16_t&);
357template void Device::Write<uint16_t>(uint16_t, uint8_t,
const uint16_t&,
361template uint32_t Device::Read<uint32_t>(uint16_t, uint8_t)
const;
362template uint32_t Device::Read<uint32_t>(uint16_t, uint8_t,
363 ::std::error_code&)
const;
364template void Device::Write<uint32_t>(uint16_t, uint8_t,
const uint32_t&);
365template void Device::Write<uint32_t>(uint16_t, uint8_t,
const uint32_t&,
369template float Device::Read<float>(uint16_t, uint8_t)
const;
370template float Device::Read<float>(uint16_t, uint8_t, ::std::error_code&)
const;
371template void Device::Write<float>(uint16_t, uint8_t,
const float&);
372template void Device::Write<float>(uint16_t, uint8_t,
const float&,
376template ::std::string Device::Read<::std::string>(uint16_t, uint8_t)
const;
377template ::std::string Device::Read<::std::string>(uint16_t, uint8_t,
378 ::std::error_code&)
const;
379template void Device::Write<::std::string>(uint16_t, uint8_t,
380 const ::std::string&);
386template ::std::vector<uint8_t> Device::Read<::std::vector<uint8_t>>(
387 uint16_t, uint8_t)
const;
388template ::std::vector<uint8_t> Device::Read<::std::vector<uint8_t>>(
389 uint16_t, uint8_t, ::std::error_code&)
const;
390template void Device::Write<::std::vector<uint8_t>>(
391 uint16_t, uint8_t, const ::std::vector<uint8_t>&);
396template ::std::basic_string<char16_t>
397 Device::Read<::std::basic_string<char16_t>>(uint16_t, uint8_t)
const;
398template ::std::basic_string<char16_t>
399Device::Read<::std::basic_string<char16_t>>(uint16_t, uint8_t,
400 ::std::error_code&)
const;
401template void Device::Write<::std::basic_string<char16_t>>(
402 uint16_t, uint8_t, const ::std::basic_string<char16_t>&);
403template void Device::Write<::std::basic_string<char16_t>>(
404 uint16_t, uint8_t, const ::std::basic_string<char16_t>&,
413template double Device::Read<double>(uint16_t, uint8_t)
const;
414template double Device::Read<double>(uint16_t, uint8_t,
415 ::std::error_code&)
const;
416template void Device::Write<double>(uint16_t, uint8_t,
const double&);
417template void Device::Write<double>(uint16_t, uint8_t,
const double&,
425template int64_t Device::Read<int64_t>(uint16_t, uint8_t)
const;
426template int64_t Device::Read<int64_t>(uint16_t, uint8_t,
427 ::std::error_code&)
const;
428template void Device::Write<int64_t>(uint16_t, uint8_t,
const int64_t&);
429template void Device::Write<int64_t>(uint16_t, uint8_t,
const int64_t&,
438template uint64_t Device::Read<uint64_t>(uint16_t, uint8_t)
const;
439template uint64_t Device::Read<uint64_t>(uint16_t, uint8_t,
440 ::std::error_code&)
const;
441template void Device::Write<uint64_t>(uint16_t, uint8_t,
const uint64_t&);
442template void Device::Write<uint64_t>(uint16_t, uint8_t,
const uint64_t&,
449 ::std::error_code ec;
450 Write(idx, subidx, value, ec);
456 ::std::error_code& ec) {
457 Write(idx, subidx, value, ::std::char_traits<char>::length(value), ec);
462 ::std::error_code ec;
463 Write(idx, subidx, value, ec);
469 ::std::error_code& ec) {
472 auto val = traits::to_c_type(value, ec);
477 ::std::lock_guard<Impl_> lock(*impl_);
492 traits::destroy(val);
496Device::Write(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n) {
497 ::std::error_code ec;
498 Write(idx, subidx, p, n, ec);
504 ::std::error_code& ec) {
507 ::std::lock_guard<Impl_> lock(*impl_);
523 ::std::error_code ec;
530 ::std::error_code& ec) {
533 ::std::lock_guard<Impl_> lock(*impl_);
549 ::std::error_code ec;
576 ::std::error_code ec;
583 ::std::error_code& ec)
noexcept {
584 ::std::lock_guard<Impl_> lock(*impl_);
586 SetEvent(idx, subidx, ec);
590typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
592 ::std::error_code ec;
593 T value(RpdoRead<T>(
id, idx, subidx, ec));
599typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
601 ::std::error_code& ec)
const {
604 ::std::lock_guard<Impl_> lock(*impl_);
605 ::std::tie(idx, subidx) = impl_->RpdoMapping(
id, idx, subidx, ec);
608 return Read<T>(idx, subidx, ec);
612typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
614 ::std::error_code ec;
615 T value(TpdoRead<T>(
id, idx, subidx, ec));
621typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
623 ::std::error_code& ec)
const {
626 ::std::lock_guard<Impl_> lock(*impl_);
627 ::std::tie(idx, subidx) = impl_->TpdoMapping(
id, idx, subidx, ec);
630 return Read<T>(idx, subidx, ec);
634typename ::std::enable_if<is_canopen_basic<T>::value>::type
636 ::std::error_code ec;
642typename ::std::enable_if<is_canopen_basic<T>::value>::type
644 ::std::error_code& ec) {
647 ::std::lock_guard<Impl_> lock(*impl_);
648 ::std::tie(idx, subidx) = impl_->TpdoMapping(
id, idx, subidx, ec);
650 if (!ec) Write<T>(idx, subidx, value, ec);
653#ifndef DOXYGEN_SHOULD_SKIP_THIS
656template bool Device::RpdoRead<bool>(uint8_t, uint16_t, uint8_t)
const;
657template bool Device::RpdoRead<bool>(uint8_t, uint16_t, uint8_t,
658 ::std::error_code&)
const;
659template bool Device::TpdoRead<bool>(uint8_t, uint16_t, uint8_t)
const;
660template bool Device::TpdoRead<bool>(uint8_t, uint16_t, uint8_t,
661 ::std::error_code&)
const;
662template void Device::TpdoWrite<bool>(uint8_t, uint16_t, uint8_t,
bool);
663template void Device::TpdoWrite<bool>(uint8_t, uint16_t, uint8_t,
bool,
667template int8_t Device::RpdoRead<int8_t>(uint8_t, uint16_t, uint8_t)
const;
668template int8_t Device::RpdoRead<int8_t>(uint8_t, uint16_t, uint8_t,
669 ::std::error_code&)
const;
670template int8_t Device::TpdoRead<int8_t>(uint8_t, uint16_t, uint8_t)
const;
671template int8_t Device::TpdoRead<int8_t>(uint8_t, uint16_t, uint8_t,
672 ::std::error_code&)
const;
673template void Device::TpdoWrite<int8_t>(uint8_t, uint16_t, uint8_t, int8_t);
674template void Device::TpdoWrite<int8_t>(uint8_t, uint16_t, uint8_t, int8_t,
678template int16_t Device::RpdoRead<int16_t>(uint8_t, uint16_t, uint8_t)
const;
679template int16_t Device::RpdoRead<int16_t>(uint8_t, uint16_t, uint8_t,
680 ::std::error_code&)
const;
681template int16_t Device::TpdoRead<int16_t>(uint8_t, uint16_t, uint8_t)
const;
682template int16_t Device::TpdoRead<int16_t>(uint8_t, uint16_t, uint8_t,
683 ::std::error_code&)
const;
684template void Device::TpdoWrite<int16_t>(uint8_t, uint16_t, uint8_t, int16_t);
685template void Device::TpdoWrite<int16_t>(uint8_t, uint16_t, uint8_t, int16_t,
689template int32_t Device::RpdoRead<int32_t>(uint8_t, uint16_t, uint8_t)
const;
690template int32_t Device::RpdoRead<int32_t>(uint8_t, uint16_t, uint8_t,
691 ::std::error_code&)
const;
692template int32_t Device::TpdoRead<int32_t>(uint8_t, uint16_t, uint8_t)
const;
693template int32_t Device::TpdoRead<int32_t>(uint8_t, uint16_t, uint8_t,
694 ::std::error_code&)
const;
695template void Device::TpdoWrite<int32_t>(uint8_t, uint16_t, uint8_t, int32_t);
696template void Device::TpdoWrite<int32_t>(uint8_t, uint16_t, uint8_t, int32_t,
700template uint8_t Device::RpdoRead<uint8_t>(uint8_t, uint16_t, uint8_t)
const;
701template uint8_t Device::RpdoRead<uint8_t>(uint8_t, uint16_t, uint8_t,
702 ::std::error_code&)
const;
703template uint8_t Device::TpdoRead<uint8_t>(uint8_t, uint16_t, uint8_t)
const;
704template uint8_t Device::TpdoRead<uint8_t>(uint8_t, uint16_t, uint8_t,
705 ::std::error_code&)
const;
706template void Device::TpdoWrite<uint8_t>(uint8_t, uint16_t, uint8_t, uint8_t);
707template void Device::TpdoWrite<uint8_t>(uint8_t, uint16_t, uint8_t, uint8_t,
711template uint16_t Device::RpdoRead<uint16_t>(uint8_t, uint16_t, uint8_t)
const;
712template uint16_t Device::RpdoRead<uint16_t>(uint8_t, uint16_t, uint8_t,
713 ::std::error_code&)
const;
714template uint16_t Device::TpdoRead<uint16_t>(uint8_t, uint16_t, uint8_t)
const;
715template uint16_t Device::TpdoRead<uint16_t>(uint8_t, uint16_t, uint8_t,
716 ::std::error_code&)
const;
717template void Device::TpdoWrite<uint16_t>(uint8_t, uint16_t, uint8_t, uint16_t);
718template void Device::TpdoWrite<uint16_t>(uint8_t, uint16_t, uint8_t, uint16_t,
722template uint32_t Device::RpdoRead<uint32_t>(uint8_t, uint16_t, uint8_t)
const;
723template uint32_t Device::RpdoRead<uint32_t>(uint8_t, uint16_t, uint8_t,
724 ::std::error_code&)
const;
725template uint32_t Device::TpdoRead<uint32_t>(uint8_t, uint16_t, uint8_t)
const;
726template uint32_t Device::TpdoRead<uint32_t>(uint8_t, uint16_t, uint8_t,
727 ::std::error_code&)
const;
728template void Device::TpdoWrite<uint32_t>(uint8_t, uint16_t, uint8_t, uint32_t);
729template void Device::TpdoWrite<uint32_t>(uint8_t, uint16_t, uint8_t, uint32_t,
733template float Device::RpdoRead<float>(uint8_t, uint16_t, uint8_t)
const;
734template float Device::RpdoRead<float>(uint8_t, uint16_t, uint8_t,
735 ::std::error_code&)
const;
736template float Device::TpdoRead<float>(uint8_t, uint16_t, uint8_t)
const;
737template float Device::TpdoRead<float>(uint8_t, uint16_t, uint8_t,
738 ::std::error_code&)
const;
739template void Device::TpdoWrite<float>(uint8_t, uint16_t, uint8_t,
float);
740template void Device::TpdoWrite<float>(uint8_t, uint16_t, uint8_t,
float,
752template double Device::RpdoRead<double>(uint8_t, uint16_t, uint8_t)
const;
753template double Device::RpdoRead<double>(uint8_t, uint16_t, uint8_t,
754 ::std::error_code&)
const;
755template double Device::TpdoRead<double>(uint8_t, uint16_t, uint8_t)
const;
756template double Device::TpdoRead<double>(uint8_t, uint16_t, uint8_t,
757 ::std::error_code&)
const;
758template void Device::TpdoWrite<double>(uint8_t, uint16_t, uint8_t,
double);
759template void Device::TpdoWrite<double>(uint8_t, uint16_t, uint8_t,
double,
767template int64_t Device::RpdoRead<int64_t>(uint8_t, uint16_t, uint8_t)
const;
768template int64_t Device::RpdoRead<int64_t>(uint8_t, uint16_t, uint8_t,
769 ::std::error_code&)
const;
770template int64_t Device::TpdoRead<int64_t>(uint8_t, uint16_t, uint8_t)
const;
771template int64_t Device::TpdoRead<int64_t>(uint8_t, uint16_t, uint8_t,
772 ::std::error_code&)
const;
773template void Device::TpdoWrite<int64_t>(uint8_t, uint16_t, uint8_t, int64_t);
774template void Device::TpdoWrite<int64_t>(uint8_t, uint16_t, uint8_t, int64_t,
783template uint64_t Device::RpdoRead<uint64_t>(uint8_t, uint16_t, uint8_t)
const;
784template uint64_t Device::RpdoRead<uint64_t>(uint8_t, uint16_t, uint8_t,
785 ::std::error_code&)
const;
786template uint64_t Device::TpdoRead<uint64_t>(uint8_t, uint16_t, uint8_t)
const;
787template uint64_t Device::TpdoRead<uint64_t>(uint8_t, uint16_t, uint8_t,
788 ::std::error_code&)
const;
789template void Device::TpdoWrite<uint64_t>(uint8_t, uint16_t, uint8_t, uint64_t);
790template void Device::TpdoWrite<uint64_t>(uint8_t, uint16_t, uint8_t, uint64_t,
797 ::std::error_code ec;
804 ::std::error_code& ec)
noexcept {
805 ::std::lock_guard<Impl_> lock(*impl_);
807 TpdoSetEvent(
id, idx, subidx, ec);
811Device::OnWrite(::std::function<
void(uint16_t, uint8_t)> on_write) {
812 ::std::lock_guard<Impl_> lock(*impl_);
813 impl_->on_write = on_write;
818 ::std::function<
void(uint8_t, uint16_t, uint8_t)> on_rpdo_write) {
822 ::std::lock_guard<Impl_> lock(*impl_);
823 impl_->on_rpdo_write = on_rpdo_write;
829 return impl_->dev.get();
832const ::std::type_info&
834 ::std::error_code ec;
835 auto& ti =
Type(idx, subidx, ec);
840const ::std::type_info&
842 ::std::error_code& ec)
const noexcept {
860 return typeid(int8_t);
862 return typeid(int16_t);
864 return typeid(int32_t);
866 return typeid(uint8_t);
868 return typeid(uint16_t);
870 return typeid(uint32_t);
872 return typeid(float);
874 return typeid(::std::string);
876 return typeid(::std::vector<uint8_t>);
878 return typeid(::std::basic_string<char16_t>);
882 return typeid(::std::vector<uint8_t>);
885 return typeid(double);
890 return typeid(int64_t);
896 return typeid(uint64_t);
903typename ::std::enable_if<is_canopen<T>::value, T>::type
905 ::std::error_code ec;
906 auto value = Get<T>(idx, subidx, ec);
912typename ::std::enable_if<is_canopen<T>::value, T>::type
914 ::std::error_code& ec)
const noexcept {
916 using c_type =
typename traits::c_type;
938 return traits::from_c_type(*pval);
942typename ::std::enable_if<is_canopen<T>::value>::type
944 ::std::error_code ec;
945 Set(idx, subidx, value, ec);
950typename ::std::enable_if<is_canopen<T>::value>::type
952 ::std::error_code& ec)
noexcept {
972 auto val = traits::to_c_type(value, ec);
974 auto p = traits::address(val);
975 auto n = traits::size(val);
985 traits::destroy(val);
990Device::Set(uint16_t idx, uint8_t subidx, const ::std::string& value,
991 ::std::error_code& ec)
noexcept {
992 Set(idx, subidx, value.c_str(), ec);
997Device::Set(uint16_t idx, uint8_t subidx, const ::std::vector<uint8_t>& value,
998 ::std::error_code& ec)
noexcept {
999 Set(idx, subidx, value.data(), value.size(), ec);
1002#ifndef DOXYGEN_SHOULD_SKIP_THIS
1005template bool Device::Get<bool>(uint16_t, uint8_t)
const;
1006template bool Device::Get<bool>(uint16_t, uint8_t,
1007 ::std::error_code&)
const noexcept;
1008template void Device::Set<bool>(uint16_t, uint8_t,
const bool&);
1009template void Device::Set<bool>(uint16_t, uint8_t,
const bool&,
1010 ::std::error_code&)
noexcept;
1013template int8_t Device::Get<int8_t>(uint16_t, uint8_t)
const;
1014template int8_t Device::Get<int8_t>(uint16_t, uint8_t,
1015 ::std::error_code&)
const noexcept;
1016template void Device::Set<int8_t>(uint16_t, uint8_t,
const int8_t&);
1017template void Device::Set<int8_t>(uint16_t, uint8_t,
const int8_t&,
1018 ::std::error_code&)
noexcept;
1021template int16_t Device::Get<int16_t>(uint16_t, uint8_t)
const;
1022template int16_t Device::Get<int16_t>(uint16_t, uint8_t,
1023 ::std::error_code&)
const noexcept;
1024template void Device::Set<int16_t>(uint16_t, uint8_t,
const int16_t&);
1025template void Device::Set<int16_t>(uint16_t, uint8_t,
const int16_t&,
1026 ::std::error_code&)
noexcept;
1029template int32_t Device::Get<int32_t>(uint16_t, uint8_t)
const;
1030template int32_t Device::Get<int32_t>(uint16_t, uint8_t,
1031 ::std::error_code&)
const noexcept;
1032template void Device::Set<int32_t>(uint16_t, uint8_t,
const int32_t&);
1033template void Device::Set<int32_t>(uint16_t, uint8_t,
const int32_t&,
1034 ::std::error_code&)
noexcept;
1037template uint8_t Device::Get<uint8_t>(uint16_t, uint8_t)
const;
1038template uint8_t Device::Get<uint8_t>(uint16_t, uint8_t,
1039 ::std::error_code&)
const noexcept;
1040template void Device::Set<uint8_t>(uint16_t, uint8_t,
const uint8_t&);
1041template void Device::Set<uint8_t>(uint16_t, uint8_t,
const uint8_t&,
1042 ::std::error_code&)
noexcept;
1045template uint16_t Device::Get<uint16_t>(uint16_t, uint8_t)
const;
1046template uint16_t Device::Get<uint16_t>(uint16_t, uint8_t,
1047 ::std::error_code&)
const noexcept;
1048template void Device::Set<uint16_t>(uint16_t, uint8_t,
const uint16_t&);
1049template void Device::Set<uint16_t>(uint16_t, uint8_t,
const uint16_t&,
1050 ::std::error_code&)
noexcept;
1053template uint32_t Device::Get<uint32_t>(uint16_t, uint8_t)
const;
1054template uint32_t Device::Get<uint32_t>(uint16_t, uint8_t,
1055 ::std::error_code&)
const noexcept;
1056template void Device::Set<uint32_t>(uint16_t, uint8_t,
const uint32_t&);
1057template void Device::Set<uint32_t>(uint16_t, uint8_t,
const uint32_t&,
1058 ::std::error_code&)
noexcept;
1061template float Device::Get<float>(uint16_t, uint8_t)
const;
1062template float Device::Get<float>(uint16_t, uint8_t,
1063 ::std::error_code&)
const noexcept;
1064template void Device::Set<float>(uint16_t, uint8_t,
const float&);
1065template void Device::Set<float>(uint16_t, uint8_t,
const float&,
1066 ::std::error_code&)
noexcept;
1069template ::std::string Device::Get<::std::string>(uint16_t, uint8_t)
const;
1070template ::std::string Device::Get<::std::string>(
1071 uint16_t, uint8_t, ::std::error_code&)
const noexcept;
1072template void Device::Set<::std::string>(uint16_t, uint8_t,
1073 const ::std::string&);
1079template ::std::vector<uint8_t> Device::Get<::std::vector<uint8_t>>(
1080 uint16_t, uint8_t)
const;
1081template ::std::vector<uint8_t> Device::Get<::std::vector<uint8_t>>(
1082 uint16_t, uint8_t, ::std::error_code&)
const noexcept;
1083template void Device::Set<::std::vector<uint8_t>>(
1084 uint16_t, uint8_t, const ::std::vector<uint8_t>&);
1092template ::std::basic_string<char16_t>
1093 Device::Get<::std::basic_string<char16_t>>(uint16_t, uint8_t)
const;
1094template ::std::basic_string<char16_t>
1095Device::Get<::std::basic_string<char16_t>>(uint16_t, uint8_t,
1096 ::std::error_code&)
const noexcept;
1097template void Device::Set<::std::basic_string<char16_t>>(
1098 uint16_t, uint8_t, const ::std::basic_string<char16_t>&);
1099template void Device::Set<::std::basic_string<char16_t>>(
1100 uint16_t, uint8_t, const ::std::basic_string<char16_t>&,
1101 ::std::error_code&)
noexcept;
1109template double Device::Get<double>(uint16_t, uint8_t)
const;
1110template double Device::Get<double>(uint16_t, uint8_t,
1111 ::std::error_code&)
const noexcept;
1112template void Device::Set<double>(uint16_t, uint8_t,
const double&);
1113template void Device::Set<double>(uint16_t, uint8_t,
const double&,
1114 ::std::error_code&)
noexcept;
1121template int64_t Device::Get<int64_t>(uint16_t, uint8_t)
const;
1122template int64_t Device::Get<int64_t>(uint16_t, uint8_t,
1123 ::std::error_code&)
const noexcept;
1124template void Device::Set<int64_t>(uint16_t, uint8_t,
const int64_t&);
1125template void Device::Set<int64_t>(uint16_t, uint8_t,
const int64_t&,
1126 ::std::error_code&)
noexcept;
1134template uint64_t Device::Get<uint64_t>(uint16_t, uint8_t)
const;
1135template uint64_t Device::Get<uint64_t>(uint16_t, uint8_t,
1136 ::std::error_code&)
const noexcept;
1137template void Device::Set<uint64_t>(uint16_t, uint8_t,
const uint64_t&);
1138template void Device::Set<uint64_t>(uint16_t, uint8_t,
const uint64_t&,
1139 ::std::error_code&)
noexcept;
1145 ::std::error_code ec;
1146 Set(idx, subidx, value, ec);
1152 ::std::error_code& ec)
noexcept {
1153 Set(idx, subidx, value, ::std::char_traits<char>::length(value), ec);
1158 ::std::error_code ec;
1159 Set(idx, subidx, value, ec);
1165 ::std::error_code& ec)
noexcept {
1185 auto val = traits::to_c_type(value, ec);
1187 auto p = traits::address(val);
1188 auto n = traits::size(val);
1198 traits::destroy(val);
1202Device::Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n) {
1203 ::std::error_code ec;
1204 Set(idx, subidx, p, n, ec);
1209Device::Set(uint16_t idx, uint8_t subidx,
const void* p, ::std::size_t n,
1210 ::std::error_code& ec)
noexcept {
1232#if !LELY_NO_CO_OBJ_FILE
1236 ::std::error_code ec;
1238 if (ec)
throw_sdo_error(impl_->id(), idx, subidx, ec,
"GetUploadFile");
1244 ::std::error_code& ec)
const noexcept {
1263 ::std::error_code ec;
1265 if (ec)
throw_sdo_error(impl_->id(), idx, subidx, ec,
"SetUploadFile");
1270 ::std::error_code& ec)
noexcept {
1294 ::std::error_code ec;
1296 if (ec)
throw_sdo_error(impl_->id(), idx, subidx, ec,
"GetDownloadFile");
1302 ::std::error_code& ec)
const noexcept {
1321 ::std::error_code ec;
1323 if (ec)
throw_sdo_error(impl_->id(), idx, subidx, ec,
"SetDownloadFile");
1328 ::std::error_code& ec)
noexcept {
1354 ::std::error_code ec;
1375#if !LELYY_NO_CO_MPDO
1382typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
1384 ::std::error_code ec;
1385 auto value = RpdoGet<T>(
id, idx, subidx, ec);
1391typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
1393 ::std::error_code& ec)
const noexcept {
1395 ::std::tie(idx, subidx) = impl_->RpdoMapping(
id, idx, subidx, ec);
1397 return Get<T>(idx, subidx, ec);
1401typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
1403 ::std::error_code ec;
1404 auto value = TpdoGet<T>(
id, idx, subidx, ec);
1410typename ::std::enable_if<is_canopen_basic<T>::value, T>::type
1412 ::std::error_code& ec)
const noexcept {
1414 ::std::tie(idx, subidx) = impl_->TpdoMapping(
id, idx, subidx, ec);
1416 return Get<T>(idx, subidx, ec);
1420typename ::std::enable_if<is_canopen_basic<T>::value>::type
1422 ::std::error_code ec;
1423 TpdoSet(
id, idx, subidx, value, ec);
1428typename ::std::enable_if<is_canopen_basic<T>::value>::type
1430 ::std::error_code& ec)
noexcept {
1432 ::std::tie(idx, subidx) = impl_->TpdoMapping(
id, idx, subidx, ec);
1433 if (!ec) Set<T>(idx, subidx, value, ec);
1436#ifndef DOXYGEN_SHOULD_SKIP_THIS
1439template bool Device::RpdoGet<bool>(uint8_t, uint16_t, uint8_t)
const;
1440template bool Device::RpdoGet<bool>(uint8_t, uint16_t, uint8_t,
1441 ::std::error_code&)
const noexcept;
1442template bool Device::TpdoGet<bool>(uint8_t, uint16_t, uint8_t)
const;
1443template bool Device::TpdoGet<bool>(uint8_t, uint16_t, uint8_t,
1444 ::std::error_code&)
const noexcept;
1445template void Device::TpdoSet<bool>(uint8_t, uint16_t, uint8_t,
bool);
1446template void Device::TpdoSet<bool>(uint8_t, uint16_t, uint8_t,
bool,
1447 ::std::error_code&)
noexcept;
1450template int8_t Device::RpdoGet<int8_t>(uint8_t, uint16_t, uint8_t)
const;
1451template int8_t Device::RpdoGet<int8_t>(uint8_t, uint16_t, uint8_t,
1452 ::std::error_code&)
const noexcept;
1453template int8_t Device::TpdoGet<int8_t>(uint8_t, uint16_t, uint8_t)
const;
1454template int8_t Device::TpdoGet<int8_t>(uint8_t, uint16_t, uint8_t,
1455 ::std::error_code&)
const noexcept;
1456template void Device::TpdoSet<int8_t>(uint8_t, uint16_t, uint8_t, int8_t);
1457template void Device::TpdoSet<int8_t>(uint8_t, uint16_t, uint8_t, int8_t,
1458 ::std::error_code&)
noexcept;
1461template int16_t Device::RpdoGet<int16_t>(uint8_t, uint16_t, uint8_t)
const;
1462template int16_t Device::RpdoGet<int16_t>(uint8_t, uint16_t, uint8_t,
1463 ::std::error_code&)
const noexcept;
1464template int16_t Device::TpdoGet<int16_t>(uint8_t, uint16_t, uint8_t)
const;
1465template int16_t Device::TpdoGet<int16_t>(uint8_t, uint16_t, uint8_t,
1466 ::std::error_code&)
const noexcept;
1467template void Device::TpdoSet<int16_t>(uint8_t, uint16_t, uint8_t, int16_t);
1468template void Device::TpdoSet<int16_t>(uint8_t, uint16_t, uint8_t, int16_t,
1469 ::std::error_code&)
noexcept;
1472template int32_t Device::RpdoGet<int32_t>(uint8_t, uint16_t, uint8_t)
const;
1473template int32_t Device::RpdoGet<int32_t>(uint8_t, uint16_t, uint8_t,
1474 ::std::error_code&)
const noexcept;
1475template int32_t Device::TpdoGet<int32_t>(uint8_t, uint16_t, uint8_t)
const;
1476template int32_t Device::TpdoGet<int32_t>(uint8_t, uint16_t, uint8_t,
1477 ::std::error_code&)
const noexcept;
1478template void Device::TpdoSet<int32_t>(uint8_t, uint16_t, uint8_t, int32_t);
1479template void Device::TpdoSet<int32_t>(uint8_t, uint16_t, uint8_t, int32_t,
1480 ::std::error_code&)
noexcept;
1483template uint8_t Device::RpdoGet<uint8_t>(uint8_t, uint16_t, uint8_t)
const;
1484template uint8_t Device::RpdoGet<uint8_t>(uint8_t, uint16_t, uint8_t,
1485 ::std::error_code&)
const noexcept;
1486template uint8_t Device::TpdoGet<uint8_t>(uint8_t, uint16_t, uint8_t)
const;
1487template uint8_t Device::TpdoGet<uint8_t>(uint8_t, uint16_t, uint8_t,
1488 ::std::error_code&)
const noexcept;
1489template void Device::TpdoSet<uint8_t>(uint8_t, uint16_t, uint8_t, uint8_t);
1490template void Device::TpdoSet<uint8_t>(uint8_t, uint16_t, uint8_t, uint8_t,
1491 ::std::error_code&)
noexcept;
1494template uint16_t Device::RpdoGet<uint16_t>(uint8_t, uint16_t, uint8_t)
const;
1495template uint16_t Device::RpdoGet<uint16_t>(uint8_t, uint16_t, uint8_t,
1496 ::std::error_code&)
const noexcept;
1497template uint16_t Device::TpdoGet<uint16_t>(uint8_t, uint16_t, uint8_t)
const;
1498template uint16_t Device::TpdoGet<uint16_t>(uint8_t, uint16_t, uint8_t,
1499 ::std::error_code&)
const noexcept;
1500template void Device::TpdoSet<uint16_t>(uint8_t, uint16_t, uint8_t, uint16_t);
1501template void Device::TpdoSet<uint16_t>(uint8_t, uint16_t, uint8_t, uint16_t,
1502 ::std::error_code&)
noexcept;
1505template uint32_t Device::RpdoGet<uint32_t>(uint8_t, uint16_t, uint8_t)
const;
1506template uint32_t Device::RpdoGet<uint32_t>(uint8_t, uint16_t, uint8_t,
1507 ::std::error_code&)
const noexcept;
1508template uint32_t Device::TpdoGet<uint32_t>(uint8_t, uint16_t, uint8_t)
const;
1509template uint32_t Device::TpdoGet<uint32_t>(uint8_t, uint16_t, uint8_t,
1510 ::std::error_code&)
const noexcept;
1511template void Device::TpdoSet<uint32_t>(uint8_t, uint16_t, uint8_t, uint32_t);
1512template void Device::TpdoSet<uint32_t>(uint8_t, uint16_t, uint8_t, uint32_t,
1513 ::std::error_code&)
noexcept;
1516template float Device::RpdoGet<float>(uint8_t, uint16_t, uint8_t)
const;
1517template float Device::RpdoGet<float>(uint8_t, uint16_t, uint8_t,
1518 ::std::error_code&)
const noexcept;
1519template float Device::TpdoGet<float>(uint8_t, uint16_t, uint8_t)
const;
1520template float Device::TpdoGet<float>(uint8_t, uint16_t, uint8_t,
1521 ::std::error_code&)
const noexcept;
1522template void Device::TpdoSet<float>(uint8_t, uint16_t, uint8_t,
float);
1523template void Device::TpdoSet<float>(uint8_t, uint16_t, uint8_t,
float,
1524 ::std::error_code&)
noexcept;
1535template double Device::RpdoGet<double>(uint8_t, uint16_t, uint8_t)
const;
1536template double Device::RpdoGet<double>(uint8_t, uint16_t, uint8_t,
1537 ::std::error_code&)
const noexcept;
1538template double Device::TpdoGet<double>(uint8_t, uint16_t, uint8_t)
const;
1539template double Device::TpdoGet<double>(uint8_t, uint16_t, uint8_t,
1540 ::std::error_code&)
const noexcept;
1541template void Device::TpdoSet<double>(uint8_t, uint16_t, uint8_t,
double);
1542template void Device::TpdoSet<double>(uint8_t, uint16_t, uint8_t,
double,
1543 ::std::error_code&)
noexcept;
1550template int64_t Device::RpdoGet<int64_t>(uint8_t, uint16_t, uint8_t)
const;
1551template int64_t Device::RpdoGet<int64_t>(uint8_t, uint16_t, uint8_t,
1552 ::std::error_code&)
const noexcept;
1553template int64_t Device::TpdoGet<int64_t>(uint8_t, uint16_t, uint8_t)
const;
1554template int64_t Device::TpdoGet<int64_t>(uint8_t, uint16_t, uint8_t,
1555 ::std::error_code&)
const noexcept;
1556template void Device::TpdoSet<int64_t>(uint8_t, uint16_t, uint8_t, int64_t);
1557template void Device::TpdoSet<int64_t>(uint8_t, uint16_t, uint8_t, int64_t,
1558 ::std::error_code&)
noexcept;
1566template uint64_t Device::RpdoGet<uint64_t>(uint8_t, uint16_t, uint8_t)
const;
1567template uint64_t Device::RpdoGet<uint64_t>(uint8_t, uint16_t, uint8_t,
1568 ::std::error_code&)
const noexcept;
1569template uint64_t Device::TpdoGet<uint64_t>(uint8_t, uint16_t, uint8_t)
const;
1570template uint64_t Device::TpdoGet<uint64_t>(uint8_t, uint16_t, uint8_t,
1571 ::std::error_code&)
const noexcept;
1572template void Device::TpdoSet<uint64_t>(uint8_t, uint16_t, uint8_t, uint64_t);
1573template void Device::TpdoSet<uint64_t>(uint8_t, uint16_t, uint8_t, uint64_t,
1574 ::std::error_code&)
noexcept;
1580 ::std::error_code ec;
1587 ::std::error_code& ec)
noexcept {
1589 ::std::tie(idx, subidx) = impl_->TpdoMapping(
id, idx, subidx, ec);
1590 if (!ec) SetEvent(idx, subidx, ec);
1596 impl_->rpdo_mapping.clear();
1600 for (
int i = 0; !obj_1400 && i < 512; i++)
1602 for (; obj_1400; obj_1400 =
co_obj_next(obj_1400)) {
1604 if (i >= 512)
break;
1606 auto cobid = co_obj_get_val_u32(obj_1400, 1);
1612 id = co_obj_get_val_u32(obj_5800, 0) & 0xff;
1616 switch (cobid & 0x780) {
1631 if (!obj_1600)
continue;
1634 if (!obj_5a00)
continue;
1636 auto n = co_obj_get_val_u8(obj_1600, 0);
1638 if (n != co_obj_get_val_u8(obj_5a00, 0))
continue;
1639 for (
int j = 1; j <= n; j++) {
1640 auto rmap = co_obj_get_val_u32(obj_1600, j);
1641 auto tmap = co_obj_get_val_u32(obj_5a00, j);
1643 if (!rmap && !tmap)
continue;
1645 if ((rmap & 0xff) != (tmap & 0xff))
break;
1650 tmap |=
static_cast<uint32_t
>(
id) << 24;
1651 impl_->rpdo_mapping[tmap] = rmap;
1653 impl_->rpdo_mapping[rmap] = tmap;
1659 bool has_sam_mpdo =
false;
1662 for (
int i = 0; !obj_1400 && i <
CO_NUM_PDOS; i++)
1664 for (; !has_sam_mpdo && obj_1400; obj_1400 =
co_obj_next(obj_1400)) {
1670 if (co_obj_get_val_u8(obj_1400, 2) < 0xfe)
continue;
1674 has_sam_mpdo =
true;
1680 for (
int i = 0; !obj_1fd0 && i < 48; i++)
1682 for (; obj_1fd0; obj_1fd0 =
co_obj_next(obj_1fd0)) {
1684 auto n = co_obj_get_val_u8(obj_1fd0, 0);
1688 auto val = co_sub_get_val_u64(sub);
1691 uint32_t rmap = (val << 8) >> 40;
1692 uint32_t tmap =
ror32(val, 8);
1696 uint8_t min = (val >> 8) & 0xff;
1698 uint8_t blk = (val >> 56) & 0xff;
1699 if (blk) max += ::std::min(blk - 1, 0xff - min);
1701 for (
int j = 0; j <= max - min; j++) {
1703 if (
static_cast<uint8_t
>(j) > 0xff - (rmap & 0xff))
break;
1704 impl_->rpdo_mapping[tmap + j] = rmap + j;
1716 impl_->tpdo_mapping.clear();
1720 for (
int i = 0; !obj_1800 && i < 512; i++)
1722 for (; obj_1800; obj_1800 =
co_obj_next(obj_1800)) {
1724 if (i >= 512)
break;
1726 auto cobid = co_obj_get_val_u32(obj_1800, 1);
1732 id = co_obj_get_val_u32(obj_5c00, 0) & 0xff;
1736 switch (cobid & 0x780) {
1751 if (!obj_1a00)
continue;
1754 if (!obj_5e00)
continue;
1756 auto n = co_obj_get_val_u8(obj_1a00, 0);
1758 if (n != co_obj_get_val_u8(obj_5e00, 0))
continue;
1759 for (
int j = 1; j <= n; j++) {
1760 auto tmap = co_obj_get_val_u32(obj_1a00, j);
1761 auto rmap = co_obj_get_val_u32(obj_5e00, j);
1763 if (!rmap && !tmap)
continue;
1765 if ((tmap & 0xff) != (rmap & 0xff))
break;
1768 rmap |=
static_cast<uint32_t
>(
id) << 24;
1769 impl_->tpdo_mapping[rmap] = tmap;
1782 OnRpdoWrite(
id, idx, subidx);
1784 if (impl_->on_rpdo_write) {
1785 auto f = impl_->on_rpdo_write;
1793Device::Impl_::Impl_(
Device* self_, const ::std::string& dcf_txt,
1794 const ::std::string& dcf_bin, uint8_t
id,
1799 if (!dcf_bin.empty() &&
1801 util::throw_errc(
"Device");
1804 util::throw_errc(
"Device");
1819 if (
co_sub_on_dn(sub, req, &ac) == -1 || ac)
return ac;
1820 auto impl_ =
static_cast<Impl_*
>(data);
1825 static_cast<void*
>(
this));
1831Device::Impl_::OnWrite(uint16_t idx, uint8_t subidx) {
1832 self->OnWrite(idx, subidx);
1836 util::UnlockGuard<Impl_>
unlock(*
this);
1842 ::std::error_code ec;
1843 ::std::tie(
id, idx, subidx) = RpdoMapping(idx, subidx, ec);
1844 if (!ec) self->
RpdoWrite(
id, idx, subidx);
This header file is part of the utilities library; it contains the bit function definitions.
uint_least32_t ror32(uint_least32_t x, unsigned int n)
Rotates the 32-bit unsigned integer x right by n bits.
The CANopen device description.
void RpdoWrite(uint8_t id, uint16_t idx, uint8_t subidx)
Invokes OnRpdoWrite() as if a value was written to an RPDO-mapped object in the local object dictiona...
uint8_t netid() const noexcept
Returns the network-ID.
void SetUploadFile(uint16_t idx, uint8_t subidx, const char *filename)
Sets the value of the UploadFile attribute of a sub-object, if present.
typename::std::enable_if< is_canopen_basic< T >::value, T >::type RpdoGet(uint8_t id, uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object in a remote object dictionary by reading the corresponding PDO-mapped...
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...
void WriteDcf(const uint8_t *begin, const uint8_t *end)
Submits a series of SDO download requests to the local object dictionary.
void UpdateTpdoMapping()
Updates the mapping from remote RPDO-mapped sub-objects to local TPDO-mapped sub-objects.
typename::std::enable_if< is_canopen_basic< T >::value, T >::type TpdoGet(uint8_t id, uint16_t idx, uint8_t subidx) const
Reads the value of a TPDO-mapped sub-object in the local object dictionary that will be written to an...
typename::std::enable_if< is_canopen< T >::value, T >::type Read(uint16_t idx, uint8_t subidx) const
Submits an SDO upload request to the local object dictionary.
void SetDownloadFile(uint16_t idx, uint8_t subidx, const char *filename)
Sets the value of the DownloadFile attribute of a sub-object, if present.
typename::std::enable_if< 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...
const ::std::type_info & Type(uint16_t idx, uint8_t subidx) const
Returns the type of a sub-object.
typename::std::enable_if< is_canopen< T >::value >::type Set(uint16_t idx, uint8_t subidx, const T &value)
Writes a CANopen value to a sub-object.
void UpdateRpdoMapping()
Updates the mapping from remote TPDO-mapped sub-objects to local RPDO-mapped sub-objects.
typename::std::enable_if< is_canopen< T >::value, T >::type Get(uint16_t idx, uint8_t subidx) const
Reads the value of a sub-object.
void SetEvent(uint16_t idx, uint8_t subidx)
Checks if the specified sub-object in the local object dictionary can be mapped into a PDO and,...
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,...
typename::std::enable_if< is_canopen_basic< T >::value >::type TpdoSet(uint8_t id, uint16_t idx, uint8_t subidx, T value)
Writes a value to a sub-object in a remote object dictionary by writing to the corresponding PDO-mapp...
Device(const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff, util::BasicLockable *mutex=nullptr)
Creates a new CANopen device description.
typename::std::enable_if< is_canopen< T >::value >::type Write(uint16_t idx, uint8_t subidx, const T &value)
Submits an SDO download request to the local object dictionary.
const char * GetDownloadFile(uint16_t idx, uint8_t subidx) const
Returns the value of the DownloadFile attribute of a sub-object, if present.
typename::std::enable_if< 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< 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 ...
void TpdoSetEvent(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...
__co_dev * dev() const noexcept
Returns a pointer to the internal CANopen device from <lely/co/dev.hpp>.
uint8_t id() const noexcept
Returns the node-ID.
const char * GetUploadFile(uint16_t idx, uint8_t subidx) const
Returns the value of the UploadFile attribute of a sub-object, if present.
An abstract interface conforming to the BasicLockable concept.
A mutex wrapper that provides a convenient RAII-style mechanism for releasing a mutex for the duratio...
This header file is part of the CANopen library; it contains the device description declarations.
void co_dev_sam_mpdo_event(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified sub-object in the object dictionary of a CANopen device can be mapped into a ...
co_obj_t * co_dev_find_obj(const co_dev_t *dev, co_unsigned16_t idx)
Finds an object in the object dictionary of a CANopen device.
co_unsigned8_t co_dev_get_id(const co_dev_t *dev)
Returns the node-ID of a CANopen device.
int co_dev_set_id(co_dev_t *dev, co_unsigned8_t id)
Sets the node-ID of a CANopen device.
#define CO_NUM_NODES
The maximum number of nodes in a CANopen network.
co_unsigned8_t co_dev_get_netid(const co_dev_t *dev)
Returns the network-ID of a CANopen device.
void co_dev_destroy(co_dev_t *dev)
Destroys a CANopen device, including all objects in its object dictionary.
void co_dev_tpdo_event(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx)
Checks if the specified sub-object in the object dictionary of a CANopen device can be mapped into a ...
co_obj_t * co_dev_first_obj(const co_dev_t *dev)
Finds the first object (with the lowest index) in the object dictionary of a CANopen device.
int co_dev_read_dcf_file(co_dev_t *dev, co_unsigned16_t *pmin, co_unsigned16_t *pmax, const char *filename)
Reads the values of a range of objects from a file, in the concise DCF format, and stores them in the...
This is the internal header file of the C++ CANopen application library.
This header file is part of the CANopen library; it contains the Client-SDO declarations.
int co_dev_up_req(const co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, co_csdo_up_con_t *con, void *data)
Submits an upload request to a local device.
int co_dev_dn_val_req(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned16_t type, const void *val, co_csdo_dn_con_t *con, void *data)
Submits a download request to a local device.
int co_dev_dn_req(co_dev_t *dev, co_unsigned16_t idx, co_unsigned8_t subidx, const void *ptr, size_t n, co_csdo_dn_con_t *con, void *data)
Submits a download request to a local device.
int co_dev_dn_dcf_req(co_dev_t *dev, const uint_least8_t *begin, const uint_least8_t *end, co_csdo_dn_con_t *con, void *data)
Submits a series of download requests to a local device.
This header file is part of the CANopen library; it contains the Electronic Data Sheet (EDS) and Devi...
co_dev_t * co_dev_create_from_dcf_file(const char *filename)
Creates a CANopen device from an EDS or DCF file.
This header file is part of the C++ CANopen application library; it contains the CANopen device descr...
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
This header file is part of the utilities library; it contains C++ convenience functions for creating...
constexpr bool is_canopen_same(uint16_t t1, uint16_t t2) noexcept
Returns true if the CANopen data types t1 and t2 map to the same C++ type, and false if not.
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.
@ NO_PDO
Object cannot be mapped to the PDO.
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
void throw_sdo_error(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec)
Throws a lely::canopen::SdoError with the specified attributes if ec is an SDO error (ec....
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
This header file is part of the CANopen library; it contains the object dictionary declarations.
co_sub_t * co_obj_first_sub(const co_obj_t *obj)
Finds the first sub-object (with the lowest sub-index) in a CANopen object.
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
int co_sub_set_download_file(co_sub_t *sub, const char *filename)
Sets the value of the DownloadFile attribute of a CANopen sub-object.
co_unsigned16_t co_obj_get_idx(const co_obj_t *obj)
Returns the index of a CANopen object.
const void * co_sub_get_val(const co_sub_t *sub)
Returns a pointer to the current value of a CANopen sub-object.
const char * co_sub_get_download_file(const co_sub_t *sub)
Returns a pointer to the value of the DownloadFile attribute of a CANopen sub-object,...
int co_sub_set_upload_file(co_sub_t *sub, const char *filename)
Sets the value of the UploadFile attribute of a CANopen sub-object.
co_sub_t * co_obj_find_sub(const co_obj_t *obj, co_unsigned8_t subidx)
Finds a sub-object in a CANopen object.
size_t co_sub_set_val(co_sub_t *sub, const void *ptr, size_t n)
Sets the current value of a CANopen sub-object.
const char * co_sub_get_upload_file(const co_sub_t *sub)
Returns a pointer to the value of the UploadFile attribute of a CANopen sub-object,...
co_obj_t * co_obj_next(const co_obj_t *obj)
Finds the next object in the object dictionary of a CANopen device.
int co_sub_on_dn(co_sub_t *sub, struct co_sdo_req *req, co_unsigned32_t *pac)
Implements the default behavior when a download indication is received by a CANopen sub-object.
void co_obj_set_dn_ind(co_obj_t *obj, co_sub_dn_ind_t *ind, void *data)
Sets the download indication function for a CANopen object.
co_sub_t * co_sub_next(const co_sub_t *sub)
Finds the next sub-object in a CANopen object.
co_obj_t * co_sub_get_obj(const co_sub_t *sub)
Returns the a pointer to the CANopen object containing the specified sub-object.
co_unsigned16_t co_sub_get_type(const co_sub_t *sub)
Returns the data type of a CANopen sub-object.
This header file is part of the CANopen library; it contains the Process Data Object (PDO) declaratio...
#define CO_PDO_NUM_MAPS
The maximum number of mapped application objects in a single PDO.
#define CO_PDO_COBID_FRAME
The bit in the PDO COB-ID specifying whether to use an 11-bit (0) or 29-bit (1) CAN-ID.
#define CO_PDO_COBID_VALID
The bit in the PDO COB-ID specifying whether the PDO exists and is valid.
#define CO_NUM_PDOS
The maximum number of Receive/Transmit-PDOs.
#define CO_PDO_MAP_SAM_MPDO
The value of sub-index 0 of the PDO mapping parameter record indicating a a source address mode multi...
A CANopen SDO upload/download request.
The internal implementation of the CANopen device description.
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 class template mapping CANopen types to C and 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.
int co_type_is_basic(co_unsigned16_t type)
Returns 1 if the specified (static) data type is a basic type, and 0 if not.
#define CO_DEFTYPE_REAL32
The data type (and object index) of a 32-bit IEEE-754 floating-point number.
This header file is part of the CANopen library; it contains the CANopen value declarations.
const void * co_val_addressof(co_unsigned16_t type, const void *val)
Returns the address of the first byte in a value of the specified data type.
size_t co_val_sizeof(co_unsigned16_t type, const void *val)
Returns the size (in bytes) of a value of the specified data type.
size_t co_val_read_file(co_unsigned16_t type, void *val, const char *filename)
Reads a value of the specified data type from a file.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.