Lely core libraries 1.9.2
node.hpp
Go to the documentation of this file.
1
22#ifndef LELY_COAPP_NODE_HPP_
23#define LELY_COAPP_NODE_HPP_
24
25#include <lely/coapp/device.hpp>
27
28namespace lely {
29
30// The CANopen NMT node service from <lely/co/nmt.hpp>.
31class CONMT;
32
33namespace canopen {
34
36enum class NmtCommand {
38 START = 0x01,
40 STOP = 0x02,
42 ENTER_PREOP = 0x80,
44 RESET_NODE = 0x81,
46 RESET_COMM = 0x82
47};
48
50enum class NmtState {
52 BOOTUP = 0x00,
54 STOP = 0x04,
56 START = 0x05,
58 RESET_NODE = 0x06,
60 RESET_COMM = 0x07,
62 PREOP = 0x7f,
64 TOGGLE = 0x80
65};
66
67constexpr NmtState operator&(NmtState lhs, NmtState rhs) {
68 return static_cast<NmtState>(static_cast<int>(lhs) & static_cast<int>(rhs));
69}
70
71constexpr NmtState
72operator|(NmtState lhs, NmtState rhs) {
73 return static_cast<NmtState>(static_cast<int>(lhs) | static_cast<int>(rhs));
74}
75
76constexpr NmtState
77operator^(NmtState lhs, NmtState rhs) {
78 return static_cast<NmtState>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
79}
80
81constexpr NmtState
82operator~(NmtState lhs) {
83 return static_cast<NmtState>(~static_cast<int>(lhs));
84}
85
86inline NmtState&
87operator&=(NmtState& lhs, NmtState rhs) noexcept {
88 return lhs = lhs & rhs;
89}
90
91inline NmtState&
92operator|=(NmtState& lhs, NmtState rhs) noexcept {
93 return lhs = lhs | rhs;
94}
95
96inline NmtState&
97operator^=(NmtState& lhs, NmtState rhs) noexcept {
98 return lhs = lhs ^ rhs;
99}
100
109class Node : protected BasicLockable, public IoContext, public Device {
110 public:
111 using time_point = ::std::chrono::steady_clock::time_point;
112
128 Node(aio::TimerBase& timer, aio::CanBusBase& bus,
129 const ::std::string& dcf_txt, const ::std::string& dcf_bin = "",
130 uint8_t id = 0xff);
131
132 Node(const Node&) = delete;
133 Node& operator=(const Node&) = delete;
134
135 virtual ~Node();
136
143 void Reset();
144
145 protected:
146 virtual void lock() final override;
147 virtual void unlock() final override;
148
154 void OnCanState(CanState new_state, CanState old_state) noexcept override;
155
160 CONMT* nmt() const noexcept;
161
162 /*
163 * Generates an EMCY error and triggers the error handling behavior according
164 * to object 1029:01 (Error behavior object) in case of a communication error
165 * (emergency error code 0x81xx).
166 *
167 * @param eec the emergency error code.
168 * @param er the error register.
169 * @param msef the manufacturer-specific error code.
170 */
171 void Error(uint16_t eec, uint8_t er, const uint8_t msef[5] = nullptr);
172
178 void RpdoRtr(int num = 0);
179
188 void TpdoEvent(int num = 0);
189
190#ifndef DOXYGEN_SHOULD_SKIP_THIS
191 private:
192#endif
200 virtual void
201 OnCommand(NmtCommand cs) noexcept {
202 (void)cs;
203 }
204
216 virtual void
217 OnHeartbeat(uint8_t id, bool occurred) noexcept {
218 (void)id;
219 (void)occurred;
220 }
221
231 virtual void
232 OnState(uint8_t id, NmtState st) noexcept {
233 (void)id;
234 (void)st;
235 }
236
257 virtual void
258 OnRpdo(int num, ::std::error_code ec, const void* p,
259 ::std::size_t n) noexcept {
260 (void)num;
261 (void)ec;
262 (void)p;
263 (void)n;
264 }
265
279 virtual void
280 OnRpdoError(int num, uint16_t eec, uint8_t er) noexcept {
281 (void)num;
282 Error(eec, er);
283 }
284
304 virtual void
305 OnTpdo(int num, ::std::error_code ec, const void* p,
306 ::std::size_t n) noexcept {
307 (void)num;
308 (void)ec;
309 (void)p;
310 (void)n;
311 }
312
321 virtual void
322 OnSync(uint8_t cnt, const time_point& t) noexcept {
323 (void)cnt;
324 (void)t;
325 }
326
336 virtual void
337 OnSyncError(uint16_t eec, uint8_t er) noexcept {
338 Error(eec, er);
339 }
340
346 virtual void
347 OnTime(const ::std::chrono::system_clock::time_point& abs_time) noexcept {
348 (void)abs_time;
349 }
350
359 virtual void
360 OnEmcy(uint8_t id, uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept {
361 (void)id;
362 (void)eec;
363 (void)er;
364 (void)msef;
365 }
366
367 private:
368 struct Impl_;
369 ::std::unique_ptr<Impl_> impl_;
370};
371
372} // namespace canopen
373
374} // namespace lely
375
376#endif // LELY_COAPP_NODE_HPP_
An opaque CANopen NMT master/slave service type.
Definition: nmt.hpp:70
An abstract interface conforming to the BasicLockable concept.
Definition: coapp.hpp:40
The CANopen device description.
Definition: device.hpp:42
The I/O context.
Definition: io_context.hpp:42
The base class for CANopen nodes.
Definition: node.hpp:109
void Reset()
(Re)starts the node.
Definition: node.cpp:103
void OnCanState(CanState new_state, CanState old_state) noexcept override
Implements the default behavior for a CAN bus state change.
Definition: node.cpp:123
virtual void OnTime(const ::std::chrono::system_clock::time_point &abs_time) noexcept
The function invoked when a TIME message is received.
Definition: node.hpp:347
virtual void OnRpdo(int num, ::std::error_code ec, const void *p, ::std::size_t n) noexcept
The function invoked when a Receive-PDO is processed.
Definition: node.hpp:258
virtual void OnCommand(NmtCommand cs) noexcept
The function invoked when an NMT command is received from the master.
Definition: node.hpp:201
virtual void OnRpdoError(int num, uint16_t eec, uint8_t er) noexcept
The function invoked when a Receive-PDO length mismatch or timeout error occurs.
Definition: node.hpp:280
virtual void OnTpdo(int num, ::std::error_code ec, const void *p, ::std::size_t n) noexcept
The function invoked after a Transmit-PDO is sent or an error occurs.
Definition: node.hpp:305
void TpdoEvent(int num=0)
Triggers the transmission of an event-driven (asynchronous) PDO.
Definition: node.cpp:156
CONMT * nmt() const noexcept
Returns a pointer to the internal CANopen NMT master/slave service from <lely/co/nmt....
Definition: node.cpp:137
virtual void OnSyncError(uint16_t eec, uint8_t er) noexcept
The function invoked when the data length of a received SYNC message does not match.
Definition: node.hpp:337
virtual void OnSync(uint8_t cnt, const time_point &t) noexcept
The function invoked when a SYNC message is sent/received.
Definition: node.hpp:322
virtual void OnEmcy(uint8_t id, uint16_t eec, uint8_t er, uint8_t msef[5]) noexcept
The function invoked when an EMCY message is received.
Definition: node.hpp:360
virtual void OnHeartbeat(uint8_t id, bool occurred) noexcept
The function invoked when a heartbeat timeout event occurs or is resolved.
Definition: node.hpp:217
void RpdoRtr(int num=0)
Requests the transmission of a PDO.
Definition: node.cpp:147
virtual void unlock() final override
Releases the lock held by the execution agent. Throws no exceptions.
Definition: node.cpp:118
virtual void OnState(uint8_t id, NmtState st) noexcept
The function invoked when an NMT state change or boot-up event is detected for a remote node by the h...
Definition: node.hpp:232
virtual void lock() final override
Blocks until a lock can be obtained for the current execution agent (thread, process,...
Definition: node.cpp:114
This header file is part of the C++ CANopen application library; it contains the CANopen device descr...
This header file is part of the C++ CANopen application library; it contains the I/O context declarat...
NmtState
The NMT states.
Definition: node.hpp:50
@ TOGGLE
The mask to get/set the toggle bit from an NMT state.
@ PREOP
Pre-operational.
NmtCommand
The NMT command specifiers.
Definition: node.hpp:36
@ ENTER_PREOP
Enter pre-operational.
@ RESET_COMM
Reset communication.
Global namespace for the Lely Industries N.V. libraries.
Definition: buf.hpp:32