26#if !LELY_NO_COAPP_MASTER
42 rpdo_mapped(master.RpdoMapped(id)),
43 tpdo_mapped(master.TpdoMapped(id)),
44 tpdo_event_mutex(master.tpdo_event_mutex),
55 throw ::std::out_of_range(
"invalid logical device number: " +
56 ::std::to_string(driver.
Number()));
57 if (find(driver.
id()) != end())
58 throw ::std::out_of_range(
"logical device number " +
59 ::std::to_string(driver.
Number()) +
60 " already registered");
62 MapType::operator[](driver.
Number()) = &driver;
68 if (
it != end() &&
it->second == &driver)
erase(
it);
75 if (
it != end())
return it->second->AsyncConfig();
76 }
else if (size() == 1) {
78 return begin()->second->AsyncConfig();
79 }
else if (!
empty()) {
80 ::std::array<SdoFuture<void>, 8> futures;
83 for (
const auto&
it : *
this) futures[n++] =
it.second->AsyncConfig();
86 ::std::array<ev_future_t*, 8>
tmp;
87 ::std::copy(futures.begin(), futures.end(),
tmp.begin());
93 for (
const auto&
it : futures) {
95 if (
it)
it.get().value();
106 if (
it != end())
return it->second->AsyncDeconfig();
107 }
else if (size() == 1) {
109 return begin()->second->AsyncDeconfig();
110 }
else if (!
empty()) {
111 ::std::array<SdoFuture<void>, 8> futures;
114 for (
const auto&
it : *
this) futures[n++] =
it.second->AsyncDeconfig();
118 ::std::array<ev_future_t*, 8>
tmp;
119 ::std::copy(futures.begin(), futures.end(),
tmp.begin());
125 for (
const auto&
it : futures) {
127 if (
it)
it.get().value();
142 for (
const auto&
it : *
this)
it.second->OnCanError(
error);
147 if (idx >= 0x6000 && idx <= 0x9fff) {
148 int num = (idx - 0x6000) / 0x800 + 1;
150 if (
it != end())
it->second->OnRpdoWrite(idx - (num - 1) * 0x800, subidx);
152 for (
const auto&
it : *
this)
it.second->OnRpdoWrite(idx, subidx);
158 for (
const auto&
it : *
this)
it.second->OnCommand(cs);
163 for (
const auto&
it : *
this)
it.second->OnHeartbeat(
occurred);
168 for (
const auto&
it : *
this)
it.second->OnState(st);
173 for (
const auto&
it : *
this)
it.second->OnSync(cnt,
t);
178 for (
const auto&
it : *
this)
it.second->OnSyncError(eec, er);
183 const ::std::chrono::system_clock::time_point&
abs_time)
noexcept {
184 for (
const auto&
it : *
this)
it.second->OnTime(
abs_time);
189 for (
const auto&
it : *
this)
it.second->OnEmcy(eec, er, msef);
194 for (
const auto&
it : *
this)
it.second->OnNodeGuarding(
occurred);
199 for (
const auto&
it : *
this)
it.second->OnBoot(st, es,
what);
204 ::std::function<
void(::std::error_code ec)>
res)
noexcept {
207 res(::std::error_code{});
210 auto f = AsyncConfig();
212 f.submit(GetExecutor(), [
res, f] {
214 ::std::error_code ec;
215 auto& result = f.get();
216 if (result.has_error()) {
218 ::std::rethrow_exception(result.error());
219 }
catch (const ::std::system_error&
e) {
227 }
catch (::std::system_error&
e) {
234BasicDriver::OnDeconfig(
235 ::std::function<
void(::std::error_code ec)>
res)
noexcept {
238 res(::std::error_code{});
241 auto f = AsyncDeconfig();
243 f.submit(GetExecutor(), [
res, f] {
245 ::std::error_code ec;
246 auto& result = f.get();
247 if (result.has_error()) {
249 ::std::rethrow_exception(result.error());
250 }
catch (const ::std::system_error&
e) {
258 }
catch (::std::system_error&
e) {
void OnCommand(NmtCommand cs) noexcept override
The default implementation notifies all registered logical device drivers.
void OnSyncError(uint16_t eec, uint8_t er) noexcept override
The default implementation notifies all registered logical device drivers.
void OnCanState(io::CanState new_state, io::CanState old_state) noexcept override
The default implementation notifies all registered logical device drivers.
SdoFuture< void > AsyncDeconfig(int num=0)
Invokes LogicalDriverBase::AsyncDeconfig() for the specified logical device driver.
void OnEmcy(uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept override
The default implementation notifies all registered logical device drivers.
void Insert(LogicalDriverBase &driver)
Registers a logical device driver for the remote node.
SdoFuture< void > AsyncConfig(int num=0)
Invokes LogicalDriverBase::AsyncConfig() for the specified logical device driver.
void OnState(NmtState st) noexcept override
The default implementation notifies all registered logical device drivers.
void Erase(LogicalDriverBase &driver)
Unregisters a logical device driver for the remote node.
void OnSync(uint8_t cnt, const time_point &t) noexcept override
The default implementation notifies all registered logical device drivers.
ev::Executor GetExecutor() const noexcept final
Returns the executor used to execute event handlers for this driver, including SDO confirmation funct...
void OnHeartbeat(bool occurred) noexcept override
The default implementation notifies all registered logical device drivers.
void OnNodeGuarding(bool occurred) noexcept override
The default implementation notifies all registered logical device drivers.
BasicDriver(ev_exec_t *exec, BasicMaster &master, uint8_t id)
Creates a new driver for a remote CANopen node and registers it with the master.
void OnConfig(::std::function< void(::std::error_code ec)> res) noexcept override
The default implementation invokes AsyncConfig() to start the configuration process for all registere...
void OnRpdoWrite(uint16_t idx, uint8_t subidx) noexcept override
The default implementation notifies all registered logical device drivers, unless the object index is...
void OnBoot(NmtState st, char es, const ::std::string &what) noexcept override
The default implementation notifies all registered logical device drivers.
void OnTime(const ::std::chrono::system_clock::time_point &abs_time) noexcept override
The default implementation notifies all registered logical device drivers.
void OnCanError(io::CanError error) noexcept override
The default implementation notifies all registered logical device drivers.
BasicMaster & master
A reference to the master with which this driver is registered.
void Erase(DriverBase &driver)
Unregisters a driver for a remote CANopen node.
void Insert(DriverBase &driver)
Registers a driver for a remote CANopen node.
virtual uint8_t id() const noexcept=0
Returns the node-ID.
The abstract driver interface for a logical device on a remote CANopen node.
virtual int Number() const noexcept=0
Returns the number of the logical device on the remote node.
The type of objects thrown as exceptions to report a system error with an associated error code.
This is the internal header file of the C++ CANopen application library.
This header file is part of the C++ CANopen application library; it contains the remote node driver i...
CanError
The error flags of a CAN bus, which are not mutually exclusive.
CanState
The states of a CAN node, depending on the TX/RX error count.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
SdoFuture< void > make_empty_sdo_future()
Returns an SDO future with a shared state that is immediately ready, containing a successful result o...
NmtCommand
The NMT command specifiers.