81 void OnCsInd(
COLSS*, uint8_t cs) noexcept;
82 void OnErrInd(
COLSS*, uint8_t cs, uint8_t err, uint8_t spec) noexcept;
83 void OnLssIdInd(
COLSS*, uint8_t cs, co_unsigned32_t
id) noexcept;
84 void OnNidInd(
COLSS*, uint8_t cs, uint8_t
id) noexcept;
85 void OnScanInd(
COLSS*, uint8_t cs,
const co_id*
id) noexcept;
87 void OnWait(::std::error_code) noexcept;
103 void* lss_data{
nullptr};
109 co_id id1{4, 0, 0, 0, 0};
110 co_id id2{4, 0, 0, 0, 0};
116 LssSwitchRequestBase::OnRequest(
void* data) noexcept {
117 static_cast<LssMaster::Impl_*
>(data)->OnSwitch(*
this);
121 LssSwitchSelectiveRequestBase::OnRequest(
void* data) noexcept {
122 static_cast<LssMaster::Impl_*
>(data)->OnSwitchSelective(*
this);
126 LssSetIdRequestBase::OnRequest(
void* data) noexcept {
127 static_cast<LssMaster::Impl_*
>(data)->OnSetId(*
this);
131 LssSetBitrateRequestBase::OnRequest(
void* data) noexcept {
132 static_cast<LssMaster::Impl_*
>(data)->OnSetBitrate(*
this);
136 LssSwitchBitrateRequestBase::OnRequest(
void* data) noexcept {
137 static_cast<LssMaster::Impl_*
>(data)->OnSwitchBitrate(*
this);
141 LssStoreRequestBase::OnRequest(
void* data) noexcept {
142 static_cast<LssMaster::Impl_*
>(data)->OnStore(*
this);
146 LssGetVendorIdRequestBase::OnRequest(
void* data) noexcept {
147 static_cast<LssMaster::Impl_*
>(data)->OnGetVendorId(*
this);
151 LssGetProductCodeRequestBase::OnRequest(
void* data) noexcept {
152 static_cast<LssMaster::Impl_*
>(data)->OnGetProductCode(*
this);
156 LssGetRevisionRequestBase::OnRequest(
void* data) noexcept {
157 static_cast<LssMaster::Impl_*
>(data)->OnGetRevision(*
this);
161 LssGetSerialNrRequestBase::OnRequest(
void* data) noexcept {
162 static_cast<LssMaster::Impl_*
>(data)->OnGetSerialNr(*
this);
166 LssGetIdRequestBase::OnRequest(
void* data) noexcept {
167 static_cast<LssMaster::Impl_*
>(data)->OnGetId(*
this);
171 LssIdNonConfigRequestBase::OnRequest(
void* data) noexcept {
172 static_cast<LssMaster::Impl_*
>(data)->OnIdNonConfig(*
this);
176 LssSlowscanRequestBase::OnRequest(
void* data) noexcept {
177 static_cast<LssMaster::Impl_*
>(data)->OnSlowscan(*
this);
181 LssFastscanRequestBase::OnRequest(
void* data) noexcept {
182 static_cast<LssMaster::Impl_*
>(data)->OnFastscan(*
this);
188 : impl_(new
Impl_(this, exec, node, ctrl, node.nmt())) {}
190 LssMaster::~LssMaster() =
default;
207 ::std::chrono::microseconds
209 ::std::lock_guard<Impl_>
lock(*impl_);
210 ::std::chrono::microseconds::rep value = impl_->inhibit;
211 return ::std::chrono::microseconds(value * 100);
216 auto value = inhibit.count();
218 if (value > ::std::numeric_limits<uint16_t>::max() * 100)
219 value = ::std::numeric_limits<uint16_t>::max() * 100;
221 ::std::lock_guard<Impl_>
lock(*impl_);
223 impl_->inhibit = (value + 99) / 100;
224 if (impl_->lss) impl_->lss->setInhibit(impl_->inhibit);
228 ::std::chrono::milliseconds
230 ::std::lock_guard<Impl_>
lock(*impl_);
231 return ::std::chrono::milliseconds(impl_->timeout);
236 auto value = timeout.count();
238 if (value > ::std::numeric_limits<int>::max())
239 value = ::std::numeric_limits<int>::max();
241 ::std::lock_guard<Impl_>
lock(*impl_);
242 impl_->timeout = value;
243 if (impl_->lss) impl_->lss->setTimeout(impl_->timeout);
253 p.
set(ec ? ::std::make_exception_ptr(
254 ::std::system_error(ec,
"AsyncSwitch"))
257 if (preq) *preq = req;
267 exec, address, [p](::std::error_code ec)
mutable {
268 p.
set(ec ? ::std::make_exception_ptr(
269 ::std::system_error(ec,
"AsyncSwitchSelective"))
272 if (preq) *preq = req;
283 p.
set(ec ? ::std::make_exception_ptr(
284 ::std::system_error(ec,
"AsyncSetId"))
287 if (preq) *preq = req;
297 exec, bitrate, [p](::std::error_code ec)
mutable {
298 p.
set(ec ? ::std::make_exception_ptr(
299 ::std::system_error(ec,
"AsyncSetBitrate"))
302 if (preq) *preq = req;
311 p.
set(ec ? ::std::make_exception_ptr(::std::system_error(ec,
"AsyncStore"))
314 if (preq) *preq = req;
324 exec, [p](::std::error_code ec, uint32_t number)
mutable {
326 p.
set(util::failure(::std::make_exception_ptr(
327 ::std::system_error(ec,
"AsyncGetVendorId"))));
329 p.
set(util::success(number));
331 if (preq) *preq = req;
341 exec, [p](::std::error_code ec, uint32_t number)
mutable {
343 p.
set(util::failure(::std::make_exception_ptr(
344 ::std::system_error(ec,
"AsyncGetProductCode"))));
346 p.
set(util::success(number));
348 if (preq) *preq = req;
358 exec, [p](::std::error_code ec, uint32_t number)
mutable {
360 p.
set(util::failure(::std::make_exception_ptr(
361 ::std::system_error(ec,
"AsyncGetRevision"))));
363 p.
set(util::success(number));
365 if (preq) *preq = req;
375 exec, [p](::std::error_code ec, uint32_t number)
mutable {
377 p.
set(util::failure(::std::make_exception_ptr(
378 ::std::system_error(ec,
"AsyncGetSerialNr"))));
380 p.
set(util::success(number));
382 if (preq) *preq = req;
391 exec, [p](::std::error_code ec, uint8_t
id)
mutable {
393 p.
set(util::failure(::std::make_exception_ptr(
394 ::std::system_error(ec,
"AsyncGetId"))));
396 p.
set(util::success(
id));
398 if (preq) *preq = req;
408 exec, [p](::std::error_code ec,
bool found)
mutable {
410 p.
set(util::failure(::std::make_exception_ptr(
411 ::std::system_error(ec,
"AsyncIdNonConfig"))));
413 p.
set(util::success(found));
415 if (preq) *preq = req;
427 [p](::std::error_code ec,
const LssAddress& address)
mutable {
429 p.
set(util::failure(::std::make_exception_ptr(
430 ::std::system_error(ec,
"AsyncSlowscan"))));
432 p.
set(util::success(address));
434 if (preq) *preq = req;
446 [p](::std::error_code ec,
const LssAddress& address)
mutable {
448 p.
set(util::failure(::std::make_exception_ptr(
449 ::std::system_error(ec,
"AsyncFastscan"))));
451 p.
set(util::success(address));
453 if (preq) *preq = req;
460 ::std::lock_guard<util::BasicLockable>
lock(*
this);
467 ::std::lock_guard<Impl_>
lock(*impl_);
468 return impl_->Cancel(&req, ec) != 0;
474 ::std::lock_guard<Impl_>
lock(*impl_);
475 return impl_->Cancel(
nullptr, ec);
480 ::std::lock_guard<Impl_>
lock(*impl_);
481 return impl_->Abort(&req) != 0;
486 ::std::lock_guard<Impl_>
lock(*impl_);
487 return impl_->Abort(
nullptr);
492 int bitrate, ::std::chrono::milliseconds delay,
493 ::std::function<
void(::std::error_code ec)> res) noexcept {
494 if (GetController()) {
498 .AsyncWait(GetExecutor(), delay / 2)
504 GetController()->stop();
507 return GetNode().AsyncWait(GetExecutor(), delay / 2);
514 GetController()->set_bitrate(bitrate);
517 return GetNode().AsyncWait(GetExecutor(), delay);
520 ::std::error_code ec;
525 GetController()->restart();
526 }
catch (::std::system_error& e) {
556 exec(exec_ ? exec_ : static_cast<
ev_exec_t*>(node.GetExecutor())),
561 nmt->getLSSReq(&lss_func, &lss_data);
562 nmt->setLSSReq<Impl_, &Impl_::OnLssReq>(
this);
565 inhibit = lss->getInhibit();
566 timeout = lss->getTimeout();
573 ::std::error_code ec;
574 ctrl->get_bitrate(&bitrate,
nullptr, ec);
578 LssMaster::Impl_::~Impl_() { nmt->setLSSReq(lss_func, lss_data); }
581 LssMaster::Impl_::OnLssReq(CONMT*, COLSS* lss) noexcept {
584 lss->setInhibit(inhibit);
585 lss->setTimeout(timeout);
589 self->GetExecutor().post([
this]() noexcept {
590 self->OnStart([
this](::std::error_code) noexcept {
591 ::std::lock_guard<Impl_>
lock(*
this);
599 LssMaster::Impl_::Submit(detail::LssRequestBase& req) {
600 if (!req.exec) req.exec =
self->GetExecutor();
601 auto exec = req.GetExecutor();
606 if (first) OnRequest(req);
610 LssMaster::Impl_::Cancel(detail::LssRequestBase* req, ::std::error_code ec) {
625 auto exec = req->GetExecutor();
629 n += n < ::std::numeric_limits<::std::size_t>::max();
635 LssMaster::Impl_::Abort(detail::LssRequestBase* req) {
646 LssMaster::Impl_::Pop(detail::LssRequestBase* req,
sllist& queue) {
662 return req !=
nullptr;
666 LssMaster::Impl_::OnSwitch(detail::LssSwitchRequestBase& req) noexcept {
672 ::std::error_code ec;
673 if (!lss->switchReq(
static_cast<int>(req.state)))
683 LssMaster::Impl_::OnSwitchSelective(
684 detail::LssSwitchSelectiveRequestBase& req) noexcept {
688 id1 = {4, req.address.vendor_id, req.address.product_code,
689 req.address.revision, req.address.serial_nr};
696 if (lss->switchSelReq<Impl_, &Impl_::OnCsInd>(id1,
this) == -1) {
705 LssMaster::Impl_::OnSetId(detail::LssSetIdRequestBase& req) noexcept {
714 if (lss->setIdReq<Impl_, &Impl_::OnErrInd>(req.id,
this) == -1) {
723 LssMaster::Impl_::OnSetBitrate(detail::LssSetBitrateRequestBase& req) noexcept {
732 switch (req.bitrate) {
741 if (lss->setRateReq<Impl_, &Impl_::OnErrInd>(req.bitrate / 1000,
this) ==
746 bitrate = req.bitrate;
758 LssMaster::Impl_::OnSwitchBitrate(
759 detail::LssSwitchBitrateRequestBase& req) noexcept {
768 if (!bitrate || req.delay < 0 ||
769 req.delay > ::std::numeric_limits<uint16_t>::max()) {
772 }
else if (lss->switchRateReq(req.delay) == -1) {
779 ::std::chrono::milliseconds delay(req.delay);
781 self->GetExecutor().post([
this, delay]() noexcept {
782 self->OnSwitchBitrate(bitrate, delay, [
this](::std::error_code ec) {
784 ::std::lock_guard<Impl_>
lock(*
this);
787 auto req =
static_cast<detail::LssSwitchBitrateRequestBase*
>(task);
798 LssMaster::Impl_::OnStore(detail::LssStoreRequestBase& req) noexcept {
807 if (lss->storeReq<Impl_, &Impl_::OnErrInd>(
this) == -1) {
816 LssMaster::Impl_::OnGetVendorId(
817 detail::LssGetVendorIdRequestBase& req) noexcept {
827 if (lss->getVendorIdReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
836 LssMaster::Impl_::OnGetProductCode(
837 detail::LssGetProductCodeRequestBase& req) noexcept {
847 if (lss->getProductCodeReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
856 LssMaster::Impl_::OnGetRevision(
857 detail::LssGetRevisionRequestBase& req) noexcept {
867 if (lss->getRevisionReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
876 LssMaster::Impl_::OnGetSerialNr(
877 detail::LssGetSerialNrRequestBase& req) noexcept {
887 if (lss->getSerialNrReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
896 LssMaster::Impl_::OnGetId(detail::LssGetIdRequestBase& req) noexcept {
906 if (lss->getIdReq<Impl_, &Impl_::OnNidInd>(
this) == -1) {
915 LssMaster::Impl_::OnIdNonConfig(
916 detail::LssIdNonConfigRequestBase& req) noexcept {
925 if (lss->idNonCfgSlaveReq<Impl_, &Impl_::OnCsInd>(
this) == -1) {
934 LssMaster::Impl_::OnSlowscan(detail::LssSlowscanRequestBase& req) noexcept {
938 id1 = {4, req.lo.vendor_id, req.lo.product_code, req.lo.revision,
940 id2 = {4, req.hi.vendor_id, req.hi.product_code, req.hi.revision,
948 req.address = {0, 0, 0, 0};
949 if (lss->slowscanReq<Impl_, &Impl_::OnScanInd>(id1, id2,
this) == -1) {
958 LssMaster::Impl_::OnFastscan(detail::LssFastscanRequestBase& req) noexcept {
962 id1 = {4, req.address.vendor_id, req.address.product_code,
963 req.address.revision, req.address.serial_nr};
964 id2 = {4, req.mask.vendor_id, req.mask.product_code, req.mask.revision,
972 if (lss->fastscanReq<Impl_, &Impl_::OnScanInd>(&id1, &id2,
this) == -1) {
981 LssMaster::Impl_::OnCsInd(COLSS*, uint8_t cs) noexcept {
984 auto req =
static_cast<detail::LssSwitchRequestBase*
>(task);
995 LssMaster::Impl_::OnErrInd(COLSS*, uint8_t cs, uint8_t err, uint8_t) noexcept {
998 auto req =
static_cast<detail::LssRequestBase*
>(task);
1045 LssMaster::Impl_::OnLssIdInd(COLSS*, uint8_t cs, co_unsigned32_t
id) noexcept {
1048 auto req =
static_cast<detail::LssGetNumberRequestBase*
>(task);
1061 LssMaster::Impl_::OnNidInd(COLSS*, uint8_t cs, uint8_t
id) noexcept {
1064 auto req =
static_cast<detail::LssGetIdRequestBase*
>(task);
1077 LssMaster::Impl_::OnScanInd(COLSS*, uint8_t cs,
const co_id*
id) noexcept {
1081 auto req =
static_cast<detail::LssScanRequestBase*
>(task);
1085 req->address.vendor_id =
id->vendor_id;
1086 req->address.product_code =
id->product_code;
1087 req->address.revision =
id->revision;
1088 req->address.serial_nr =
id->serial_nr;
1097 LssMaster::Impl_::OnRequest(detail::LssRequestBase& req) noexcept {
1099 req.OnRequest(
this);
1107 LssMaster::Impl_::OnCompletion(detail::LssRequestBase& req) noexcept {
1111 auto exec = req.GetExecutor();
1113 exec.on_task_fini();
1116 if (task) OnRequest(*
static_cast<detail::LssRequestBase*
>(task));
An opaque CANopen LSS master/slave service type.
An opaque CANopen NMT master/slave service type.
The base class for CANopen LSS masters.
bool Abort(detail::LssRequestBase &req)
Aborts a pending LSS request.
ev::Executor GetExecutor() const noexcept
Returns the default executor used to execute completion tasks of LSS requests.
LssMaster(ev_exec_t *exec, Node &node, io::CanControllerBase *ctrl=nullptr)
Creates a new CANopen LSS master.
LssFuture< uint8_t > AsyncGetId(ev_exec_t *exec, detail::LssGetIdRequestBase **preq=nullptr)
Queues an asynchronous LSS 'inquire node-ID' request and creates a future which becomes ready once th...
LssFuture< LssAddress > AsyncSlowscan(ev_exec_t *exec, const LssAddress &lo, const LssAddress &hi, detail::LssSlowscanRequestBase **preq=nullptr)
Queues an asynchronous 'LSS Slowscan' request and creates a future which becomes ready once the reque...
LssFuture< void > AsyncSetBitrate(ev_exec_t *exec, int bitrate, detail::LssSetBitrateRequestBase **preq=nullptr)
Queues an asynchronous LSS 'configure bit timing parameters' request and creates a future which becom...
LssFuture< uint32_t > AsyncGetProductCode(ev_exec_t *exec, detail::LssGetProductCodeRequestBase **preq=nullptr)
Queues an asynchronous LSS 'inquire identity product-code' request and creates a future which becomes...
Node & GetNode() const noexcept
Returns the CANopen master node.
void SetTime()
Update the CAN network time.
LssFuture< void > AsyncSwitchSelective(ev_exec_t *exec, const LssAddress &address, detail::LssSwitchSelectiveRequestBase **preq=nullptr)
Queues an asynchronous LSS 'switch state selective' request and creates a future which becomes ready ...
LssFuture< LssAddress > AsyncFastscan(ev_exec_t *exec, const LssAddress &address={0, 0, 0, 0}, const LssAddress &mask={0, 0, 0, 0}, detail::LssFastscanRequestBase **preq=nullptr)
Queues an asynchronous 'LSS Fastscan' request and creates a future which becomes ready once the reque...
LssFuture< void > AsyncSwitch(ev_exec_t *exec, LssState state=LssState::WAITING, detail::LssSwitchRequestBase **preq=nullptr)
Queues an asynchronous LSS 'switch state global' request and creates a future which becomes ready onc...
LssFuture< uint32_t > AsyncGetVendorId(ev_exec_t *exec, detail::LssGetVendorIdRequestBase **preq=nullptr)
Queues an asynchronous LSS 'inquire identity vendor-ID' request and creates a future which becomes re...
bool Cancel(detail::LssRequestBase &req)
Cancels a pending LSS request.
::std::size_t AbortAll()
Aborts all pending LSS requests.
void Submit(detail::LssRequestBase &req)
Queues an LSS request.
LssFuture< uint32_t > AsyncGetSerialNr(ev_exec_t *exec, detail::LssGetSerialNrRequestBase **preq=nullptr)
Queues an asynchronous LSS 'inquire identity serial-number' request and creates a future which become...
void lock() final
Blocks until a lock can be obtained for the current execution agent (thread, process,...
void SetTimeout(const ::std::chrono::milliseconds &timeout)
Sets the timeout when waiting for a slave to respond to an LSS request.
::std::chrono::microseconds GetInhibit() const
Returns the inhibit time between successive CAN frames.
virtual void OnSwitchBitrate(int bitrate, ::std::chrono::milliseconds delay, ::std::function< void(::std::error_code ec)> res) noexcept
The function invoked when the master activates the bit rate of all CANopen devices in the network.
void unlock() final
Releases the lock held by the execution agent. Throws no exceptions.
void SetInhibit(const ::std::chrono::microseconds &inhibit)
Sets the inhibit time between successive CAN frames.
::std::chrono::milliseconds GetTimeout() const
Returns the timeout when waiting for a slave to respond to an LSS request.
io::CanControllerBase * GetController() const noexcept
Returns the pointer to the CAN controller for this node passed to the constructor (may be a null poin...
LssFuture< uint32_t > AsyncGetRevision(ev_exec_t *exec, detail::LssGetRevisionRequestBase **preq=nullptr)
Queues an asynchronous LSS 'inquire identity revision-number' request and creates a future which beco...
LssFuture< bool > AsyncIdNonConfig(ev_exec_t *exec, detail::LssIdNonConfigRequestBase **preq=nullptr)
Queues an asynchronous LSS 'identify non-configured remote slave' request and creates a future which ...
LssFuture< void > AsyncSetId(ev_exec_t *exec, uint8_t id, detail::LssSetIdRequestBase **preq=nullptr)
Queues an asynchronous LSS 'configure node-ID' request and creates a future which becomes ready once ...
::std::size_t CancelAll()
Cancels all pending LSS requests and stops the ongoing request, if any.
LssFuture< void > AsyncStore(ev_exec_t *exec, detail::LssStoreRequestBase **preq=nullptr)
Queues an asynchronous LSS 'store configuration' request and creates a future which becomes ready onc...
The base class for CANopen nodes.
void SetTime()
Updates the CAN network time.
An abstract task executor. This class is a wrapper around #ev_exec_t*.
result_type & get()
Returns the result of a ready future.
Future< T, E > get_future() const noexcept
Returns a lely::ev::Future with (a reference to) the same shared state as *this.
bool set(U &&u)
Satisfies a promise, if it was not aready satisfied, and stores the specified value as the result in ...
A reference to an abstract CAN controller.
void unlock() final
Releases the lock held by the execution agent. Throws no exceptions.
void lock() final
Blocks until a lock can be obtained for the current execution agent (thread, process,...
An abstract interface conforming to the BasicLockable concept.
value_type & value()
Returns a reference to the value if *this contains a value, and throws an exception if *this contains...
This is the internal header file of the C++ CANopen application library.
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.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
#define LELY_CO_LSS_INHIBIT
The default LSS inhibit time (in multiples of 100 microseconds).
#define LELY_CO_LSS_TIMEOUT
The default LSS timeout (in milliseconds).
This header file is part of the CANopen library; it contains the C++ interface of the Layer Setting S...
This header file is part of the C++ CANopen application library; it contains the CANopen Layer Settin...
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::LssSwitchSelectiveRequestWrapper< F > * >::type make_lss_switch_selective_request(ev_exec_t *exec, const LssAddress &address, F &&con)
Creates an LSS 'switch state selective' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, uint32_t >::value, detail::LssGetRevisionRequestWrapper< F > * >::type make_lss_get_revision_request(ev_exec_t *exec, F &&con)
Creates an LSS 'inquire identity revision-number' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::LssSetBitrateRequestWrapper< F > * >::type make_lss_set_bitrate_request(ev_exec_t *exec, int bitrate, F &&con)
Creates an LSS 'configure bit timing parameters' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, bool >::value, detail::LssIdNonConfigRequestWrapper< F > * >::type make_lss_id_non_config_request(ev_exec_t *exec, F &&con)
Creates an LSS 'identify non-configured remote slave' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, uint32_t >::value, detail::LssGetSerialNrRequestWrapper< F > * >::type make_lss_get_serial_nr_request(ev_exec_t *exec, F &&con)
Creates an LSS 'inquire identity serial-number' request with a completion task.
LssState
The states of the LSS finite state automaton (FSA) of a slave device.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::LssStoreRequestWrapper< F > * >::type make_lss_store_request(ev_exec_t *exec, F &&con)
Creates an LSS 'store configuration' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, uint32_t >::value, detail::LssGetVendorIdRequestWrapper< F > * >::type make_lss_get_vendor_id_request(ev_exec_t *exec, F &&con)
Creates an LSS 'inquire identity vendor-ID' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, uint8_t >::value, detail::LssGetIdRequestWrapper< F > * >::type make_lss_get_id_request(ev_exec_t *exec, F &&con)
Creates an LSS 'inquire node-ID' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::LssSetIdRequestWrapper< F > * >::type make_lss_set_id_request(ev_exec_t *exec, uint8_t id, F &&con)
Creates an LSS 'configure node-ID' request with a completion task.
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::LssSwitchRequestWrapper< F > * >::type make_lss_switch_request(ev_exec_t *exec, LssState state, F &&con)
Creates an LSS 'switch state global' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, LssAddress >::value, detail::LssSlowscanRequestWrapper< F > * >::type make_lss_slowscan_request(ev_exec_t *exec, const LssAddress &lo, const LssAddress &hi, F &&con)
Creates an 'LSS Slowscan' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, LssAddress >::value, detail::LssFastscanRequestWrapper< F > * >::type make_lss_fastscan_request(ev_exec_t *exec, const LssAddress &address, const LssAddress &mask, F &&con)
Creates an 'LSS Fastscan' request with a completion task.
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code, uint32_t >::value, detail::LssGetProductCodeRequestWrapper< F > * >::type make_lss_get_product_code_request(ev_exec_t *exec, F &&con)
Creates an LSS 'inquire identity product-code' request with a completion task.
void co_nmt_lss_req_t(co_nmt_t *nmt, co_lss_t *lss, void *data)
The type of a CANopen LSS request function, invoked by an NMT master before booting the slaves (see F...
This header file is part of the CANopen library; it contains the C++ interface of the network managem...
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
void sllist_push_front(struct sllist *list, struct slnode *node)
Pushes a node to the front of a singly-linked list.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
struct slnode * sllist_first(const struct sllist *list)
Returns a pointer to the first node in a singly-linked list.
The 128-bit number uniquely identifying each CANopen node.
void lock() final
Blocks until a lock can be obtained for the current execution agent (thread, process,...
void unlock() final
Releases the lock held by the execution agent. Throws no exceptions.
A node in a singly-linked list.
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.
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.