24 #ifndef LELY_IO2_CAN_HPP_
25 #define LELY_IO2_CAN_HPP_
49 NONE = IO_CAN_BUS_FLAG_NONE,
50 MASK = IO_CAN_BUS_FLAG_MASK
54 operator~(CanBusFlag rhs) {
55 return static_cast<CanBusFlag
>(~static_cast<int>(rhs));
59 operator&(CanBusFlag lhs, CanBusFlag rhs) {
60 return static_cast<CanBusFlag
>(
static_cast<int>(lhs) &
static_cast<int>(rhs));
64 operator^(CanBusFlag lhs, CanBusFlag rhs) {
65 return static_cast<CanBusFlag>(
static_cast<int>(lhs) ^
static_cast<int>(rhs));
69 operator|(CanBusFlag lhs, CanBusFlag rhs) {
70 return static_cast<CanBusFlag>(
static_cast<int>(lhs) |
static_cast<int>(rhs));
74 operator&=(CanBusFlag& lhs, CanBusFlag rhs) {
75 return lhs = lhs & rhs;
79 operator^=(CanBusFlag& lhs, CanBusFlag rhs) {
80 return lhs = lhs ^ rhs;
84 operator|=(CanBusFlag& lhs, CanBusFlag rhs) {
85 return lhs = lhs | rhs;
94 ::std::chrono::nanoseconds* dp,
ev_exec_t* exec, F&& f)
96 msg,
err, dp ? &ts_ :
nullptr, exec,
99 auto result = read->r.result;
100 ::std::error_code ec;
103 if (self->dp_) *
self->dp_ = util::from_timespec(self->ts_);
104 compat::invoke(::std::move(self->func_), result, ec);
108 func_(::std::forward<F>(f)) {}
118 ::std::chrono::nanoseconds* dp_{
nullptr};
119 typename ::std::decay<F>::type func_;
130 inline typename ::std::enable_if<
134 ::std::chrono::nanoseconds* dp,
ev_exec_t* exec,
137 ::std::forward<F>(f));
147 using Signature = void(
int, ::std::error_code);
159 *
self->dp_ = util::from_timespec(self->ts_);
161 auto result = read->r.result;
162 ::std::error_code ec;
165 self->func_(result, ec);
169 func_(::std::forward<F>(f)) {}
181 operator ev_task&() & noexcept {
return task; }
191 ::std::chrono::nanoseconds* dp_{
nullptr};
192 ::std::function<Signature> func_;
207 compat::invoke(::std::move(self->func_), ec);
210 func_(::std::forward<F>(f)) {}
217 typename ::std::decay<F>::type func_;
229 inline typename ::std::enable_if<
244 using Signature = void(::std::error_code);
259 func_(::std::forward<F>(f)) {}
270 operator ev_task&() & noexcept {
return task; }
279 ::std::function<Signature> func_;
294 stop(::std::error_code& ec) noexcept {
307 ::std::error_code ec;
309 if (ec) throw ::std::system_error(ec,
"stop");
314 stopped(::std::error_code& ec)
const noexcept {
331 ::std::error_code ec;
332 auto result = stopped(ec);
333 if (ec) throw ::std::system_error(ec,
"stopped");
352 ::std::error_code ec;
354 if (ec) throw ::std::system_error(ec,
"restart");
359 get_bitrate(
int* pnominal,
int* pdata, ::std::error_code& ec)
const noexcept {
372 ::std::error_code ec;
373 get_bitrate(pnominal, pdata, ec);
374 if (ec) throw ::std::system_error(ec,
"get_bitrate");
379 set_bitrate(
int nominal,
int data, ::std::error_code& ec) noexcept {
392 ::std::error_code ec;
393 set_bitrate(nominal, data, ec);
394 if (ec) throw ::std::system_error(ec,
"set_bitrate");
410 return static_cast<CanState>(state);
416 ::std::error_code ec;
417 auto result = get_state(ec);
418 if (ec) throw ::std::system_error(ec,
"get_state");
443 if (flags == -1) util::throw_errc(
"get_flags");
450 ::std::error_code& ec) noexcept {
453 timespec ts = {0, 0};
454 int result =
io_can_chan_read(*
this, msg, err, dp ? &ts :
nullptr, timeout);
459 if (dp) *dp = util::from_timespec(ts);
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");
486 ::std::forward<F>(f)));
494 submit_read(msg, err, dp,
nullptr, ::std::forward<F>(f));
512 timespec* tp =
nullptr,
522 return async_read(
nullptr, msg, err, tp, pread);
527 write(
const can_msg& msg,
int timeout, ::std::error_code& ec) noexcept {
540 ::std::error_code ec;
541 write(msg, timeout, ec);
542 if (ec) throw ::std::system_error(ec,
"write");
563 submit_write(msg,
nullptr, ::std::forward<F>(f));
583 if (!future) util::throw_errc(
"async_write");
590 return async_write(
nullptr, msg, pwrite);
An abstract task executor. This class is a wrapper around #ev_exec_t*.
A reference to an abstract CAN channel.
void submit_write(const can_msg &msg, ev_exec_t *exec, F &&f)
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, ev_exec_t *exec, F &&f)
bool read(can_msg *msg, can_err *err=nullptr, ::std::chrono::nanoseconds *dp=nullptr, int timeout=-1)
CanBusFlag get_flags() const
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)
void write(const can_msg &msg, int timeout=-1)
ev::Future< void, int > async_write(const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
void submit_read(struct io_can_chan_read &read) noexcept
void submit_write(struct io_can_chan_write &write) noexcept
ev::Future< int, int > async_read(can_msg *msg, can_err *err=nullptr, timespec *tp=nullptr, struct io_can_chan_read **pread=nullptr)
bool abort_read(struct io_can_chan_read &read) noexcept
bool abort_write(struct io_can_chan_write &write) noexcept
void write(const can_msg &msg, int timeout, ::std::error_code &ec) noexcept
ev::Future< void, int > async_write(ev_exec_t *exec, const can_msg &msg, struct io_can_chan_write **pwrite=nullptr)
void submit_write(const can_msg &msg, F &&f)
int read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, int timeout, ::std::error_code &ec) noexcept
bool cancel_read(struct io_can_chan_read &read) noexcept
void submit_read(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
bool cancel_write(struct io_can_chan_write &write) noexcept
A read operation suitable for use with a CAN channel.
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.
CanChannelRead(can_msg *msg, can_err *err, ::std::chrono::nanoseconds *dp, F &&f)
Constructs a read operation with a completion task.
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
A write operation suitable for use with a CAN channel.
CanChannelWrite(const can_msg &msg, F &&f)
Constructs a write operation with a completion task.
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
CanChannelWrite(const can_msg &msg, ev_exec_t *exec, F &&f)
Constructs a write operation with a completion task.
A reference to an abstract CAN controller.
CanState get_state() const
void stop(::std::error_code &ec) noexcept
void set_bitrate(int nominal, int data=0)
bool stopped(::std::error_code &ec) const noexcept
void set_bitrate(int nominal, int data, ::std::error_code &ec) noexcept
void get_bitrate(int *pnominal, int *pdata, ::std::error_code &ec) const noexcept
CanState get_state(::std::error_code &ec) const noexcept
void restart(::std::error_code &ec) noexcept
void get_bitrate(int *pnominal, int *pdata=nullptr) const
An abstract I/O device. This class is a wrapper around #io_dev_t*.
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.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
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.
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.
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.
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.
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
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.
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.
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.
const struct io_can_ctrl_vtbl *const io_can_ctrl_t
An abstract CAN controller.
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.
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.
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.
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,...
int io_can_ctrl_stop(io_can_ctrl_t *ctrl)
Stops a CAN controller.
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.
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_write.
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_...
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
int io_can_ctrl_set_bitrate(io_can_ctrl_t *ctrl, int nominal, int data)
Configures the bitrate(s) of a CAN controller.
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...
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...
@ IO_CAN_BUS_FLAG_BRS
Bit Rate Switch support is enabled.
@ IO_CAN_BUS_FLAG_FDF
FD Format (formerly Extended Data Length) support is enabled.
@ IO_CAN_BUS_FLAG_ERR
Reception of error frames is enabled.
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.
int io_can_ctrl_get_bitrate(const io_can_ctrl_t *ctrl, int *pnominal, int *pdata)
Obtains the bitrate(s) of a CAN controller.
int io_can_ctrl_restart(io_can_ctrl_t *ctrl)
(Re)starts a CAN contoller.
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.
CanBusFlag
The CAN bus flags.
@ 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.
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.
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
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.
A CAN or CAN FD format frame.
A CAN channel read operation.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
struct can_msg * msg
The address at which to store the CAN frame.
struct can_err * err
The address at which to store the CAN error frame.
A CAN channel write operation.
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.