26#if !LELY_NO_COAPP_SLAVE
50 netid()
const noexcept {
73 ::std::function<
void(
bool)> on_life_guarding;
82BasicSlave::~BasicSlave() =
default;
85typename ::std::enable_if<is_canopen<T>::value>::type
89 OnRead<T>(idx, subidx, ::std::move(ind), ec);
90 if (ec)
throw SdoError(impl_->id(), idx, subidx, ec);
95template <
class T,
class F>
99 using c_type =
typename traits::c_type;
108 auto value = traits::from_c_type(*
pval);
111 ac =
static_cast<uint32_t>(ec.value());
114 auto val = traits::to_c_type(value, ec);
115 ac =
static_cast<uint32_t>(ec.value());
117 traits::destroy(val);
126typename ::std::enable_if<is_canopen<T>::value>::type
129 ::std::error_code& ec) {
148 auto key = Impl_::Key(
sub);
157 auto self =
static_cast<Impl_*
>(data);
158 auto it = self->up_ind.find(self->Key(
sub));
159 if (
it == self->up_ind.end())
return 0;
160 return it->second(
sub, req);
169typename ::std::enable_if<is_canopen<T>::value>::type
176typename ::std::enable_if<is_canopen<T>::value>::type
178 ::std::error_code& ec) {
184typename ::std::enable_if<is_canopen<T>::value>::type
187 ::std::error_code ec;
188 OnWrite<T>(idx, subidx, ::std::move(ind), ec);
189 if (ec)
throw SdoError(impl_->id(), idx, subidx, ec);
194template <
class T,
class F>
195typename ::std::enable_if<is_canopen_basic<T>::value,
uint32_t>::type
198 using c_type =
typename traits::c_type;
211 ac =
static_cast<uint32_t>(ec.value());
216 traits::destroy(val);
220template <
class T,
class F>
221typename ::std::enable_if<!is_canopen_basic<T>::value, uint32_t>::type
223 using traits = canopen_traits<T>;
224 using c_type =
typename traits::c_type;
234 auto value = traits::from_c_type(val);
238 traits::destroy(val);
239 val = traits::to_c_type(value, ec);
241 ac =
static_cast<uint32_t
>(ec.value());
246 traits::destroy(val);
253typename ::std::enable_if<is_canopen<T>::value>::type
256 ::std::error_code& ec) {
275 auto key = Impl_::Key(
sub);
283 auto self =
static_cast<Impl_*
>(data);
284 auto it = self->dn_ind.find(self->Key(
sub));
285 if (
it == self->dn_ind.end())
return 0;
286 return it->second(
sub, req);
295typename ::std::enable_if<is_canopen<T>::value>::type
302typename ::std::enable_if<is_canopen<T>::value>::type
304 ::std::error_code& ec) {
309#ifndef DOXYGEN_SHOULD_SKIP_THIS
317template void BasicSlave::OnRead<bool>(
uint16_t,
319template void BasicSlave::OnRead<bool>(
uint16_t,
322template void BasicSlave::OnWrite<bool>(
327template void BasicSlave::OnWrite<bool>(
329template void BasicSlave::OnWrite<bool>(
uint16_t,
334template void BasicSlave::OnRead<int8_t>(
336template void BasicSlave::OnRead<int8_t>(
339template void BasicSlave::OnRead<int8_t>(
341template void BasicSlave::OnRead<int8_t>(
343template void BasicSlave::OnWrite<int8_t>(
345template void BasicSlave::OnWrite<int8_t>(
348template void BasicSlave::OnWrite<int8_t>(
350template void BasicSlave::OnWrite<int8_t>(
354template void BasicSlave::OnRead<int16_t>(
356template void BasicSlave::OnRead<int16_t>(
359template void BasicSlave::OnRead<int16_t>(
361template void BasicSlave::OnRead<int16_t>(
363template void BasicSlave::OnWrite<int16_t>(
365template void BasicSlave::OnWrite<int16_t>(
368template void BasicSlave::OnWrite<int16_t>(
370template void BasicSlave::OnWrite<int16_t>(
374template void BasicSlave::OnRead<int32_t>(
376template void BasicSlave::OnRead<int32_t>(
379template void BasicSlave::OnRead<int32_t>(
381template void BasicSlave::OnRead<int32_t>(
383template void BasicSlave::OnWrite<int32_t>(
385template void BasicSlave::OnWrite<int32_t>(
388template void BasicSlave::OnWrite<int32_t>(
390template void BasicSlave::OnWrite<int32_t>(
394template void BasicSlave::OnRead<uint8_t>(
396template void BasicSlave::OnRead<uint8_t>(
399template void BasicSlave::OnRead<uint8_t>(
401template void BasicSlave::OnRead<uint8_t>(
403template void BasicSlave::OnWrite<uint8_t>(
405template void BasicSlave::OnWrite<uint8_t>(
408template void BasicSlave::OnWrite<uint8_t>(
410template void BasicSlave::OnWrite<uint8_t>(
414template void BasicSlave::OnRead<uint16_t>(
416template void BasicSlave::OnRead<uint16_t>(
419template void BasicSlave::OnRead<uint16_t>(
421template void BasicSlave::OnRead<uint16_t>(
423template void BasicSlave::OnWrite<uint16_t>(
425template void BasicSlave::OnWrite<uint16_t>(
428template void BasicSlave::OnWrite<uint16_t>(
430template void BasicSlave::OnWrite<uint16_t>(
434template void BasicSlave::OnRead<uint32_t>(
436template void BasicSlave::OnRead<uint32_t>(
439template void BasicSlave::OnRead<uint32_t>(
441template void BasicSlave::OnRead<uint32_t>(
443template void BasicSlave::OnWrite<uint32_t>(
445template void BasicSlave::OnWrite<uint32_t>(
448template void BasicSlave::OnWrite<uint32_t>(
450template void BasicSlave::OnWrite<uint32_t>(
454template void BasicSlave::OnRead<float>(
459template void BasicSlave::OnRead<float>(
461template void BasicSlave::OnRead<float>(
uint16_t,
464template void BasicSlave::OnWrite<float>(
466template void BasicSlave::OnWrite<float>(
469template void BasicSlave::OnWrite<float>(
471template void BasicSlave::OnWrite<float>(
475template void BasicSlave::OnRead<::std::string>(
477template void BasicSlave::OnRead<::std::string>(
480template void BasicSlave::OnRead<::std::string>(
482template void BasicSlave::OnRead<::std::string>(
485template void BasicSlave::OnWrite<::std::string>(
487template void BasicSlave::OnWrite<::std::string>(
490template void BasicSlave::OnWrite<::std::string>(
492template void BasicSlave::OnWrite<::std::string>(
497template void BasicSlave::OnRead<::std::vector<uint8_t>>(
499 ::std::function<OnReadSignature<::std::vector<uint8_t>>>);
500template void BasicSlave::OnRead<::std::vector<uint8_t>>(
501 uint16_t,
uint8_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>,
503template void BasicSlave::OnRead<::std::vector<uint8_t>>(
504 uint16_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>);
505template void BasicSlave::OnRead<::std::vector<uint8_t>>(
506 uint16_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>,
508template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
510 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>);
511template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
513 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>,
515template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
516 uint16_t, ::std::function<OnWriteSignature<::std::vector<uint8_t>>>);
517template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
518 uint16_t, ::std::function<OnWriteSignature<::std::vector<uint8_t>>>,
522template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
524 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>);
525template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
527 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>,
529template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
530 uint16_t, ::std::function<OnReadSignature<::std::basic_string<char16_t>>>);
531template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
532 uint16_t, ::std::function<OnReadSignature<::std::basic_string<char16_t>>>,
534template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
536 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>);
537template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
539 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>,
541template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
542 uint16_t, ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>);
543template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
544 uint16_t, ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>,
553template void BasicSlave::OnRead<double>(
555template void BasicSlave::OnRead<double>(
558template void BasicSlave::OnRead<double>(
560template void BasicSlave::OnRead<double>(
562template void BasicSlave::OnWrite<double>(
564template void BasicSlave::OnWrite<double>(
567template void BasicSlave::OnWrite<double>(
569template void BasicSlave::OnWrite<double>(
577template void BasicSlave::OnRead<int64_t>(
579template void BasicSlave::OnRead<int64_t>(
582template void BasicSlave::OnRead<int64_t>(
584template void BasicSlave::OnRead<int64_t>(
586template void BasicSlave::OnWrite<int64_t>(
588template void BasicSlave::OnWrite<int64_t>(
591template void BasicSlave::OnWrite<int64_t>(
593template void BasicSlave::OnWrite<int64_t>(
602template void BasicSlave::OnRead<uint64_t>(
604template void BasicSlave::OnRead<uint64_t>(
607template void BasicSlave::OnRead<uint64_t>(
609template void BasicSlave::OnRead<uint64_t>(
611template void BasicSlave::OnWrite<uint64_t>(
613template void BasicSlave::OnWrite<uint64_t>(
616template void BasicSlave::OnWrite<uint64_t>(
618template void BasicSlave::OnWrite<uint64_t>(
625 ::std::lock_guard<util::BasicLockable>
lock(*
this);
626 impl_->on_life_guarding = on_life_guarding;
635 [](
co_nmt_t*
nmt,
int state,
void* data)
noexcept {
636 static_cast<Impl_*
>(data)->OnLgInd(
nmt, state);
644BasicSlave::Impl_::OnLgInd(
co_nmt_t* nmt,
int state)
noexcept {
649 self->OnLifeGuarding(occurred);
650 if (on_life_guarding) {
651 auto f = on_life_guarding;
652 util::UnlockGuard<util::BasicLockable> unlock(*self);
659BasicSlave::Impl_::Key(uint16_t idx, uint8_t subidx)
noexcept {
660 return (uint32_t(idx) << 8) | subidx;
664BasicSlave::Impl_::Key(
const co_sub_t* sub)
noexcept {
The base class for CANopen slaves.
BasicSlave(ev_exec_t *exec, io::TimerBase &timer, io::CanChannelBase &chan, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen slave.
typename::std::enable_if< is_canopen< 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-...
typename::std::enable_if< is_canopen< 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...
void OnLifeGuarding(::std::function< void(bool)> on_life_guarding)
Registers the function to be invoked when a life guarding event occurs or is resolved.
__co_dev * dev() const noexcept
Returns a pointer to the internal CANopen device from <lely/co/dev.hpp>.
The base class for CANopen nodes.
__co_nmt * nmt() const noexcept
Returns a pointer to the internal CANopen NMT master/slave service from <lely/co/nmt....
The type of exception thrown when an SDO abort code is received.
A reference to an abstract CAN channel.
void lock() final
Blocks until a lock can be obtained for the current execution agent (thread, process,...
A reference to an abstract timer.
This header file is part of the CANopen library; it contains the device description declarations.
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.
co_unsigned8_t co_dev_get_netid(const co_dev_t *dev)
Returns the network-ID of a CANopen device.
This is the internal header file of the C++ CANopen application library.
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
int co_sdo_req_dn_val(struct co_sdo_req *req, co_unsigned16_t type, void *val, co_unsigned32_t *pac)
Copies the next segment of the specified CANopen SDO download request to the internal buffer and,...
int co_sdo_req_up_val(struct co_sdo_req *req, co_unsigned16_t type, const void *val, co_unsigned32_t *pac)
Writes the specified value to a buffer and constructs a CANopen SDO upload request.
#define CO_SDO_AC_NO_DATA
SDO abort code: No data available.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
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.
@ 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.
This header file is part of the CANopen library; it contains the network management (NMT) declaration...
void co_nmt_on_lg(co_nmt_t *nmt, int state)
Implements the default behavior when a life guarding event occurs (see section 7.2....
void co_nmt_set_lg_ind(co_nmt_t *nmt, co_nmt_lg_ind_t *ind, void *data)
Sets the indication function invoked when a life guarding event occurs.
@ CO_NMT_EC_OCCURRED
An NMT error control event occurred.
This header file is part of the CANopen library; it contains the object dictionary declarations.
co_unsigned8_t co_sub_get_subidx(const co_sub_t *sub)
Returns the sub-index of a CANopen sub-object.
void co_sub_set_up_ind(co_sub_t *sub, co_sub_up_ind_t *ind, void *data)
Sets the upload indication function for 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.
void co_sub_set_dn_ind(co_sub_t *sub, co_sub_dn_ind_t *ind, void *data)
Sets the download indication function for 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.
int co_sub_dn(co_sub_t *sub, void *val)
Downloads (moves) a value into a CANopen sub-object if the refuse-write-on-download flag (CO_OBJ_FLAG...
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_unsigned32_t co_sub_chk_val(const co_sub_t *sub, co_unsigned16_t type, const void *val)
Checks if the specifed value would be a valid value for a CANopen 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 C++ CANopen application library; it contains the CANopen slave declar...
A CANopen NMT master/slave service.
A CANopen SDO upload/download request.
The internal implementation of the CANopen slave.