26 #if !LELY_NO_COAPP_SLAVE 47 netid()
const noexcept {
48 return self->dev()->getNetid();
52 return self->dev()->getId();
55 void OnLgInd(
CONMT*
nmt,
int state) noexcept;
63 static constexpr uint32_t Key(uint16_t idx, uint8_t subidx) noexcept;
64 static uint32_t Key(
const COSub* sub) noexcept;
68 ::std::map<uint32_t, ::std::function<uint32_t(COSub*, void*)>> dn_ind;
69 ::std::map<uint32_t, ::std::function<uint32_t(const COSub*, void*)>> up_ind;
73 const ::std::string& dcf_txt,
74 const ::std::string& dcf_bin, uint8_t
id)
75 :
Node(timer, bus, dcf_txt, dcf_bin, id),
78 BasicSlave::~BasicSlave() =
default;
81 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
83 ::std::function<OnReadSignature<T>> ind) {
85 OnRead<T>(idx, subidx, ::std::move(ind), ec);
86 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec);
91 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
92 typename ::std::enable_if<detail::IsCanopenBasic<T>::value,
93 ::std::error_code>::type
98 return ind(sub->getObj()->getIdx(), sub->getSubidx(), val);
104 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
105 typename ::std::enable_if<detail::IsCanopenArray<T>::value,
106 ::std::error_code>::type
107 OnUpInd(
const COSub* sub, COVal<N>& val,
const F& ind) {
112 auto ec = ind(sub->getObj()->getIdx(), sub->getSubidx(), value);
113 if (!ec) val = ::std::move(value);
123 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
125 ::std::function<OnReadSignature<T>> ind,
126 ::std::error_code& ec) {
127 constexpr
auto N = co_type_traits_T<T>::index;
129 auto obj =
dev()->find(idx);
135 auto sub = obj->find(subidx);
146 auto key = Impl_::Key(sub);
148 impl_->up_ind[key] = [=](
const COSub* sub,
void* p) -> uint32_t {
149 auto ec = OnUpInd<T>(sub, *
static_cast<COVal<N>*
>(p), ind);
152 sub->setUpInd<N, Impl_, &Impl_::OnUpInd>(impl_.get());
154 if (impl_->up_ind.erase(key)) sub->setUpInd(
nullptr,
nullptr);
159 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
161 ::std::function<OnWriteSignature<T>> ind) {
162 ::std::error_code ec;
163 OnWrite<T>(idx, subidx, ::std::move(ind), ec);
164 if (ec)
throw SdoError(impl_->netid(), impl_->id(), idx, subidx, ec);
169 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
170 typename ::std::enable_if<detail::IsCanopenBasic<T>::value,
171 ::std::error_code>::type
172 OnDnInd(COSub* sub, COVal<N>& val,
const F& ind) {
176 return ind(sub->getObj()->getIdx(), sub->getSubidx(), val,
183 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
184 typename ::std::enable_if<detail::IsCanopenArray<T>::value,
185 ::std::error_code>::type
186 OnDnInd(COSub* sub, COVal<N>& val,
const F& ind) {
191 auto ec = ind(sub->getObj()->getIdx(), sub->getSubidx(), value);
192 if (!ec) val = ::std::move(value);
202 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
204 ::std::function<OnWriteSignature<T>> ind,
205 ::std::error_code& ec) {
206 constexpr
auto N = co_type_traits_T<T>::index;
208 auto obj =
dev()->find(idx);
214 auto sub = obj->find(subidx);
225 auto key = Impl_::Key(sub);
227 impl_->dn_ind[key] = [=](COSub* sub,
void* p) -> uint32_t {
228 auto ec = OnDnInd<T>(sub, *
static_cast<COVal<N>*
>(p), ind);
231 sub->setDnInd<N, Impl_, &Impl_::OnDnInd>(impl_.get());
233 if (impl_->dn_ind.erase(key)) sub->setDnInd(
nullptr,
nullptr);
237 #ifndef DOXYGEN_SHOULD_SKIP_THIS 240 template void BasicSlave::OnRead<bool>(uint16_t, uint8_t,
241 ::std::function<OnReadSignature<bool>>);
242 template void BasicSlave::OnRead<bool>(uint16_t, uint8_t,
243 ::std::function<OnReadSignature<bool>>,
245 template void BasicSlave::OnWrite<bool>(
246 uint16_t, uint8_t, ::std::function<OnWriteSignature<bool>>);
247 template void BasicSlave::OnWrite<bool>(uint16_t, uint8_t,
248 ::std::function<OnWriteSignature<bool>>,
252 template void BasicSlave::OnRead<int8_t>(
253 uint16_t, uint8_t, ::std::function<OnReadSignature<int8_t>>);
254 template void BasicSlave::OnRead<int8_t>(
255 uint16_t, uint8_t, ::std::function<OnReadSignature<int8_t>>,
257 template void BasicSlave::OnWrite<int8_t>(
258 uint16_t, uint8_t, ::std::function<OnWriteSignature<int8_t>>);
259 template void BasicSlave::OnWrite<int8_t>(
260 uint16_t, uint8_t, ::std::function<OnWriteSignature<int8_t>>,
264 template void BasicSlave::OnRead<int16_t>(
265 uint16_t, uint8_t, ::std::function<OnReadSignature<int16_t>>);
266 template void BasicSlave::OnRead<int16_t>(
267 uint16_t, uint8_t, ::std::function<OnReadSignature<int16_t>>,
269 template void BasicSlave::OnWrite<int16_t>(
270 uint16_t, uint8_t, ::std::function<OnWriteSignature<int16_t>>);
271 template void BasicSlave::OnWrite<int16_t>(
272 uint16_t, uint8_t, ::std::function<OnWriteSignature<int16_t>>,
276 template void BasicSlave::OnRead<int32_t>(
277 uint16_t, uint8_t, ::std::function<OnReadSignature<int32_t>>);
278 template void BasicSlave::OnRead<int32_t>(
279 uint16_t, uint8_t, ::std::function<OnReadSignature<int32_t>>,
281 template void BasicSlave::OnWrite<int32_t>(
282 uint16_t, uint8_t, ::std::function<OnWriteSignature<int32_t>>);
283 template void BasicSlave::OnWrite<int32_t>(
284 uint16_t, uint8_t, ::std::function<OnWriteSignature<int32_t>>,
288 template void BasicSlave::OnRead<uint8_t>(
289 uint16_t, uint8_t, ::std::function<OnReadSignature<uint8_t>>);
290 template void BasicSlave::OnRead<uint8_t>(
291 uint16_t, uint8_t, ::std::function<OnReadSignature<uint8_t>>,
293 template void BasicSlave::OnWrite<uint8_t>(
294 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint8_t>>);
295 template void BasicSlave::OnWrite<uint8_t>(
296 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint8_t>>,
300 template void BasicSlave::OnRead<uint16_t>(
301 uint16_t, uint8_t, ::std::function<OnReadSignature<uint16_t>>);
302 template void BasicSlave::OnRead<uint16_t>(
303 uint16_t, uint8_t, ::std::function<OnReadSignature<uint16_t>>,
305 template void BasicSlave::OnWrite<uint16_t>(
306 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint16_t>>);
307 template void BasicSlave::OnWrite<uint16_t>(
308 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint16_t>>,
312 template void BasicSlave::OnRead<uint32_t>(
313 uint16_t, uint8_t, ::std::function<OnReadSignature<uint32_t>>);
314 template void BasicSlave::OnRead<uint32_t>(
315 uint16_t, uint8_t, ::std::function<OnReadSignature<uint32_t>>,
317 template void BasicSlave::OnWrite<uint32_t>(
318 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint32_t>>);
319 template void BasicSlave::OnWrite<uint32_t>(
320 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint32_t>>,
324 template void BasicSlave::OnRead<float>(
325 uint16_t, uint8_t, ::std::function<OnReadSignature<float>>);
326 template void BasicSlave::OnRead<float>(uint16_t, uint8_t,
327 ::std::function<OnReadSignature<float>>,
329 template void BasicSlave::OnWrite<float>(
330 uint16_t, uint8_t, ::std::function<OnWriteSignature<float>>);
331 template void BasicSlave::OnWrite<float>(
332 uint16_t, uint8_t, ::std::function<OnWriteSignature<float>>,
336 template void BasicSlave::OnRead<::std::string>(
337 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::string>>);
338 template void BasicSlave::OnRead<::std::string>(
339 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::string>>,
341 template void BasicSlave::OnWrite<::std::string>(
342 uint16_t, uint8_t, ::std::function<OnWriteSignature<::std::string>>);
343 template void BasicSlave::OnWrite<::std::string>(
344 uint16_t, uint8_t, ::std::function<OnWriteSignature<::std::string>>,
348 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
350 ::std::function<OnReadSignature<::std::vector<uint8_t>>>);
351 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
352 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>,
354 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
356 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>);
357 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
359 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>,
363 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
365 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>);
366 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
368 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>,
370 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
372 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>);
373 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
375 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>,
384 template void BasicSlave::OnRead<double>(
385 uint16_t, uint8_t, ::std::function<OnReadSignature<double>>);
386 template void BasicSlave::OnRead<double>(
387 uint16_t, uint8_t, ::std::function<OnReadSignature<double>>,
389 template void BasicSlave::OnWrite<double>(
390 uint16_t, uint8_t, ::std::function<OnWriteSignature<double>>);
391 template void BasicSlave::OnWrite<double>(
392 uint16_t, uint8_t, ::std::function<OnWriteSignature<double>>,
400 template void BasicSlave::OnRead<int64_t>(
401 uint16_t, uint8_t, ::std::function<OnReadSignature<int64_t>>);
402 template void BasicSlave::OnRead<int64_t>(
403 uint16_t, uint8_t, ::std::function<OnReadSignature<int64_t>>,
405 template void BasicSlave::OnWrite<int64_t>(
406 uint16_t, uint8_t, ::std::function<OnWriteSignature<int64_t>>);
407 template void BasicSlave::OnWrite<int64_t>(
408 uint16_t, uint8_t, ::std::function<OnWriteSignature<int64_t>>,
417 template void BasicSlave::OnRead<uint64_t>(
418 uint16_t, uint8_t, ::std::function<OnReadSignature<uint64_t>>);
419 template void BasicSlave::OnRead<uint64_t>(
420 uint16_t, uint8_t, ::std::function<OnReadSignature<uint64_t>>,
422 template void BasicSlave::OnWrite<uint64_t>(
423 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint64_t>>);
424 template void BasicSlave::OnWrite<uint64_t>(
425 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint64_t>>,
428 #endif // DOXYGEN_SHOULD_SKIP_THIS 430 BasicSlave::Impl_::Impl_(BasicSlave* self_, CONMT* nmt) : self(self_) {
431 nmt->setLgInd<Impl_, &Impl_::OnLgInd>(
this);
435 BasicSlave::Impl_::OnLgInd(CONMT* nmt,
int state) noexcept {
442 template <u
int16_t N>
444 BasicSlave::Impl_::OnDnInd(COSub* sub, COVal<N>& val) noexcept {
445 auto it = dn_ind.find(Key(sub));
446 if (it == dn_ind.end())
return 0;
447 return it->second(sub, static_cast<void*>(&val));
450 template <u
int16_t N>
452 BasicSlave::Impl_::OnUpInd(
const COSub* sub, COVal<N>& val) noexcept {
453 auto it = up_ind.find(Key(sub));
454 if (it == up_ind.end())
return 0;
455 return it->second(sub, static_cast<void*>(&val));
459 BasicSlave::Impl_::Key(uint16_t idx, uint8_t subidx) noexcept {
460 return (uint32_t(idx) << 8) | subidx;
464 BasicSlave::Impl_::Key(
const COSub* sub) noexcept {
467 return Key(sub->getObj()->getIdx(), sub->getSubidx());
474 #endif // !LELY_NO_COAPP_SLAVE BasicSlave(aio::TimerBase &timer, aio::CanBusBase &bus, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen slave.
An NMT error control event occurred.
CONMT * nmt() const noexcept
Returns a pointer to the internal CANopen NMT master/slave service from <lely/co/nmt.hpp>.
This header file is part of the C++ CANopen application library; it contains the CANopen slave declar...
This header file is part of the CANopen library; it contains the C++ interface of the network managem...
This header file is part of the CANopen library; it contains the C++ interface of the device descript...
Sub-index does not exist.
An opaque CANopen sub-object type.
This header file is part of the CANopen library; it contains the C++ interface of the object dictiona...
The base class for CANopen slaves.
Data type does not match, length of service parameter does not match.
typename ::std::enable_if< detail::IsCanopenType< T >::value >::type OnWrite(uint16_t idx, uint8_t subidx, ::std::function< OnWriteSignature< T >> ind)
Registers a callback function to be invoked on write (SDO download) access to the specified CANopen s...
This is the internal header file of the C++ CANopen application library.
Object does not exist in the object dictionary.
The internal implementation of the CANopen slave.
typename ::std::enable_if< detail::IsCanopenType< T >::value >::type OnRead(uint16_t idx, uint8_t subidx, ::std::function< OnReadSignature< T >> ind)
Registers a callback function to be invoked on read (SDO upload) access to the specified CANopen sub-...
An opaque CANopen NMT master/slave service type.
CODev * dev() const noexcept
Returns a pointer to the internal CANopen device from <lely/co/dev.hpp>.
Global namespace for the Lely Industries N.V. libraries.
The base class for CANopen nodes.
The type of exception thrown when an SDO abort code is received.
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...