Lely core libraries  2.2.5
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 operator&(CanBusFlag lhs, CanBusFlag rhs) {
59  return static_cast<CanBusFlag>(static_cast<int>(lhs) & static_cast<int>(rhs));
60 }
61 
62 constexpr CanBusFlag
63 operator^(CanBusFlag lhs, CanBusFlag rhs) {
64  return static_cast<CanBusFlag>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
65 }
66 
67 constexpr CanBusFlag
68 operator|(CanBusFlag lhs, CanBusFlag rhs) {
69  return static_cast<CanBusFlag>(static_cast<int>(lhs) | static_cast<int>(rhs));
70 }
71 
72 inline CanBusFlag&
73 operator&=(CanBusFlag& lhs, CanBusFlag rhs) {
74  return lhs = lhs & rhs;
75 }
76 
77 inline CanBusFlag&
78 operator^=(CanBusFlag& lhs, CanBusFlag rhs) {
79  return lhs = lhs ^ rhs;
80 }
81 
82 inline CanBusFlag&
83 operator|=(CanBusFlag& lhs, CanBusFlag rhs) {
84  return lhs = lhs | rhs;
85 }
86 
87 namespace detail {
88 
89 template <class F>
91  public:
93  ::std::chrono::nanoseconds* dp, ev_exec_t* exec, F&& f)
95  msg, err, dp ? &ts_ : nullptr, exec,
96  [](ev_task* task) noexcept {
97  auto read = io_can_chan_read_from_task(task);
98  auto result = read->r.result;
99  ::std::error_code ec;
100  if (result == -1) ec = util::make_error_code(read->r.errc);
101  auto self = static_cast<CanChannelReadWrapper*>(read);
102  if (self->dp_) *self->dp_ = util::from_timespec(self->ts_);
103  compat::invoke(::std::move(self->func_), result, ec);
104  delete self;
105  }),
106  dp_(dp),
107  func_(::std::forward<F>(f)) {}
108 
110 
111  CanChannelReadWrapper& operator=(const CanChannelReadWrapper&) = delete;
112 
113  operator ev_task&() & noexcept { return task; }
114 
115  private:
116  timespec ts_{0, 0};
117  ::std::chrono::nanoseconds* dp_{nullptr};
118  typename ::std::decay<F>::type func_;
119 };
120 
121 } // namespace detail
122 
128 template <class F>
129 inline typename ::std::enable_if<
133  ::std::chrono::nanoseconds* dp, ev_exec_t* exec,
134  F&& f) {
135  return new detail::CanChannelReadWrapper<F>(msg, err, dp, exec,
136  ::std::forward<F>(f));
137 }
138 
145  public:
146  using Signature = void(int, ::std::error_code);
147 
149  template <class F>
150  CanChannelRead(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
151  ev_exec_t* exec, F&& f)
153  IO_CAN_CHAN_READ_INIT(msg, err, dp ? &ts_ : nullptr, exec,
154  [](ev_task* task) noexcept {
155  auto read = io_can_chan_read_from_task(task);
156  auto self = static_cast<CanChannelRead*>(read);
157  if (self->dp_)
158  *self->dp_ = util::from_timespec(self->ts_);
159  if (self->func_) {
160  auto result = read->r.result;
161  ::std::error_code ec;
162  if (result == -1)
163  ec = util::make_error_code(read->r.errc);
164  self->func_(result, ec);
165  }
166  }),
167  dp_(dp),
168  func_(::std::forward<F>(f)) {}
169 
171  template <class F>
172  CanChannelRead(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
173  F&& f)
174  : CanChannelRead(msg, err, dp, nullptr, ::std::forward<F>(f)) {}
175 
176  CanChannelRead(const CanChannelRead&) = delete;
177 
178  CanChannelRead& operator=(const CanChannelRead&) = delete;
179 
180  operator ev_task&() & noexcept { return task; }
181 
184  get_executor() const noexcept {
185  return ev::Executor(task.exec);
186  }
187 
188  private:
189  timespec ts_{0, 0};
190  ::std::chrono::nanoseconds* dp_{nullptr};
191  ::std::function<Signature> func_;
192 };
193 
194 namespace detail {
195 
196 template <class F>
198  public:
199  CanChannelWriteWrapper(const can_msg& msg, ev_exec_t* exec, F&& f)
201  &msg, exec,
202  [](ev_task* task) noexcept {
203  auto write = io_can_chan_write_from_task(task);
204  ::std::error_code ec = util::make_error_code(write->errc);
205  auto self = static_cast<CanChannelWriteWrapper*>(write);
206  compat::invoke(::std::move(self->func_), ec);
207  delete self;
208  }),
209  func_(::std::forward<F>(f)) {}
210 
212 
213  CanChannelWriteWrapper& operator=(const CanChannelWriteWrapper&) = delete;
214 
215  private:
216  typename ::std::decay<F>::type func_;
217 };
218 
219 } // namespace detail
220 
226 template <class F>
227 // clang-format off
228 inline typename ::std::enable_if<
232  // clang-format on
233  return new detail::CanChannelWriteWrapper<F>(msg, exec, ::std::forward<F>(f));
234 }
235 
242  public:
243  using Signature = void(::std::error_code);
244 
246  template <class F>
247  CanChannelWrite(const can_msg& msg, ev_exec_t* exec, F&& f)
249  &msg, exec,
250  [](ev_task* task) noexcept {
251  auto write = io_can_chan_write_from_task(task);
252  auto self = static_cast<CanChannelWrite*>(write);
253  if (self->func_) {
254  ::std::error_code ec = util::make_error_code(write->errc);
255  self->func_(ec);
256  }
257  }),
258  func_(::std::forward<F>(f)) {}
259 
261  template <class F>
262  CanChannelWrite(const can_msg& msg, F&& f)
263  : CanChannelWrite(msg, nullptr, ::std::forward<F>(f)) {}
264 
265  CanChannelWrite(const CanChannelWrite&) = delete;
266 
267  CanChannelWrite& operator=(const CanChannelWrite&) = delete;
268 
269  operator ev_task&() & noexcept { return task; }
270 
273  get_executor() const noexcept {
274  return ev::Executor(task.exec);
275  }
276 
277  private:
278  ::std::function<Signature> func_;
279 };
280 
286  public:
287  explicit CanControllerBase(io_can_ctrl_t* ctrl_) noexcept : ctrl(ctrl_) {}
288 
289  operator io_can_ctrl_t*() const noexcept { return ctrl; }
290 
292  void
293  stop(::std::error_code& ec) noexcept {
294  int errsv = get_errc();
295  set_errc(0);
296  if (!io_can_ctrl_stop(*this))
297  ec.clear();
298  else
299  ec = util::make_error_code();
300  set_errc(errsv);
301  }
302 
304  void
305  stop() {
306  ::std::error_code ec;
307  stop(ec);
308  if (ec) throw ::std::system_error(ec, "stop");
309  }
310 
312  bool
313  stopped(::std::error_code& ec) const noexcept {
314  int errsv = get_errc();
315  set_errc(0);
316  int stopped = io_can_ctrl_stopped(*this);
317  if (stopped >= 0) {
318  ec.clear();
319  } else {
320  ec = util::make_error_code();
321  stopped = 0;
322  }
323  set_errc(errsv);
324  return stopped != 0;
325  }
326 
328  bool
329  stopped() const {
330  ::std::error_code ec;
331  auto result = stopped(ec);
332  if (ec) throw ::std::system_error(ec, "stopped");
333  return result;
334  }
335 
337  void
338  restart(::std::error_code& ec) noexcept {
339  int errsv = get_errc();
340  set_errc(0);
341  if (!io_can_ctrl_restart(*this))
342  ec.clear();
343  else
344  ec = util::make_error_code();
345  set_errc(errsv);
346  }
347 
349  void
351  ::std::error_code ec;
352  restart(ec);
353  if (ec) throw ::std::system_error(ec, "restart");
354  }
355 
357  void
358  get_bitrate(int* pnominal, int* pdata, ::std::error_code& ec) const noexcept {
359  int errsv = get_errc();
360  set_errc(0);
361  if (!io_can_ctrl_get_bitrate(*this, pnominal, pdata))
362  ec.clear();
363  else
364  ec = util::make_error_code();
365  set_errc(errsv);
366  }
367 
369  void
370  get_bitrate(int* pnominal, int* pdata = nullptr) const {
371  ::std::error_code ec;
372  get_bitrate(pnominal, pdata, ec);
373  if (ec) throw ::std::system_error(ec, "get_bitrate");
374  }
375 
377  void
378  set_bitrate(int nominal, int data, ::std::error_code& ec) noexcept {
379  int errsv = get_errc();
380  set_errc(0);
381  if (!io_can_ctrl_set_bitrate(*this, nominal, data))
382  ec.clear();
383  else
384  ec = util::make_error_code();
385  set_errc(errsv);
386  }
387 
389  void
390  set_bitrate(int nominal, int data = 0) {
391  ::std::error_code ec;
392  set_bitrate(nominal, data, ec);
393  if (ec) throw ::std::system_error(ec, "set_bitrate");
394  }
395 
397  CanState
398  get_state(::std::error_code& ec) const noexcept {
399  int errsv = get_errc();
400  set_errc(0);
401  int state = io_can_ctrl_get_state(*this);
402  if (state >= 0) {
403  ec.clear();
404  } else {
405  ec = util::make_error_code();
406  state = 0;
407  }
408  set_errc(errsv);
409  return static_cast<CanState>(state);
410  }
411 
413  CanState
414  get_state() const {
415  ::std::error_code ec;
416  auto result = get_state(ec);
417  if (ec) throw ::std::system_error(ec, "get_state");
418  return result;
419  }
420 
421  protected:
422  io_can_ctrl_t* ctrl{nullptr};
423 };
424 
429 class CanChannelBase : public Device {
430  public:
431  using Device::operator io_dev_t*;
432 
433  explicit CanChannelBase(io_can_chan_t* chan_) noexcept
434  : Device(chan_ ? io_can_chan_get_dev(chan_) : nullptr), chan(chan_) {}
435 
436  operator io_can_chan_t*() const noexcept { return chan; }
437 
439  CanBusFlag
440  get_flags() const {
441  int flags = io_can_chan_get_flags(*this);
442  if (flags == -1) util::throw_errc("get_flags");
443  return static_cast<CanBusFlag>(flags);
444  }
445 
447  int
448  read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp, int timeout,
449  ::std::error_code& ec) noexcept {
450  int errsv = get_errc();
451  set_errc(0);
452  timespec ts = {0, 0};
453  int result = io_can_chan_read(*this, msg, err, dp ? &ts : nullptr, timeout);
454  if (result >= 0)
455  ec.clear();
456  else
457  ec = util::make_error_code();
458  if (dp) *dp = util::from_timespec(ts);
459  set_errc(errsv);
460  return result;
461  }
462 
464  bool
465  read(can_msg* msg, can_err* err = nullptr,
466  ::std::chrono::nanoseconds* dp = nullptr, int timeout = -1) {
467  ::std::error_code ec;
468  int result = read(msg, err, dp, timeout, ec);
469  if (result < 0) throw ::std::system_error(ec, "read");
470  return result > 0;
471  }
472 
474  void
475  submit_read(struct io_can_chan_read& read) noexcept {
476  io_can_chan_submit_read(*this, &read);
477  }
478 
480  template <class F>
481  void
482  submit_read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
483  ev_exec_t* exec, F&& f) {
484  submit_read(*make_can_channel_read_wrapper(msg, err, dp, exec,
485  ::std::forward<F>(f)));
486  }
487 
489  template <class F>
490  void
491  submit_read(can_msg* msg, can_err* err, ::std::chrono::nanoseconds* dp,
492  F&& f) {
493  submit_read(msg, err, dp, nullptr, ::std::forward<F>(f));
494  }
495 
497  bool
498  cancel_read(struct io_can_chan_read& read) noexcept {
499  return io_can_chan_cancel_read(*this, &read) != 0;
500  }
501 
503  bool
504  abort_read(struct io_can_chan_read& read) noexcept {
505  return io_can_chan_abort_read(*this, &read) != 0;
506  }
507 
510  async_read(ev_exec_t* exec, can_msg* msg, can_err* err = nullptr,
511  timespec* tp = nullptr,
512  struct io_can_chan_read** pread = nullptr) {
513  return ev::Future<int, int>(
514  io_can_chan_async_read(*this, exec, msg, err, tp, pread));
515  }
516 
519  async_read(can_msg* msg, can_err* err = nullptr, timespec* tp = nullptr,
520  struct io_can_chan_read** pread = nullptr) {
521  return async_read(nullptr, msg, err, tp, pread);
522  }
523 
525  void
526  write(const can_msg& msg, int timeout, ::std::error_code& ec) noexcept {
527  int errsv = get_errc();
528  set_errc(0);
529  if (!io_can_chan_write(*this, &msg, timeout))
530  ec.clear();
531  else
532  ec = util::make_error_code();
533  set_errc(errsv);
534  }
535 
537  void
538  write(const can_msg& msg, int timeout = -1) {
539  ::std::error_code ec;
540  write(msg, timeout, ec);
541  if (ec) throw ::std::system_error(ec, "write");
542  }
543 
545  void
548  }
549 
551  template <class F>
552  void
553  submit_write(const can_msg& msg, ev_exec_t* exec, F&& f) {
554  submit_write(
555  *make_can_channel_write_wrapper(msg, exec, ::std::forward<F>(f)));
556  }
557 
559  template <class F>
560  void
561  submit_write(const can_msg& msg, F&& f) {
562  submit_write(msg, nullptr, ::std::forward<F>(f));
563  }
564 
566  bool
568  return io_can_chan_cancel_write(*this, &write) != 0;
569  }
570 
572  bool
573  abort_write(struct io_can_chan_write& write) noexcept {
574  return io_can_chan_abort_write(*this, &write) != 0;
575  }
576 
579  async_write(ev_exec_t* exec, const can_msg& msg,
580  struct io_can_chan_write** pwrite = nullptr) {
581  auto future = io_can_chan_async_write(*this, exec, &msg, pwrite);
582  if (!future) util::throw_errc("async_write");
583  return ev::Future<void, int>(future);
584  }
585 
588  async_write(const can_msg& msg, struct io_can_chan_write** pwrite = nullptr) {
589  return async_write(nullptr, msg, pwrite);
590  }
591 
592  protected:
593  io_can_chan_t* chan{nullptr};
594 };
595 
596 } // namespace io
597 } // namespace lely
598 
599 #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:553
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:247
lely::io::CanControllerBase::get_state
CanState get_state(::std::error_code &ec) const noexcept
Definition: can.hpp:398
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:546
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:498
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:91
lely::io::CanControllerBase::get_bitrate
void get_bitrate(int *pnominal, int *pdata=nullptr) const
Definition: can.hpp:370
lely::io::CanControllerBase::stop
void stop()
Definition: can.hpp:305
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:538
lely::io::detail::CanChannelWriteWrapper
Definition: can.hpp:197
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:588
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:519
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:172
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:69
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:947
lely::io::CanChannelBase
A reference to an abstract CAN channel.
Definition: can.hpp:429
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:273
lely::io::CanControllerBase::stop
void stop(::std::error_code &ec) noexcept
Definition: can.hpp:293
io_can_chan_write
A CAN channel write operation.
Definition: can.h:110
lely::io::CanControllerBase::stopped
bool stopped() const
Definition: can.hpp:329
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:561
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:957
lely::io::CanControllerBase::get_state
CanState get_state() const
Definition: can.hpp:414
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:338
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:378
lely::ev::Future
A future.
Definition: future.hpp:50
lely::io::CanControllerBase::restart
void restart()
Definition: can.hpp:350
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:475
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:448
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:482
lely::io::CanChannelBase::submit_read
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Definition: can.hpp:491
lely::io::CanChannelRead
A read operation suitable for use with a CAN channel.
Definition: can.hpp:144
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:526
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:231
lely::io::CanChannelBase::get_flags
CanBusFlag get_flags() const
Definition: can.hpp:440
can.h
lely::io::CanControllerBase::stopped
bool stopped(::std::error_code &ec) const noexcept
Definition: can.hpp:313
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:358
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:184
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:97
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:132
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:285
err.hpp
lely::io::CanChannelBase::abort_write
bool abort_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:573
lely::io::CanChannelBase::cancel_write
bool cancel_write(struct io_can_chan_write &write) noexcept
Definition: can.hpp:567
lely::io::CanControllerBase::set_bitrate
void set_bitrate(int nominal, int data=0)
Definition: can.hpp:390
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:579
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:510
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:262
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:150
lely::io::CanChannelBase::abort_read
bool abort_read(struct io_can_chan_read &read) noexcept
Definition: can.hpp:504
lely::io::detail::CanChannelReadWrapper
Definition: can.hpp:90
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:241
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:465