Lely core libraries 2.3.4
sdo.cpp
Go to the documentation of this file.
1
24#include "coapp.hpp"
25
26#if !LELY_NO_CO_CSDO
27#include <lely/co/csdo.h>
28#endif
29#include <lely/co/val.h>
30#include <lely/coapp/sdo.hpp>
31
32#include <limits>
33#include <memory>
34#include <string>
35#include <utility>
36#include <vector>
37
38#include <cassert>
39
40namespace lely {
41
42namespace canopen {
43
45struct Sdo::Impl_ {
46 Impl_(__can_net* net, __co_dev* dev, uint8_t num);
47 Impl_(__co_csdo* sdo, int timeout);
48 Impl_(const Impl_&) = delete;
49 Impl_& operator=(const Impl_&) = delete;
50 ~Impl_();
51
52 void Submit(detail::SdoRequestBase& req);
53 ::std::size_t Cancel(detail::SdoRequestBase* req, SdoErrc ac);
54 ::std::size_t Abort(detail::SdoRequestBase* req);
55
56#if !LELY_NO_CO_CSDO
57 bool Pop(detail::SdoRequestBase* req, sllist& queue);
58
59 template <class T>
60 void OnDownload(detail::SdoDownloadRequestBase<T>& req) noexcept;
61 void OnDownloadDcf(detail::SdoDownloadDcfRequestBase& req) noexcept;
62 template <class T>
63 void OnUpload(detail::SdoUploadRequestBase<T>& req) noexcept;
64
65 void OnDnCon(__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac) noexcept;
66 template <class T>
67 void OnUpCon(__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac,
68 const void* ptr, size_t n) noexcept;
69
70 void OnCompletion(detail::SdoRequestBase& req) noexcept;
71
72 ::std::shared_ptr<__co_csdo> sdo;
73
74 sllist queue;
75#endif
76};
77
78namespace detail {
79
80#if !LELY_NO_STDIO
81void
83 begin = nullptr;
84 end = nullptr;
85 if (dom_) {
87 dom_ = nullptr;
88 }
89
90 if (!co_val_read_file(CO_DEFTYPE_DOMAIN, &dom_, path))
91 util::throw_errc("ReadFile");
92
93 begin =
94 static_cast<const uint8_t*>(co_val_addressof(CO_DEFTYPE_DOMAIN, &dom_));
96}
97#endif
98
99SdoDownloadDcfRequestBase::~SdoDownloadDcfRequestBase() {
100 if (dom_) co_val_fini(CO_DEFTYPE_DOMAIN, &dom_);
101}
102
103template <class T>
104void
105SdoDownloadRequestWrapper<T>::operator()() noexcept {
106 auto id = this->id;
107 auto idx = this->idx;
108 auto subidx = this->subidx;
109 auto ec = this->ec;
110 ::std::function<Signature> con;
111 con.swap(this->con_);
112 delete this;
113 if (con) con(id, idx, subidx, ec);
114}
115
116template <class T>
117void
118SdoDownloadRequestWrapper<T>::OnRequest(void* data) noexcept {
119#if LELY_NO_CO_CSDO
120 (void)data;
121#else
122 static_cast<Sdo::Impl_*>(data)->OnDownload(*this);
123#endif
124}
125
126void
127SdoDownloadDcfRequestWrapper::operator()() noexcept {
128 auto id = this->id;
129 auto idx = this->idx;
130 auto subidx = this->subidx;
131 auto ec = this->ec;
132 ::std::function<Signature> con;
133 con.swap(this->con_);
134 delete this;
135 if (con) con(id, idx, subidx, ec);
136}
137
138void
139SdoDownloadDcfRequestWrapper::OnRequest(void* data) noexcept {
140#if LELY_NO_CO_CSDO
141 (void)data;
142#else
143 static_cast<Sdo::Impl_*>(data)->OnDownloadDcf(*this);
144#endif
145}
146
147template <class T>
148void
149SdoUploadRequestWrapper<T>::operator()() noexcept {
150 auto id = this->id;
151 auto idx = this->idx;
152 auto subidx = this->subidx;
153 auto ec = this->ec;
154 T value = ::std::move(this->value);
155 ::std::function<Signature> con;
156 con.swap(this->con_);
157 delete this;
158 if (con) con(id, idx, subidx, ec, ::std::move(value));
159}
160
161template <class T>
162void
163SdoUploadRequestWrapper<T>::OnRequest(void* data) noexcept {
164#if LELY_NO_CO_CSDO
165 (void)data;
166#else
167 static_cast<Sdo::Impl_*>(data)->OnUpload(*this);
168#endif
169}
170
171#ifndef DOXYGEN_SHOULD_SKIP_THIS
172
173// BOOLEAN
174template class SdoDownloadRequestWrapper<bool>;
175template class SdoUploadRequestWrapper<bool>;
176
177// INTEGER8
178template class SdoDownloadRequestWrapper<int8_t>;
179template class SdoUploadRequestWrapper<int8_t>;
180
181// INTEGER16
182template class SdoDownloadRequestWrapper<int16_t>;
183template class SdoUploadRequestWrapper<int16_t>;
184
185// INTEGER32
186template class SdoDownloadRequestWrapper<int32_t>;
187template class SdoUploadRequestWrapper<int32_t>;
188
189// UNSIGNED8
190template class SdoDownloadRequestWrapper<uint8_t>;
191template class SdoUploadRequestWrapper<uint8_t>;
192
193// UNSIGNED16
194template class SdoDownloadRequestWrapper<uint16_t>;
195template class SdoUploadRequestWrapper<uint16_t>;
196
197// UNSIGNED32
198template class SdoDownloadRequestWrapper<uint32_t>;
199template class SdoUploadRequestWrapper<uint32_t>;
200
201// REAL32
202template class SdoDownloadRequestWrapper<float>;
203template class SdoUploadRequestWrapper<float>;
204
205// VISIBLE_STRING
206template class SdoDownloadRequestWrapper<::std::string>;
207template class SdoUploadRequestWrapper<::std::string>;
208
209// OCTET_STRING
210template class SdoDownloadRequestWrapper<::std::vector<uint8_t>>;
211template class SdoUploadRequestWrapper<::std::vector<uint8_t>>;
212
213// UNICODE_STRING
214template class SdoDownloadRequestWrapper<::std::basic_string<char16_t>>;
215template class SdoUploadRequestWrapper<::std::basic_string<char16_t>>;
216
217// TIME_OF_DAY
218// TIME_DIFFERENCE
219// DOMAIN
220// INTEGER24
221
222// REAL64
223template class SdoDownloadRequestWrapper<double>;
224template class SdoUploadRequestWrapper<double>;
225
226// INTEGER40
227// INTEGER48
228// INTEGER56
229
230// INTEGER64
231template class SdoDownloadRequestWrapper<int64_t>;
232template class SdoUploadRequestWrapper<int64_t>;
233
234// UNSIGNED24
235// UNSIGNED40
236// UNSIGNED48
237// UNSIGNED56
238
239// UNSIGNED64
240template class SdoDownloadRequestWrapper<uint64_t>;
241template class SdoUploadRequestWrapper<uint64_t>;
242
243#endif // !DOXYGEN_SHOULD_SKIP_THIS
244
245} // namespace detail
246
247template <class T>
248void
249SdoDownloadRequest<T>::operator()() noexcept {
250 if (con_) con_(this->id, this->idx, this->subidx, this->ec);
251}
252
253template <class T>
254void
255SdoDownloadRequest<T>::OnRequest(void* data) noexcept {
256#if LELY_NO_CO_CSDO
257 (void)data;
258#else
259 static_cast<Sdo::Impl_*>(data)->OnDownload(*this);
260#endif
261}
262
263void
264SdoDownloadDcfRequest::operator()() noexcept {
265 if (con_) con_(this->id, this->idx, this->subidx, this->ec);
266}
267
268void
269SdoDownloadDcfRequest::OnRequest(void* data) noexcept {
270#if LELY_NO_CO_CSDO
271 (void)data;
272#else
273 static_cast<Sdo::Impl_*>(data)->OnDownloadDcf(*this);
274#endif
275}
276
277template <class T>
278void
279SdoUploadRequest<T>::operator()() noexcept {
280 if (con_)
281 con_(this->id, this->idx, this->subidx, this->ec, ::std::move(this->value));
282}
283
284template <class T>
285void
286SdoUploadRequest<T>::OnRequest(void* data) noexcept {
287#if LELY_NO_CO_CSDO
288 (void)data;
289#else
290 static_cast<Sdo::Impl_*>(data)->OnUpload(*this);
291#endif
292}
293
294#ifndef DOXYGEN_SHOULD_SKIP_THIS
295
296// BOOLEAN
297template class SdoDownloadRequest<bool>;
298template class SdoUploadRequest<bool>;
299
300// INTEGER8
301template class SdoDownloadRequest<int8_t>;
302template class SdoUploadRequest<int8_t>;
303
304// INTEGER16
305template class SdoDownloadRequest<int16_t>;
306template class SdoUploadRequest<int16_t>;
307
308// INTEGER32
309template class SdoDownloadRequest<int32_t>;
310template class SdoUploadRequest<int32_t>;
311
312// UNSIGNED8
313template class SdoDownloadRequest<uint8_t>;
314template class SdoUploadRequest<uint8_t>;
315
316// UNSIGNED16
317template class SdoDownloadRequest<uint16_t>;
318template class SdoUploadRequest<uint16_t>;
319
320// UNSIGNED32
321template class SdoDownloadRequest<uint32_t>;
322template class SdoUploadRequest<uint32_t>;
323
324// REAL32
325template class SdoDownloadRequest<float>;
326template class SdoUploadRequest<float>;
327
328// VISIBLE_STRING
329template class SdoDownloadRequest<::std::string>;
330template class SdoUploadRequest<::std::string>;
331
332// OCTET_STRING
333template class SdoDownloadRequest<::std::vector<uint8_t>>;
334template class SdoUploadRequest<::std::vector<uint8_t>>;
335
336// UNICODE_STRING
337template class SdoDownloadRequest<::std::basic_string<char16_t>>;
338template class SdoUploadRequest<::std::basic_string<char16_t>>;
339
340// TIME_OF_DAY
341// TIME_DIFFERENCE
342// DOMAIN
343// INTEGER24
344
345// REAL64
346template class SdoDownloadRequest<double>;
347template class SdoUploadRequest<double>;
348
349// INTEGER40
350// INTEGER48
351// INTEGER56
352
353// INTEGER64
354template class SdoDownloadRequest<int64_t>;
355template class SdoUploadRequest<int64_t>;
356
357// UNSIGNED24
358// UNSIGNED40
359// UNSIGNED48
360// UNSIGNED56
361
362// UNSIGNED64
363template class SdoDownloadRequest<uint64_t>;
364template class SdoUploadRequest<uint64_t>;
365
366#endif // !DOXYGEN_SHOULD_SKIP_THIS
367
368Sdo::Sdo() = default;
369
370Sdo::Sdo(__can_net* net, uint8_t id) : Sdo(net, nullptr, id) {}
371
372Sdo::Sdo(__can_net* net, __co_dev* dev, uint8_t num)
373 : impl_(new Impl_(net, dev, num)) {}
374
376#if LELY_NO_CO_CSDO
377 : impl_(new Impl_(sdo, 0))
378#else
379 : impl_(new Impl_(sdo, co_csdo_get_timeout(sdo)))
380#endif
381{
382}
383
384Sdo& Sdo::operator=(Sdo&&) = default;
385
386Sdo::~Sdo() = default;
387
389Sdo::AsyncDownloadDcf(ev_exec_t* exec, const uint8_t* begin, const uint8_t* end,
390 const ::std::chrono::milliseconds& timeout) {
393 exec, begin, end,
394 [p](uint8_t id, uint16_t idx, uint8_t subidx,
395 ::std::error_code ec) mutable {
396 if (ec)
397 p.set(util::failure(
398 make_sdo_exception_ptr(id, idx, subidx, ec, "AsyncDownloadDcf")));
399 else
400 p.set(util::success());
401 },
402 timeout);
403 return p.get_future();
404}
405
407Sdo::AsyncDownloadDcf(ev_exec_t* exec, const char* path,
408 const ::std::chrono::milliseconds& timeout) {
411 exec, path,
412 [p](uint8_t id, uint16_t idx, uint8_t subidx,
413 ::std::error_code ec) mutable {
414 if (ec)
415 p.set(util::failure(
416 make_sdo_exception_ptr(id, idx, subidx, ec, "AsyncDownloadDcf")));
417 else
418 p.set(util::success());
419 },
420 timeout);
421 return p.get_future();
422}
423
424void
426 impl_->Submit(req);
427}
428
429bool
431 return impl_->Cancel(&req, ac) != 0;
432}
433
434::std::size_t
436 return impl_->Cancel(nullptr, ac);
437}
438
439bool
441 return impl_->Abort(&req) != 0;
442}
443
444::std::size_t
446 return impl_->Abort(nullptr);
447}
448
449Sdo::Impl_::Impl_(__can_net* net, __co_dev* dev, uint8_t num)
450#if LELY_NO_CO_CSDO
451{
452 (void)net;
453 (void)dev;
454 (void)num;
455#else
456 : sdo(co_csdo_create(net, dev, num),
457 [=](__co_csdo* sdo) noexcept { co_csdo_destroy(sdo); }) {
458 sllist_init(&queue);
459#endif
460}
461
462Sdo::Impl_::Impl_(__co_csdo* sdo_, int timeout)
463#if LELY_NO_CO_CSDO
464{
465 (void)sdo_;
466 (void)timeout;
467#else
468 : sdo(sdo_,
469 [=](__co_csdo* sdo) noexcept { co_csdo_set_timeout(sdo, timeout); }) {
470 sllist_init(&queue);
471#endif
472}
473
474Sdo::Impl_::~Impl_() { Cancel(nullptr, SdoErrc::NO_SDO); }
475
476void
477Sdo::Impl_::Submit(detail::SdoRequestBase& req) {
478 assert(req.exec);
479 ev::Executor exec(req.exec);
480
481#if !LELY_NO_CO_CSDO
482 exec.on_task_init();
483 if (!sdo) {
484#endif
485 req.id = 0;
486 req.ec = SdoErrc::NO_SDO;
487 exec.post(req);
488#if !LELY_NO_CO_CSDO
489 exec.on_task_fini();
490 } else {
491 req.id = co_csdo_get_par(sdo.get())->id;
492 bool first = sllist_empty(&queue);
493 sllist_push_back(&queue, &req._node);
494 if (first) req.OnRequest(this);
495 }
496#endif
497}
498
499::std::size_t
500Sdo::Impl_::Cancel(detail::SdoRequestBase* req, SdoErrc ac) {
501#if LELY_NO_CO_CSDO
502 (void)req;
503 (void)ac;
504
505 return 0;
506#else
507 sllist queue;
508 sllist_init(&queue);
509
510 // Cancel all matching requests, except for the first (ongoing) request.
511 if (Pop(req, queue))
512 // Stop the ongoing request, if any.
513 co_csdo_abort_req(sdo.get(), static_cast<uint32_t>(ac));
514
515 ::std::size_t n = 0;
516 slnode* node;
517 while ((node = sllist_pop_front(&queue))) {
518 req = static_cast<detail::SdoRequestBase*>(ev_task_from_node(node));
519 req->ec = ac;
520
521 auto exec = req->GetExecutor();
522 exec.post(*req);
523 exec.on_task_fini();
524
525 n += n < ::std::numeric_limits<::std::size_t>::max();
526 }
527 return n;
528#endif
529}
530
531::std::size_t
532Sdo::Impl_::Abort(detail::SdoRequestBase* req) {
533#if LELY_NO_CO_CSDO
534 (void)req;
535
536 return 0;
537#else
538 sllist queue;
539 sllist_init(&queue);
540
541 // Abort all matching requests, except for the first (ongoing) request.
542 Pop(req, queue);
543
544 return ev_task_queue_abort(&queue);
545#endif
546}
547
548#if !LELY_NO_CO_CSDO
549
550bool
551Sdo::Impl_::Pop(detail::SdoRequestBase* req, sllist& queue) {
552 if (!req) {
553 // Cancel all pending requests except for the first (ongoing) request.
554 auto node = sllist_pop_front(&this->queue);
555 sllist_append(&queue, &this->queue);
556 if (node) {
557 sllist_push_front(&this->queue, node);
558 req = static_cast<detail::SdoRequestBase*>(ev_task_from_node(node));
559 }
560 } else if (&req->_node != sllist_first(&this->queue)) {
561 if (sllist_remove(&queue, &req->_node))
562 sllist_push_back(&this->queue, &req->_node);
563 req = nullptr;
564 }
565 // Return true if the first request matched (but was not removed).
566 return req != nullptr;
567}
568
569template <class T>
570void
571Sdo::Impl_::OnDownload(detail::SdoDownloadRequestBase<T>& req) noexcept {
572 assert(&req._node == sllist_first(&queue));
573
574 using traits = canopen_traits<T>;
575
576 auto val = traits::to_c_type(req.value, req.ec);
577 if (req.ec) {
578 OnCompletion(req);
579 } else {
580 int errsv = get_errc();
581 set_errc(0);
582
583 co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
584
585 auto con = [](__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
586 void* data) noexcept {
587 static_cast<Impl_*>(data)->OnDnCon(sdo, idx, subidx, ac);
588 };
589 int result = req.block
590 ? co_csdo_blk_dn_val_req(sdo.get(), req.idx, req.subidx,
591 traits::index, &val, con, this)
592 : co_csdo_dn_val_req(sdo.get(), req.idx, req.subidx,
593 traits::index, &val, con, this);
594 if (result == -1) {
595 req.ec = util::make_error_code();
596 OnCompletion(req);
597 }
598
599 set_errc(errsv);
600 traits::destroy(val);
601 }
602}
603
604void
605Sdo::Impl_::OnDownloadDcf(detail::SdoDownloadDcfRequestBase& req) noexcept {
606 assert(&req._node == sllist_first(&queue));
607
608 int errsv = get_errc();
609 set_errc(0);
610
611 co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
613 sdo.get(), req.begin, req.end,
614 [](__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
615 void* data) noexcept {
616 static_cast<Impl_*>(data)->OnDnCon(sdo, idx, subidx, ac);
617 },
618 this) == -1) {
619 req.ec = util::make_error_code();
620 OnCompletion(req);
621 }
622
623 set_errc(errsv);
624}
625
626template <class T>
627void
628Sdo::Impl_::OnUpload(detail::SdoUploadRequestBase<T>& req) noexcept {
629 assert(&req._node == sllist_first(&queue));
630
631 int errsv = get_errc();
632 set_errc(0);
633
634 co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
635
636 auto con = [](__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
637 const void* ptr, size_t n, void* data) noexcept {
638 static_cast<Impl_*>(data)->OnUpCon<T>(sdo, idx, subidx, ac, ptr, n);
639 };
640 int result =
641 req.block
642 ? co_csdo_blk_up_req(sdo.get(), req.idx, req.subidx, 0, con, this)
643 : co_csdo_up_req(sdo.get(), req.idx, req.subidx, con, this);
644 if (result == -1) {
645 req.ec = util::make_error_code();
646 OnCompletion(req);
647 }
648
649 set_errc(errsv);
650}
651
652void
653Sdo::Impl_::OnDnCon(__co_csdo*, uint16_t idx, uint8_t subidx,
654 uint32_t ac) noexcept {
655 auto task = ev_task_from_node(sllist_first(&queue));
656 assert(task);
657 auto req = static_cast<detail::SdoRequestBase*>(task);
658
659 req->idx = idx;
660 req->subidx = subidx;
661 req->ec = SdoErrc(ac);
662
663 OnCompletion(*req);
664}
665
666template <class T>
667void
668Sdo::Impl_::OnUpCon(__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac,
669 const void* ptr, size_t n) noexcept {
670 using traits = canopen_traits<T>;
671 using c_type = typename traits::c_type;
672
673 auto task = ev_task_from_node(sllist_first(&queue));
674 assert(task);
675 auto req = static_cast<detail::SdoUploadRequestBase<T>*>(task);
676
677 auto val = c_type();
678 if (!ac) {
679 ::std::error_code ec;
680 val = traits::construct(ptr, n, ec);
681 if (ec) ac = static_cast<uint32_t>(sdo_errc(ec));
682 }
683
684 req->idx = idx;
685 req->subidx = subidx;
686 req->ec = SdoErrc(ac);
687 req->value = ac ? T() : traits::from_c_type(val);
688
689 traits::destroy(val);
690
691 OnCompletion(*req);
692}
693
694void
695Sdo::Impl_::OnCompletion(detail::SdoRequestBase& req) noexcept {
696 assert(&req._node == sllist_first(&queue));
697 sllist_pop_front(&queue);
698
699 ev::Executor exec(req.exec);
700 exec.post(req);
701 exec.on_task_fini();
702
703 auto task = ev_task_from_node(sllist_first(&queue));
704 if (task) static_cast<detail::SdoRequestBase*>(task)->OnRequest(this);
705}
706
707#endif // !LELY_NO_CO_CSDO
708
709} // namespace canopen
710
711} // namespace lely
A Client-SDO queue.
Definition: sdo.hpp:588
Sdo()
Default-constructs an invalid Client-SDO queue.
bool Abort(detail::SdoRequestBase &req)
Aborts a pending SDO request.
Definition: sdo.cpp:440
void Submit(detail::SdoRequestBase &req)
Queues an LSS request.
Definition: sdo.cpp:425
bool Cancel(detail::SdoRequestBase &req, SdoErrc ac)
Cancels a pending SDO request.
Definition: sdo.cpp:430
void SubmitDownloadDcf(SdoDownloadDcfRequest &req)
Queues an SDO download DCF request.
Definition: sdo.hpp:705
~Sdo()
Destructs the Client-SDO queue.
::std::size_t AbortAll()
Aborts all pending SDO requests.
Definition: sdo.cpp:445
::std::size_t CancelAll(SdoErrc ac)
Cancels all pending SDO requests and stops the ongoing request, if any.
Definition: sdo.cpp:435
SdoFuture< void > AsyncDownloadDcf(ev_exec_t *exec, const uint8_t *begin, const uint8_t *end, const ::std::chrono::milliseconds &timeout={})
Queues a series asynchronous SDO download requests, corresponding to the entries in the specified con...
Definition: sdo.cpp:389
const uint8_t * end
A pointer to one past the last byte in the concise DCF.
Definition: sdo.hpp:262
void Read(const char *path)
Reads a concise DCF from the specified path.
Definition: sdo.cpp:82
const uint8_t * begin
A pointer the the first byte in a concise DCF (see object 1F22 in CiA 302-3 version 4....
Definition: sdo.hpp:256
uint16_t idx
The object index.
Definition: sdo.hpp:193
uint8_t subidx
The object sub-index.
Definition: sdo.hpp:195
::std::error_code ec
The SDO abort code (0 on success).
Definition: sdo.hpp:208
A future.
Definition: future.hpp:384
A promise.
Definition: future.hpp:60
Future< T, E > get_future() const noexcept
Returns a lely::ev::Future with (a reference to) the same shared state as *this.
Definition: future.hpp:188
bool set(U &&u)
Satisfies a promise, if it was not aready satisfied, and stores the specified value as the result in ...
Definition: future.hpp:166
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_csdo_up_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_csdo_up_con_t *con, void *data)
Submits an upload request to a remote Server-SDO.
Definition: csdo.c:1294
void co_csdo_set_timeout(co_csdo_t *sdo, int timeout)
Sets the timeout of a Client-SDO.
Definition: csdo.c:1142
int co_csdo_get_timeout(const co_csdo_t *sdo)
Returns the timeout (in milliseconds) of a Client-SDO.
Definition: csdo.c:1134
int co_csdo_blk_up_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned8_t pst, co_csdo_up_con_t *con, void *data)
Submits a block upload request to a remote Server-SDO.
Definition: csdo.c:1356
int co_csdo_blk_dn_val_req(co_csdo_t *sdo, 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 block download request to a remote Server-SDO.
Definition: csdo.c:1332
void co_csdo_abort_req(co_csdo_t *sdo, co_unsigned32_t ac)
Submits an abort transfer request to a remote Server-SDO.
Definition: csdo.c:1211
int co_csdo_dn_dcf_req(co_csdo_t *sdo, 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 remote Server-SDO.
Definition: csdo.c:1265
const struct co_sdo_par * co_csdo_get_par(const co_csdo_t *sdo)
Returns a pointer to the SDO parameter record of a Client-SDO.
Definition: csdo.c:1126
co_csdo_t * co_csdo_create(can_net_t *net, co_dev_t *dev, co_unsigned8_t num)
Creates a new CANopen Client-SDO service.
Definition: csdo.c:997
int co_csdo_dn_val_req(co_csdo_t *sdo, 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 remote Server-SDO.
Definition: csdo.c:1241
void co_csdo_destroy(co_csdo_t *sdo)
Destroys a CANopen Client-SDO service.
Definition: csdo.c:1024
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
int to_sdo_timeout(const ::std::chrono::duration< Rep, Period > &d)
Converts a duration to an SDO timeout.
Definition: sdo.hpp:148
SdoErrc
The SDO abort codes.
Definition: sdo_error.hpp:42
@ NO_SDO
Resource not available: SDO connection.
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
Definition: sdo_error.cpp:180
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
::std::exception_ptr make_sdo_exception_ptr(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec) noexcept
Creates an std::exception_ptr that holds a reference to a lely::canopen::SdoError with the specified ...
Definition: sdo_error.cpp:209
This header file is part of the C++ CANopen master library; it contains the Client-SDO queue declarat...
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
Definition: sllist.h:194
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
Definition: sllist.h:257
void sllist_push_front(struct sllist *list, struct slnode *node)
Pushes a node to the front of a singly-linked list.
Definition: sllist.h:221
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
Definition: sllist.c:46
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
Definition: sllist.h:232
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
Definition: sllist.h:202
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
Definition: sllist.h:243
struct slnode * sllist_first(const struct sllist *list)
Returns a pointer to the first node in a singly-linked list.
Definition: sllist.h:271
A CAN network interface.
Definition: net.c:37
A CANopen Client-SDO.
Definition: csdo.c:71
co_unsigned16_t idx
The current object index.
Definition: csdo.c:91
A CANopen device.
Definition: dev.h:30
co_unsigned8_t id
Node-ID of SDO's client resp. server.
Definition: sdo.h:53
The internal implementation of the Client-SDO queue.
Definition: sdo.cpp:45
A singly-linked list.
Definition: sllist.h:52
A node in a singly-linked list.
Definition: sllist.h:40
size_t ev_task_queue_abort(struct sllist *queue)
Aborts the tasks in queue by invoking ev_exec_on_task_fini() for each of them.
Definition: task.c:55
struct ev_task * ev_task_from_node(struct slnode *node)
Converts a pointer to a node in a queue to the address of the task containing the node.
Definition: task.c:32
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
Definition: type.h:77
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.
Definition: val.c:260
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.
Definition: val.c:269
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.
Definition: val.c:671
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
Definition: val.c:249