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
36namespace lely {
37namespace io {
38
40enum 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
53constexpr CanBusFlag
54operator~(CanBusFlag rhs) {
55 return static_cast<CanBusFlag>(~static_cast<int>(rhs));
56}
57
58constexpr CanBusFlag
59operator&(CanBusFlag lhs, CanBusFlag rhs) {
60 return static_cast<CanBusFlag>(static_cast<int>(lhs) & static_cast<int>(rhs));
61}
62
63constexpr CanBusFlag
64operator^(CanBusFlag lhs, CanBusFlag rhs) {
65 return static_cast<CanBusFlag>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
66}
67
68constexpr CanBusFlag
69operator|(CanBusFlag lhs, CanBusFlag rhs) {
70 return static_cast<CanBusFlag>(static_cast<int>(lhs) | static_cast<int>(rhs));
71}
72
73inline CanBusFlag&
74operator&=(CanBusFlag& lhs, CanBusFlag rhs) {
75 return lhs = lhs & rhs;
76}
77
78inline CanBusFlag&
79operator^=(CanBusFlag& lhs, CanBusFlag rhs) {
80 return lhs = lhs ^ rhs;
81}
82
83inline CanBusFlag&
84operator|=(CanBusFlag& lhs, CanBusFlag rhs) {
85 return lhs = lhs | rhs;
86}
87
88namespace detail {
89
90template <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 {
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
129template <class F>
130inline 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
195namespace detail {
196
197template <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
227template <class F>
228// clang-format off
229inline 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
301 set_errc(errsv);
302 }
303
305 void
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 {
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
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
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
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
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 {
407 state = 0;
408 }
409 set_errc(errsv);
410 return static_cast<CanState>(state);
411 }
412
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
430class 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
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
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) {
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
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< void, int > async_write(ev_exec_t *exec, const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
Definition: can.hpp:580
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(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
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
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
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
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.
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
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
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
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_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
@ 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
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
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
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
CanBusFlag
The CAN bus flags.
Definition: can.hpp:40
@ BRS
Bit Rate Switch support is enabled.
@ FDF
FD Format (formerly Extended Data Length) support is enabled.
@ ERR
Reception of error frames is enabled.
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.
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
STL namespace.
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.