Lely core libraries  2.3.4
can.hpp
Go to the documentation of this file.
1 
24 #ifndef LELY_IO2_CAN_HPP_
25 #define LELY_IO2_CAN_HPP_
26 
27 #include <lely/ev/future.hpp>
28 #include <lely/io2/can/err.hpp>
29 #include <lely/io2/can/msg.hpp>
30 #include <lely/io2/can.h>
31 #include <lely/io2/dev.hpp>
32 #include <lely/util/chrono.hpp>
33 
34 #include <utility>
35 
36 namespace lely {
37 namespace io {
38 
40 enum class CanBusFlag : int {
43 #if !LELY_NO_CANFD
48 #endif
49  NONE = IO_CAN_BUS_FLAG_NONE,
50  MASK = IO_CAN_BUS_FLAG_MASK
51 };
52 
53 constexpr CanBusFlag
54 operator~(CanBusFlag rhs) {
55  return static_cast<CanBusFlag>(~static_cast<int>(rhs));
56 }
57 
58 constexpr CanBusFlag
59 operator&(CanBusFlag lhs, CanBusFlag rhs) {
60  return static_cast<CanBusFlag>(static_cast<int>(lhs) & static_cast<int>(rhs));
61 }
62 
63 constexpr CanBusFlag
64 operator^(CanBusFlag lhs, CanBusFlag rhs) {
65  return static_cast<CanBusFlag>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
66 }
67 
68 constexpr CanBusFlag
69 operator|(CanBusFlag lhs, CanBusFlag rhs) {
70  return static_cast<CanBusFlag>(static_cast<int>(lhs) | static_cast<int>(rhs));
71 }
72 
73 inline CanBusFlag&
74 operator&=(CanBusFlag& lhs, CanBusFlag rhs) {
75  return lhs = lhs & rhs;
76 }
77 
78 inline CanBusFlag&
79 operator^=(CanBusFlag& lhs, CanBusFlag rhs) {
80  return lhs = lhs ^ rhs;
81 }
82 
83 inline CanBusFlag&
84 operator|=(CanBusFlag& lhs, CanBusFlag rhs) {
85  return lhs = lhs | rhs;
86 }
87 
88 namespace detail {
89 
90 template <class F>
92  public:
94  ::std::chrono::nanoseconds* dp, ev_exec_t* exec, F&& f)
96  msg, err, dp ? &ts_ : nullptr, exec,
97  [](ev_task* task) noexcept {
98  auto read = io_can_chan_read_from_task(task);
99  auto result = read->r.result;
100  ::std::error_code ec;
101  if (result == -1) ec = util::make_error_code(read->r.errc);
102  auto self = static_cast<CanChannelReadWrapper*>(read);
103  if (self->dp_) *self->dp_ = util::from_timespec(self->ts_);
104  compat::invoke(::std::move(self->func_), result, ec);
105  delete self;
106  }),
107  dp_(dp),
108  func_(::std::forward<F>(f)) {}
109 
111 
112  CanChannelReadWrapper& operator=(const CanChannelReadWrapper&) = delete;
113 
114  operator ev_task&() & noexcept { return task; }
115 
116  private:
117  timespec ts_{0, 0};
118  ::std::chrono::nanoseconds* dp_{nullptr};
119  typename ::std::decay<F>::type func_;
120 };
121 
122 } // namespace detail
123 
129 template <class F>
130 inline typename ::std::enable_if<
134  ::std::chrono::nanoseconds* dp, ev_exec_t* exec,
135  F&& f) {
136  return new detail::CanChannelReadWrapper<F>(msg, err, dp, exec,
137  ::std::forward<F>(f));
138 }
139 
146  public:
147  using Signature = void(int, ::std::error_code);
148 
150  template <class F>
151  CanChannelRead(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
152  ev_exec_t* exec, F&& f)
154  IO_CAN_CHAN_READ_INIT(msg, err, dp ? &ts_ : nullptr, exec,
155  [](ev_task* task) noexcept {
156  auto read = io_can_chan_read_from_task(task);
157  auto self = static_cast<CanChannelRead*>(read);
158  if (self->dp_)
159  *self->dp_ = util::from_timespec(self->ts_);
160  if (self->func_) {
161  auto result = read->r.result;
162  ::std::error_code ec;
163  if (result == -1)
164  ec = util::make_error_code(read->r.errc);
165  self->func_(result, ec);
166  }
167  }),
168  dp_(dp),
169  func_(::std::forward<F>(f)) {}
170 
172  template <class F>
173  CanChannelRead(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
174  F&& f)
175  : CanChannelRead(msg, err, dp, nullptr, ::std::forward<F>(f)) {}
176 
177  CanChannelRead(const CanChannelRead&) = delete;
178 
179  CanChannelRead& operator=(const CanChannelRead&) = delete;
180 
181  operator ev_task&() & noexcept { return task; }
182 
185  get_executor() const noexcept {
186  return ev::Executor(task.exec);
187  }
188 
189  private:
190  timespec ts_{0, 0};
191  ::std::chrono::nanoseconds* dp_{nullptr};
192  ::std::function<Signature> func_;
193 };
194 
195 namespace detail {
196 
197 template <class F>
199  public:
200  CanChannelWriteWrapper(const can_msg& msg, ev_exec_t* exec, F&& f)
202  &msg, exec,
203  [](ev_task* task) noexcept {
204  auto write = io_can_chan_write_from_task(task);
205  ::std::error_code ec = util::make_error_code(write->errc);
206  auto self = static_cast<CanChannelWriteWrapper*>(write);
207  compat::invoke(::std::move(self->func_), ec);
208  delete self;
209  }),
210  func_(::std::forward<F>(f)) {}
211 
213 
214  CanChannelWriteWrapper& operator=(const CanChannelWriteWrapper&) = delete;
215 
216  private:
217  typename ::std::decay<F>::type func_;
218 };
219 
220 } // namespace detail
221 
227 template <class F>
228 // clang-format off
229 inline typename ::std::enable_if<
233  // clang-format on
234  return new detail::CanChannelWriteWrapper<F>(msg, exec, ::std::forward<F>(f));
235 }
236 
243  public:
244  using Signature = void(::std::error_code);
245 
247  template <class F>
248  CanChannelWrite(const can_msg& msg, ev_exec_t* exec, F&& f)
250  &msg, exec,
251  [](ev_task* task) noexcept {
252  auto write = io_can_chan_write_from_task(task);
253  auto self = static_cast<CanChannelWrite*>(write);
254  if (self->func_) {
255  ::std::error_code ec = util::make_error_code(write->errc);
256  self->func_(ec);
257  }
258  }),
259  func_(::std::forward<F>(f)) {}
260 
262  template <class F>
263  CanChannelWrite(const can_msg& msg, F&& f)
264  : CanChannelWrite(msg, nullptr, ::std::forward<F>(f)) {}
265 
266  CanChannelWrite(const CanChannelWrite&) = delete;
267 
268  CanChannelWrite& operator=(const CanChannelWrite&) = delete;
269 
270  operator ev_task&() & noexcept { return task; }
271 
274  get_executor() const noexcept {
275  return ev::Executor(task.exec);
276  }
277 
278  private:
279  ::std::function<Signature> func_;
280 };
281 
287  public:
288  explicit CanControllerBase(io_can_ctrl_t* ctrl_) noexcept : ctrl(ctrl_) {}
289 
290  operator io_can_ctrl_t*() const noexcept { return ctrl; }
291 
293  void
294  stop(::std::error_code& ec) noexcept {
295  int errsv = get_errc();
296  set_errc(0);
297  if (!io_can_ctrl_stop(*this))
298  ec.clear();
299  else
300  ec = util::make_error_code();
301  set_errc(errsv);
302  }
303 
305  void
306  stop() {
307  ::std::error_code ec;
308  stop(ec);
309  if (ec) throw ::std::system_error(ec, "stop");
310  }
311 
313  bool
314  stopped(::std::error_code& ec) const noexcept {
315  int errsv = get_errc();
316  set_errc(0);
317  int stopped = io_can_ctrl_stopped(*this);
318  if (stopped >= 0) {
319  ec.clear();
320  } else {
321  ec = util::make_error_code();
322  stopped = 0;
323  }
324  set_errc(errsv);
325  return stopped != 0;
326  }
327 
329  bool
330  stopped() const {
331  ::std::error_code ec;
332  auto result = stopped(ec);
333  if (ec) throw ::std::system_error(ec, "stopped");
334  return result;
335  }
336 
338  void
339  restart(::std::error_code& ec) noexcept {
340  int errsv = get_errc();
341  set_errc(0);
342  if (!io_can_ctrl_restart(*this))
343  ec.clear();
344  else
345  ec = util::make_error_code();
346  set_errc(errsv);
347  }
348 
350  void
352  ::std::error_code ec;
353  restart(ec);
354  if (ec) throw ::std::system_error(ec, "restart");
355  }
356 
358  void
359  get_bitrate(int* pnominal, int* pdata, ::std::error_code& ec) const noexcept {
360  int errsv = get_errc();
361  set_errc(0);
362  if (!io_can_ctrl_get_bitrate(*this, pnominal, pdata))
363  ec.clear();
364  else
365  ec = util::make_error_code();
366  set_errc(errsv);
367  }
368 
370  void
371  get_bitrate(int* pnominal, int* pdata = nullptr) const {
372  ::std::error_code ec;
373  get_bitrate(pnominal, pdata, ec);
374  if (ec) throw ::std::system_error(ec, "get_bitrate");
375  }
376 
378  void
379  set_bitrate(int nominal, int data, ::std::error_code& ec) noexcept {
380  int errsv = get_errc();
381  set_errc(0);
382  if (!io_can_ctrl_set_bitrate(*this, nominal, data))
383  ec.clear();
384  else
385  ec = util::make_error_code();
386  set_errc(errsv);
387  }
388 
390  void
391  set_bitrate(int nominal, int data = 0) {
392  ::std::error_code ec;
393  set_bitrate(nominal, data, ec);
394  if (ec) throw ::std::system_error(ec, "set_bitrate");
395  }
396 
398  CanState
399  get_state(::std::error_code& ec) const noexcept {
400  int errsv = get_errc();
401  set_errc(0);
402  int state = io_can_ctrl_get_state(*this);
403  if (state >= 0) {
404  ec.clear();
405  } else {
406  ec = util::make_error_code();
407  state = 0;
408  }
409  set_errc(errsv);
410  return static_cast<CanState>(state);
411  }
412 
414  CanState
415  get_state() const {
416  ::std::error_code ec;
417  auto result = get_state(ec);
418  if (ec) throw ::std::system_error(ec, "get_state");
419  return result;
420  }
421 
422  protected:
423  io_can_ctrl_t* ctrl{nullptr};
424 };
425 
430 class CanChannelBase : public Device {
431  public:
432  using Device::operator io_dev_t*;
433 
434  explicit CanChannelBase(io_can_chan_t* chan_) noexcept
435  : Device(chan_ ? io_can_chan_get_dev(chan_) : nullptr), chan(chan_) {}
436 
437  operator io_can_chan_t*() const noexcept { return chan; }
438 
440  CanBusFlag
441  get_flags() const {
442  int flags = io_can_chan_get_flags(*this);
443  if (flags == -1) util::throw_errc("get_flags");
444  return static_cast<CanBusFlag>(flags);
445  }
446 
448  int
449  read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp, int timeout,
450  ::std::error_code& ec) noexcept {
451  int errsv = get_errc();
452  set_errc(0);
453  timespec ts = {0, 0};
454  int result = io_can_chan_read(*this, msg, err, dp ? &ts : nullptr, timeout);
455  if (result >= 0)
456  ec.clear();
457  else
458  ec = util::make_error_code();
459  if (dp) *dp = util::from_timespec(ts);
460  set_errc(errsv);
461  return result;
462  }
463 
465  bool
466  read(can_msg* msg, can_err* err = nullptr,
467  ::std::chrono::nanoseconds* dp = nullptr, int timeout = -1) {
468  ::std::error_code ec;
469  int result = read(msg, err, dp, timeout, ec);
470  if (result < 0) throw ::std::system_error(ec, "read");
471  return result > 0;
472  }
473 
475  void
476  submit_read(struct io_can_chan_read& read) noexcept {
477  io_can_chan_submit_read(*this, &read);
478  }
479 
481  template <class F>
482  void
483  submit_read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
484  ev_exec_t* exec, F&& f) {
485  submit_read(*make_can_channel_read_wrapper(msg, err, dp, exec,
486  ::std::forward<F>(f)));
487  }
488 
490  template <class F>
491  void
492  submit_read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
493  F&& f) {
494  submit_read(msg, err, dp, nullptr, ::std::forward<F>(f));
495  }
496 
498  bool
499  cancel_read(struct io_can_chan_read& read) noexcept {
500  return io_can_chan_cancel_read(*this, &read) != 0;
501  }
502 
504  bool
505  abort_read(struct io_can_chan_read& read) noexcept {
506  return io_can_chan_abort_read(*this, &read) != 0;
507  }
508 
511  async_read(ev_exec_t* exec, can_msg* msg, can_err* err = nullptr,
512  timespec* tp = nullptr,
513  struct io_can_chan_read** pread = nullptr) {
514  return ev::Future<int, int>(
515  io_can_chan_async_read(*this, exec, msg, err, tp, pread));
516  }
517 
520  async_read(can_msg* msg, can_err* err = nullptr, timespec* tp = nullptr,
521  struct io_can_chan_read** pread = nullptr) {
522  return async_read(nullptr, msg, err, tp, pread);
523  }
524 
526  void
527  write(const can_msg& msg, int timeout, ::std::error_code& ec) noexcept {
528  int errsv = get_errc();
529  set_errc(0);
530  if (!io_can_chan_write(*this, &msg, timeout))
531  ec.clear();
532  else
533  ec = util::make_error_code();
534  set_errc(errsv);
535  }
536 
538  void
539  write(const can_msg& msg, int timeout = -1) {
540  ::std::error_code ec;
541  write(msg, timeout, ec);
542  if (ec) throw ::std::system_error(ec, "write");
543  }
544 
546  void
547  submit_write(struct io_can_chan_write& write) noexcept {
548  io_can_chan_submit_write(*this, &write);
549  }
550 
552  template <class F>
553  void
554  submit_write(const can_msg& msg, ev_exec_t* exec, F&& f) {
555  submit_write(
556  *make_can_channel_write_wrapper(msg, exec, ::std::forward<F>(f)));
557  }
558 
560  template <class F>
561  void
562  submit_write(const can_msg& msg, F&& f) {
563  submit_write(msg, nullptr, ::std::forward<F>(f));
564  }
565 
567  bool
568  cancel_write(struct io_can_chan_write& write) noexcept {
569  return io_can_chan_cancel_write(*this, &write) != 0;
570  }
571 
573  bool
574  abort_write(struct io_can_chan_write& write) noexcept {
575  return io_can_chan_abort_write(*this, &write) != 0;
576  }
577 
580  async_write(ev_exec_t* exec, const can_msg& msg,
581  struct io_can_chan_write** pwrite = nullptr) {
582  auto future = io_can_chan_async_write(*this, exec, &msg, pwrite);
583  if (!future) util::throw_errc("async_write");
584  return ev::Future<void, int>(future);
585  }
586 
589  async_write(const can_msg& msg, struct io_can_chan_write** pwrite = nullptr) {
590  return async_write(nullptr, msg, pwrite);
591  }
592 
593  protected:
594  io_can_chan_t* chan{nullptr};
595 };
596 
597 } // namespace io
598 } // namespace lely
599 
600 #endif // !LELY_IO2_CAN_HPP_
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
A future.
Definition: future.hpp:384
A reference to an abstract CAN channel.
Definition: can.hpp:430
void submit_write(const can_msg &msg, ev_exec_t *exec, F &&f)
Definition: can.hpp:554
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Definition: can.hpp:483
bool read(can_msg *msg, can_err *err=nullptr, ::std::chrono::nanoseconds *dp=nullptr, int timeout=-1)
Definition: can.hpp:466
CanBusFlag get_flags() const
Definition: can.hpp:441
ev::Future< int, int > async_read(ev_exec_t *exec, can_msg *msg, can_err *err=nullptr, timespec *tp=nullptr, struct io_can_chan_read **pread=nullptr)
Definition: can.hpp:511
void write(const can_msg &msg, int timeout=-1)
Definition: can.hpp:539
ev::Future< void, int > async_write(const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
Definition: can.hpp:589
void submit_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:476
void submit_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:547
ev::Future< int, int > async_read(can_msg *msg, can_err *err=nullptr, timespec *tp=nullptr, struct io_can_chan_read **pread=nullptr)
Definition: can.hpp:520
bool abort_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:505
bool abort_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:574
void write(const can_msg &msg, int timeout, ::std::error_code &ec) noexcept
Definition: can.hpp:527
ev::Future< void, int > async_write(ev_exec_t *exec, const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
Definition: can.hpp:580
void submit_write(const can_msg &msg, F &&f)
Definition: can.hpp:562
int read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, int timeout, ::std::error_code &ec) noexcept
Definition: can.hpp:449
bool cancel_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:499
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Definition: can.hpp:492
bool cancel_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:568
A read operation suitable for use with a CAN channel.
Definition: can.hpp:145
CanChannelRead(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Constructs a read operation with a completion task.
Definition: can.hpp:151
CanChannelRead(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Constructs a read operation with a completion task.
Definition: can.hpp:173
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can.hpp:185
A write operation suitable for use with a CAN channel.
Definition: can.hpp:242
CanChannelWrite(const can_msg &msg, F &&f)
Constructs a write operation with a completion task.
Definition: can.hpp:263
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can.hpp:274
CanChannelWrite(const can_msg &msg, ev_exec_t *exec, F &&f)
Constructs a write operation with a completion task.
Definition: can.hpp:248
A reference to an abstract CAN controller.
Definition: can.hpp:286
CanState get_state() const
Definition: can.hpp:415
void stop(::std::error_code &ec) noexcept
Definition: can.hpp:294
void set_bitrate(int nominal, int data=0)
Definition: can.hpp:391
bool stopped(::std::error_code &ec) const noexcept
Definition: can.hpp:314
void set_bitrate(int nominal, int data, ::std::error_code &ec) noexcept
Definition: can.hpp:379
void get_bitrate(int *pnominal, int *pdata, ::std::error_code &ec) const noexcept
Definition: can.hpp:359
CanState get_state(::std::error_code &ec) const noexcept
Definition: can.hpp:399
void restart(::std::error_code &ec) noexcept
Definition: can.hpp:339
void get_bitrate(int *pnominal, int *pdata=nullptr) const
Definition: can.hpp:371
bool stopped() const
Definition: can.hpp:330
An abstract I/O device. This class is a wrapper around #io_dev_t*.
Definition: dev.hpp:35
This header file is part of the I/O library; it contains the C++ CAN bus error definitions.
CanState
The states of a CAN node, depending on the TX/RX error count.
Definition: err.hpp:33
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
This header file is part of the event library; it contains the C++ interface for the futures and prom...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
This header file is part of the I/O library; it contains the abstract CAN bus interface.
struct io_can_chan_write * io_can_chan_write_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel write operation from a pointer to its completion task.
Definition: can.c:99
int io_can_ctrl_stopped(const io_can_ctrl_t *ctrl)
Returns 1 in the CAN controller is stopped, 0 if not, and -1 on error.
Definition: can.h:415
int io_can_chan_write(io_can_chan_t *chan, const struct can_msg *msg, int timeout)
Writes a CAN frame to a CAN channel.
Definition: can.h:506
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
Definition: can.h:59
static size_t io_can_chan_abort_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Aborts the specified CAN channel write operation if it is pending.
Definition: can.h:524
struct io_can_chan_read * io_can_chan_read_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel read operation from a pointer to its completion task.
Definition: can.c:93
static size_t io_can_chan_abort_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Aborts the specified CAN channel read operation if it is pending.
Definition: can.h:500
const struct io_can_ctrl_vtbl *const io_can_ctrl_t
An abstract CAN controller.
Definition: can.h:56
static size_t io_can_chan_cancel_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Cancels the specified CAN channel read operation if it is pending.
Definition: can.h:494
io_dev_t * io_can_chan_get_dev(const io_can_chan_t *chan)
Returns a pointer to the abstract I/O device representing the CAN channel.
Definition: can.h:469
void io_can_chan_submit_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Submits a write operation to a CAN channel.
Definition: can.h:512
int io_can_ctrl_get_state(const io_can_ctrl_t *ctrl)
Returns the state of the CAN controller: one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE,...
Definition: can.h:439
int io_can_ctrl_stop(io_can_ctrl_t *ctrl)
Stops a CAN controller.
Definition: can.h:409
void io_can_chan_submit_read(io_can_chan_t *chan, struct io_can_chan_read *read)
Submits a read operation to a CAN channel.
Definition: can.h:488
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_write.
Definition: can.h:130
int io_can_chan_get_flags(const io_can_chan_t *chan)
Returns the flafs of the CAN bus: any combination of IO_CAN_BUS_FLAG_ERR, IO_CAN_BUS_FLAG_FDF and IO_...
Definition: can.h:475
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
Definition: can.h:104
int io_can_ctrl_set_bitrate(io_can_ctrl_t *ctrl, int nominal, int data)
Configures the bitrate(s) of a CAN controller.
Definition: can.h:433
ev_future_t * io_can_chan_async_read(io_can_chan_t *chan, ev_exec_t *exec, struct can_msg *msg, struct can_err *err, struct timespec *tp, struct io_can_chan_read **pread)
Submits an asynchronous read operation to a CAN channel and creates a future which becomes ready once...
Definition: can.c:46
ev_future_t * io_can_chan_async_write(io_can_chan_t *chan, ev_exec_t *exec, const struct can_msg *msg, struct io_can_chan_write **pwrite)
Submits an asynchronous write operation to a CAN channel and creates a future which becomes ready onc...
Definition: can.c:70
@ IO_CAN_BUS_FLAG_BRS
Bit Rate Switch support is enabled.
Definition: can.h:44
@ IO_CAN_BUS_FLAG_FDF
FD Format (formerly Extended Data Length) support is enabled.
Definition: can.h:42
@ IO_CAN_BUS_FLAG_ERR
Reception of error frames is enabled.
Definition: can.h:39
int io_can_chan_read(io_can_chan_t *chan, struct can_msg *msg, struct can_err *err, struct timespec *tp, int timeout)
Reads a CAN frame or CAN error frame from a CAN channel.
Definition: can.h:481
int io_can_ctrl_get_bitrate(const io_can_ctrl_t *ctrl, int *pnominal, int *pdata)
Obtains the bitrate(s) of a CAN controller.
Definition: can.h:427
int io_can_ctrl_restart(io_can_ctrl_t *ctrl)
(Re)starts a CAN contoller.
Definition: can.h:421
static size_t io_can_chan_cancel_write(io_can_chan_t *chan, struct io_can_chan_write *write)
Cancels the specified CAN channel write operation if it is pending.
Definition: can.h:518
CanBusFlag
The CAN bus flags.
Definition: can.hpp:40
@ ERR
Reception of error frames is enabled.
typename ::std::enable_if< compat::is_invocable< F, int, ::std::error_code >::value, detail::CanChannelReadWrapper< F > * >::type make_can_channel_read_wrapper(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Creates a CAN channel read operation with a completion task.
Definition: can.hpp:133
typename ::std::enable_if< compat::is_invocable< F, ::std::error_code >::value, detail::CanChannelWriteWrapper< F > * >::type make_can_channel_write_wrapper(const can_msg &msg, ev_exec_t *exec, F &&f)
Creates a CAN channel write operation with a completion task.
Definition: can.hpp:232
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
Definition: dev.h:35
This header file is part of the I/O library; it contains the C++ interface for the abstract I/O devic...
This header file is part of the I/O library; it contains the C++ CAN frame declarations.
@ BRS
The Bit Rate Switch (BRS) flag (only available in CAN FD format frames).
@ FDF
The FD Format (FDF) flag, formerly known as Extended Data Length (EDL).
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
A CAN error frame.
Definition: err.h:28
A CAN or CAN FD format frame.
Definition: msg.h:87
An executable task.
Definition: task.h:41
A CAN channel read operation.
Definition: can.h:74
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition: can.h:98
struct can_msg * msg
The address at which to store the CAN frame.
Definition: can.h:80
struct can_err * err
The address at which to store the CAN error frame.
Definition: can.h:86
A CAN channel write operation.
Definition: can.h:110
Determines whether F can be invoked with the arguments Args....
This header file is part of the utilities library; it contains the time function declarations.