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 {
42  ERR = IO_CAN_BUS_FLAG_ERR,
43 #if !LELY_NO_CANFD
44  FDF = IO_CAN_BUS_FLAG_FDF,
47  BRS = IO_CAN_BUS_FLAG_BRS,
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
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
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_
lely::io::CanChannelBase::submit_write
void submit_write(const can_msg &msg, ev_exec_t *exec, F &&f)
Definition: can.hpp:554
io_can_chan_abort_read
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
lely::io::CanChannelWrite::CanChannelWrite
CanChannelWrite(const can_msg &msg, ev_exec_t *exec, F &&f)
Constructs a write operation with a completion task.
Definition: can.hpp:248
lely::io::CanControllerBase::get_state
CanState get_state(::std::error_code &ec) const noexcept
Definition: can.hpp:399
io_can_ctrl_restart
int io_can_ctrl_restart(io_can_ctrl_t *ctrl)
(Re)starts a CAN contoller.
Definition: can.h:421
dev.hpp
lely::io::CanChannelBase::submit_write
void submit_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:547
ev_exec_t
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
lely::io::CanChannelBase::cancel_read
bool cancel_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:499
io_can_chan_read_from_task
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
lely::io::CanControllerBase::get_bitrate
void get_bitrate(int *pnominal, int *pdata=nullptr) const
Definition: can.hpp:371
lely::io::CanControllerBase::stop
void stop()
Definition: can.hpp:306
IO_CAN_BUS_FLAG_ERR
@ IO_CAN_BUS_FLAG_ERR
Reception of error frames is enabled.
Definition: can.h:39
lely::io::CanChannelBase::write
void write(const can_msg &msg, int timeout=-1)
Definition: can.hpp:539
lely::io::detail::CanChannelWriteWrapper
Definition: can.hpp:198
io_can_chan_get_flags
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
lely::io::CanChannelBase::async_write
ev::Future< void, int > async_write(const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
Definition: can.hpp:589
can_msg
A CAN or CAN FD format frame.
Definition: msg.h:87
io_can_chan_write::task
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the write operation.
Definition: can.h:121
lely::io::CanChannelBase::async_read
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
lely::io::CanChannelRead::CanChannelRead
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
io_can_chan_read
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
io_can_chan_async_write
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
get_errc
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
lely::io::CanChannelBase
A reference to an abstract CAN channel.
Definition: can.hpp:430
can_err
A CAN error frame.
Definition: err.h:28
lely::io::CanBusFlag
CanBusFlag
The CAN bus flags.
Definition: can.hpp:40
io_can_chan_read
A CAN channel read operation.
Definition: can.h:74
IO_CAN_CHAN_READ_INIT
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
Definition: can.h:104
io_can_chan_submit_write
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
lely::io::CanState
CanState
The states of a CAN node, depending on the TX/RX error count.
Definition: err.hpp:33
io_can_chan_read::msg
struct can_msg * msg
The address at which to store the CAN frame.
Definition: can.h:80
IO_CAN_BUS_FLAG_FDF
@ IO_CAN_BUS_FLAG_FDF
FD Format (formerly Extended Data Length) support is enabled.
Definition: can.h:42
lely::io::CanChannelWrite::get_executor
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can.hpp:274
lely::io::CanControllerBase::stop
void stop(::std::error_code &ec) noexcept
Definition: can.hpp:294
io_can_chan_write
A CAN channel write operation.
Definition: can.h:110
lely::io::CanControllerBase::stopped
bool stopped() const
Definition: can.hpp:330
io_can_chan_t
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
Definition: can.h:59
io_can_ctrl_get_bitrate
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
io_can_chan_write::msg
const struct can_msg * msg
A pointer to the CAN frame to be written.
Definition: can.h:116
lely::io::CanChannelBase::submit_write
void submit_write(const can_msg &msg, F &&f)
Definition: can.hpp:562
lely::io::Device
An abstract I/O device. This class is a wrapper around #io_dev_t*.
Definition: dev.hpp:35
chrono.hpp
set_errc
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
lely::io::CanControllerBase::get_state
CanState get_state() const
Definition: can.hpp:415
lely::ev::Executor
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
lely::io::CanControllerBase::restart
void restart(::std::error_code &ec) noexcept
Definition: can.hpp:339
lely::compat::is_invocable
Determines whether F can be invoked with the arguments Args....
Definition: type_traits.hpp:206
lely::io::CanControllerBase::set_bitrate
void set_bitrate(int nominal, int data, ::std::error_code &ec) noexcept
Definition: can.hpp:379
lely::ev::Future
A future.
Definition: future.hpp:50
lely::io::CanControllerBase::restart
void restart()
Definition: can.hpp:351
IO_CAN_CHAN_WRITE_INIT
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_write.
Definition: can.h:130
io_can_chan_cancel_write
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
lely::io::CanChannelBase::submit_read
void submit_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:476
io_can_chan_get_dev
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
lely::io::CanChannelBase::read
int read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, int timeout, ::std::error_code &ec) noexcept
Definition: can.hpp:449
lely::io::CanChannelBase::submit_read
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
Definition: can.hpp:483
lely::io::CanChannelBase::submit_read
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Definition: can.hpp:492
lely::io::CanChannelRead
A read operation suitable for use with a CAN channel.
Definition: can.hpp:145
msg.hpp
io_can_chan_async_read
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
lely::io::CanChannelBase::write
void write(const can_msg &msg, int timeout, ::std::error_code &ec) noexcept
Definition: can.hpp:527
lely::io::make_can_channel_write_wrapper
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
lely::io::CanChannelBase::get_flags
CanBusFlag get_flags() const
Definition: can.hpp:441
can.h
lely::io::CanControllerBase::stopped
bool stopped(::std::error_code &ec) const noexcept
Definition: can.hpp:314
future.hpp
io_can_chan_cancel_read
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
lely::io::CanControllerBase::get_bitrate
void get_bitrate(int *pnominal, int *pdata, ::std::error_code &ec) const noexcept
Definition: can.hpp:359
IO_CAN_BUS_FLAG_BRS
@ IO_CAN_BUS_FLAG_BRS
Bit Rate Switch support is enabled.
Definition: can.h:44
io_can_chan_read::err
struct can_err * err
The address at which to store the CAN error frame.
Definition: can.h:86
lely::io::CanChannelRead::get_executor
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can.hpp:185
io_can_chan_write_from_task
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
lely::io::make_can_channel_read_wrapper
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
ev_task
An executable task.
Definition: task.h:41
io_can_chan_write
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
lely::io::CanControllerBase
A reference to an abstract CAN controller.
Definition: can.hpp:286
err.hpp
lely::io::CanChannelBase::abort_write
bool abort_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:574
lely::io::CanChannelBase::cancel_write
bool cancel_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:568
lely::io::CanControllerBase::set_bitrate
void set_bitrate(int nominal, int data=0)
Definition: can.hpp:391
lely::io::CanChannelBase::async_write
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
lely::io::CanChannelBase::async_read
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
io_dev_t
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
Definition: dev.h:35
io_can_ctrl_stop
int io_can_ctrl_stop(io_can_ctrl_t *ctrl)
Stops a CAN controller.
Definition: can.h:409
lely::io::CanChannelWrite::CanChannelWrite
CanChannelWrite(const can_msg &msg, F &&f)
Constructs a write operation with a completion task.
Definition: can.hpp:263
io_can_ctrl_stopped
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
io_can_chan_read::task
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition: can.h:98
io_can_chan_abort_write
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
io_can_ctrl_set_bitrate
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
lely::canopen::make_error_code
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
lely::io::CanChannelRead::CanChannelRead
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
lely::io::CanChannelBase::abort_read
bool abort_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:505
lely::io::detail::CanChannelReadWrapper
Definition: can.hpp:91
ev_task::exec
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
Definition: task.h:43
lely::io::CanChannelWrite
A write operation suitable for use with a CAN channel.
Definition: can.hpp:242
io_can_ctrl_get_state
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
io_can_chan_submit_read
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
io_can_ctrl_t
const struct io_can_ctrl_vtbl *const io_can_ctrl_t
An abstract CAN controller.
Definition: can.h:56
lely::io::CanChannelBase::read
bool read(can_msg *msg, can_err *err=nullptr, ::std::chrono::nanoseconds *dp=nullptr, int timeout=-1)
Definition: can.hpp:466