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 
28 namespace lely {
29 
30 // The CANopen NMT node service from <lely/co/nmt.hpp>.
31 class CONMT;
32 
33 namespace canopen {
34 
36 enum class NmtCommand {
38  START = 0x01,
40  STOP = 0x02,
42  ENTER_PREOP = 0x80,
44  RESET_NODE = 0x81,
46  RESET_COMM = 0x82
47 };
48 
50 enum 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 
67 constexpr NmtState operator&(NmtState lhs, NmtState rhs) {
68  return static_cast<NmtState>(static_cast<int>(lhs) & static_cast<int>(rhs));
69 }
70 
71 constexpr NmtState
72 operator|(NmtState lhs, NmtState rhs) {
73  return static_cast<NmtState>(static_cast<int>(lhs) | static_cast<int>(rhs));
74 }
75 
76 constexpr NmtState
77 operator^(NmtState lhs, NmtState rhs) {
78  return static_cast<NmtState>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
79 }
80 
81 constexpr NmtState
82 operator~(NmtState lhs) {
83  return static_cast<NmtState>(~static_cast<int>(lhs));
84 }
85 
86 inline NmtState&
87 operator&=(NmtState& lhs, NmtState rhs) noexcept {
88  return lhs = lhs & rhs;
89 }
90 
91 inline NmtState&
92 operator|=(NmtState& lhs, NmtState rhs) noexcept {
93  return lhs = lhs | rhs;
94 }
95 
96 inline NmtState&
97 operator^=(NmtState& lhs, NmtState rhs) noexcept {
98  return lhs = lhs ^ rhs;
99 }
100 
109 class 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
193 
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_
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 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
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
This header file is part of the C++ CANopen application library; it contains the CANopen device descr...
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
NmtCommand
The NMT command specifiers.
Definition: node.hpp:36
CONMT * nmt() const noexcept
Returns a pointer to the internal CANopen NMT master/slave service from <lely/co/nmt.hpp>.
Definition: node.cpp:137
virtual void unlock() final override
Releases the lock held by the execution agent. Throws no exceptions.
Definition: node.cpp:118
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
void OnCanState(CanState new_state, CanState old_state) noexcept override
Implements the default behavior for a CAN bus state change.
Definition: node.cpp:123
Node(aio::TimerBase &timer, aio::CanBusBase &bus, const ::std::string &dcf_txt, const ::std::string &dcf_bin="", uint8_t id=0xff)
Creates a new CANopen node.
Definition: node.cpp:93
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
The mask to get/set the toggle bit from an NMT state.
This header file is part of the C++ CANopen application library; it contains the I/O context declarat...
virtual void OnCommand(NmtCommand cs) noexcept
The function invoked when an NMT command is received from the master.
Definition: node.hpp:201
An abstract interface conforming to the BasicLockable concept.
Definition: coapp.hpp:40
void Reset()
(Re)starts the node.
Definition: node.cpp:103
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
void RpdoRtr(int num=0)
Requests the transmission of a PDO.
Definition: node.cpp:147
NmtState
The NMT states.
Definition: node.hpp:50
An opaque CANopen NMT master/slave service type.
Definition: nmt.hpp:70
virtual void lock() final override
Blocks until a lock can be obtained for the current execution agent (thread, process, task).
Definition: node.cpp:114
The CANopen device description.
Definition: device.hpp:42
Global namespace for the Lely Industries N.V. libraries.
Definition: buf.hpp:32
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
The base class for CANopen nodes.
Definition: node.hpp:109
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
The I/O context.
Definition: io_context.hpp:42
void TpdoEvent(int num=0)
Triggers the transmission of an event-driven (asynchronous) PDO.
Definition: node.cpp:156