Lely core libraries
2.2.5
|
Go to the documentation of this file.
39 #ifndef LELY_IO_CAN_NET_TXLEN
44 #define LELY_IO_CAN_NET_TXLEN 1000
47 #ifndef LELY_IO_CAN_NET_TXTIMEO
52 #define LELY_IO_CAN_NET_TXTIMEO 100
55 static void io_can_net_svc_shutdown(
struct io_svc *svc);
58 static const struct io_svc_vtbl io_can_net_svc_vtbl = {
60 &io_can_net_svc_shutdown
176 static void io_can_net_wait_next_func(
struct ev_task *task);
177 static void io_can_net_wait_confirm_func(
struct ev_task *task);
178 static void io_can_net_read_func(
struct ev_task *task);
179 static void io_can_net_write_func(
struct ev_task *task);
181 static int io_can_net_next_func(
const struct timespec *tp,
void *data);
182 static int io_can_net_send_func(
const struct can_msg *msg,
void *data);
184 static void io_can_net_c_wait_func(
struct spscring *ring,
void *arg);
193 static void default_on_read_error_func(
int errc,
size_t errcnt,
void *arg);
194 static void default_on_queue_error_func(
int errc,
size_t errcnt,
void *arg);
195 static void default_on_write_error_func(
int errc,
size_t errcnt,
void *arg);
196 static void default_on_can_state_func(
int new_state,
int old_state,
void *arg);
197 static void default_on_can_error_func(
int error,
void *arg);
200 io_can_net_alloc(
void)
209 io_can_net_free(
void *ptr)
242 goto error_create_tq;
245 0, 0, NULL, &io_can_net_wait_next_func);
247 0, 0, NULL, &io_can_net_wait_confirm_func);
256 &io_can_net_read_func);
264 &net->
write_msg, NULL, &io_can_net_write_func);
272 goto error_alloc_tx_buf;
303 goto error_create_net;
305 net->
next = (
struct timespec){ 0, 0 };
346 io_can_net_svc_shutdown(&net->
svc);
354 if (io_can_net_do_abort_tasks(net))
360 "io_can_net_fini() invoked with pending operations");
378 size_t txlen,
int txtimeo)
389 io_can_net_init(net, exec, timer, chan, txlen, txtimeo);
399 io_can_net_free(net);
409 io_can_net_fini(net);
410 io_can_net_free(net);
427 io_can_net_do_wait(net);
681 struct timespec now = { 0, 0 };
688 io_can_net_svc_shutdown(
struct io_svc *svc)
706 io_can_net_wait_next_func(
struct ev_task *task)
722 int submit_wait_next = 0;
724 struct timespec now = { 0, 0 };
728 submit_wait_next = 1;
737 if (submit_wait_next)
742 io_can_net_wait_confirm_func(
struct ev_task *task)
796 }
else if (read->
r.
result == 0) {
799 int old_state = net->
state;
878 if (!net->
shutdown && !io_can_net_do_wait(net))
879 io_can_net_do_write(net);
887 io_can_net_next_func(
const struct timespec *tp,
void *data)
918 io_can_net_send_func(
const struct can_msg *
msg,
void *data)
951 io_can_net_c_wait_func(
struct spscring *ring,
void *arg)
958 if (!io_can_net_do_wait(net))
959 io_can_net_do_write(net);
963 io_can_net_from_svc(
const struct io_svc *svc)
978 &net->
tx_ring, 1, &io_can_net_c_wait_func, net))
1050 default_on_read_error_func(
int errc,
size_t errcnt,
void *arg)
1058 "CAN frame successfully read after %zu read error%s",
1059 errcnt, errcnt > 1 ?
"s" :
"");
1063 default_on_queue_error_func(
int errc,
size_t errcnt,
void *arg)
1069 "CAN transmit queue full; dropping frame");
1072 "CAN frame successfully queued after dropping %zd frame%s",
1073 errcnt, errcnt > 1 ?
"s" :
"");
1077 default_on_write_error_func(
int errc,
size_t errcnt,
void *arg)
1085 "CAN frame successfully written after %zu write error%s",
1086 errcnt, errcnt > 1 ?
"s" :
"");
1090 default_on_can_state_func(
int new_state,
int old_state,
void *arg)
1095 switch (new_state) {
1100 diag(
DIAG_INFO, 0,
"CAN bus is in the error passive state");
1115 default_on_can_error_func(
int error,
void *arg)
1129 "acknowledgment error detected on CAN bus");
1132 "one or more unknown errors detected on CAN bus");
struct timespec value
The absolute expiration time.
ev_exec_t * io_can_net_get_exec(const io_can_net_t *net)
Returns a pointer to the executor used by the CAN network interface to execute asynchronous tasks.
int read_errc
The error code of the last read operation.
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.
void io_can_net_set_on_read_error_func(io_can_net_t *net, io_can_net_on_error_func_t *func, void *arg)
Sets the function invoked when a new CAN frame read error occurs, or when a read operation completes ...
void io_tqueue_submit_wait(io_tqueue_t *tq, struct io_tqueue_wait *wait)
Submits a wait operation to a timer queue.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
void mtx_destroy(mtx_t *mtx)
Releases any resources used by the mutex at mtx.
io_can_net_on_can_error_func_t * on_can_error_func
A pointer to the function to be invoked when an error is detected on the CAN bus.
struct io_tqueue_wait wait_confirm
The operation used to wait for a CAN frame write confirmation.
struct io_tqueue_wait wait_next
The operation used to wait for the next CANopen event.
size_t spscring_c_capacity(struct spscring *ring)
Returns the total capacity available for a consumer in a single-producer single-consumer ring buffer,...
@ CAN_STATE_BUSOFF
The bus off state (TX/RX error count >= 256).
unsigned wait_next_submitted
A flag indicating whether wait_next has been submitted to tq.
struct can_msg * tx_buf
The transmit queue.
struct can_msg read_msg
The CAN frame being read.
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.
void can_net_get_time(const can_net_t *net, struct timespec *tp)
Retrieves the current time of a CAN network interface.
void io_can_net_set_on_write_error_func(io_can_net_t *net, io_can_net_on_error_func_t *func, void *arg)
Sets the function invoked when a new CAN frame write error occurs, or when a write operation complete...
size_t spscring_c_commit(struct spscring *ring, size_t size)
Makes the specified number of indices available to a producer and, if this satisfies a wait operation...
@ CAN_STATE_ACTIVE
The error active state (TX/RX error count < 128).
#define IO_TQUEUE_WAIT_INIT(sec, nsec, exec, func)
The static initializer for io_tqueue_wait.
mtx_t mtx
The mutex protecting the callbacks, flags and internal CAN network interface.
The virtual table of an I/O service.
void * on_write_error_arg
The user-specified argument for on_write_error_func.
int can_net_set_time(can_net_t *net, const struct timespec *tp)
Sets the current time of a CAN network interface.
int txtimeo
The timeout (in milliseconds) when waiting for a CAN frame write confirmation.
void io_can_net_get_on_read_error_func(const io_can_net_t *net, io_can_net_on_error_func_t **pfunc, void **parg)
Retrieves the function invoked when a new CAN frame read error occurs, or when a read operation compl...
@ CAN_ERROR_BIT
A single bit error.
@ DIAG_INFO
An informational message.
A CAN or CAN FD format frame.
#define IO_SVC_INIT(vptr)
The static initializer for io_svc.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the write operation.
void io_can_net_on_can_error_func_t(int error, void *arg)
The type of function invoked when a CAN bus error is detected by an CAN network interface.
size_t tx_errcnt
The number of frames dropped due to the transmit queue being full.
void io_can_net_get_on_queue_error_func(const io_can_net_t *net, io_can_net_on_error_func_t **pfunc, void **parg)
Retrieves the function invoked when a CAN frame is dropped because the transmit queue is full,...
int can_net_recv(can_net_t *net, const struct can_msg *msg)
Receives a CAN frame with a network interface and processes it with the corresponding receiver(s).
struct can_err read_err
The CAN error frame being read.
size_t read_errcnt
The number of errors since the last successful read operation.
unsigned read_submitted
A flag indicating whether read has been submitted to chan.
int errc
The error number, obtained as if by get_errc(), if an error occurred or the operation was canceled.
int mtx_lock(mtx_t *mtx)
Blocks until it locks the mutex at mtx.
struct io_tqueue_wait * io_tqueue_wait_from_task(struct ev_task *task)
Obtains a pointer to a timer queue wait operation from a pointer to its completion task.
ev_exec_t * exec
A pointer to the executor ...
struct timespec next
The time at which the next CAN timer will trigger.
can_net_t * net
A pointer to the internal CAN network interface.
@ CAN_STATE_PASSIVE
The error passive state (TX/RX error count < 256).
io_clock_t * io_timer_get_clock(const io_timer_t *timer)
Returns a pointer to the clock used by the timer.
int spscring_c_abort_wait(struct spscring *ring)
Aborts a wait operation previously registered with spscring_c_submit_wait().
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
size_t write_errcnt
The number of errors since the last successful write operation.
int io_clock_gettime(const io_clock_t *clock, struct timespec *tp)
Obtains the current time value of the specified clock.
int timespec_cmp(const void *p1, const void *p2)
Compares two times.
void io_ctx_insert(io_ctx_t *ctx, struct io_svc *svc)
Registers an I/O service with an I/O context.
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
@ CAN_ERROR_ACK
An acknowledgment error.
size_t spscring_c_alloc(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, including wrapping, in a single-producer,...
void can_net_destroy(can_net_t *net)
Destroys a CAN network interface.
io_can_net_on_error_func_t * on_queue_error_func
A pointer to the function invoked when a CAN frame is dropped because the transmit queue is full,...
int spscring_c_submit_wait(struct spscring *ring, size_t size, void(*func)(struct spscring *ring, void *arg), void *arg)
Checks if the requested range of indices, including wrapping, in a single-producer,...
void timespec_add_msec(struct timespec *tp, uint_least64_t msec)
Adds msec milliseconds to the time at tp.
void * on_queue_error_arg
The user-specified argument for on_queue_error_func.
size_t spscring_p_alloc(struct spscring *ring, size_t *psize)
Allocates a consecutive range of indices, including wrapping, in a single-producer,...
void io_can_net_destroy(io_can_net_t *net)
Destroys a CAN network interface.
A CAN channel read operation.
void io_can_net_get_on_can_error_func(const io_can_net_t *net, io_can_net_on_can_error_func_t **pfunc, void **parg)
Retrieves the function invoked when a CAN bus error is detected.
@ CAN_ERROR_OTHER
One or more other errors.
pthread_mutex_t mtx_t
A complete object type that holds an identifier for a mutex.
#define CAN_MSG_INIT
The static initializer for can_msg.
unsigned write_submitted
A flag indicating whether write has been submitted to chan.
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
#define LELY_IO_CAN_NET_TXTIMEO
The default timeout (in milliseconds) of a CAN network interface when waiting for a CAN frame write c...
int errc
The error number, obtained as if by get_errc(), if result is -1.
io_tqueue_t * tq
A pointer to the timer queue used to schedule wait operations.
@ thrd_success
Indicates that the requested operation succeeded.
@ CAN_ERROR_FORM
A form error.
struct can_msg write_msg
The CAN frame being written.
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.
unsigned shutdown
A flag indicating whether the I/O service has been shut down.
void spscring_init(struct spscring *ring, size_t size)
Initializes a single-producer, single-consumer ring buffer with the specified size.
int mtx_unlock(mtx_t *mtx)
Unlocks the mutex at mtx.
@ ERRNUM_CANCELED
Operation canceled.
A CAN channel write operation.
A wait operation suitable for use with a timer queue.
void io_can_net_start(io_can_net_t *net)
Starts a CAN network interface and begins processing CAN frames.
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
int result
The result of the read operation: 1 if a CAN frame is received, 0 if an error frame is received,...
const struct can_msg * msg
A pointer to the CAN frame to be written.
int io_can_net_set_time(io_can_net_t *net)
Updates the CAN network time.
struct io_svc svc
The I/O service representing the channel.
#define LELY_IO_CAN_NET_TXLEN
The default length (in number of CAN frames) of the user-space transmit queue of a CAN network interf...
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
can_net_t * can_net_create(void)
Creates a new CAN network interface.
@ CAN_STATE_STOPPED
The device is stopped.
struct io_can_chan_read read
The operation used to read CAN frames.
void * on_can_error_arg
The user-specified argument for #on_error_func.
io_ctx_t * ctx
A pointer to the I/O context with which the channel is registered.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the wait operation.
io_can_net_on_error_func_t * on_read_error_func
A pointer to the function invoked when a new CAN frame read error occurs, or when a read operation co...
io_can_net_t * io_can_net_create(ev_exec_t *exec, io_timer_t *timer, io_can_chan_t *chan, size_t txlen, int txtimeo)
Creates a new CAN network interface.
unsigned started
A flag indicating wheter the CAN network interface has been started.
io_clock_t * io_can_net_get_clock(const io_can_net_t *net)
Returns a pointer to the clock used by the CAN network interface.
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_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.
int state
The current state of the CAN bus.
int error
The error flags of the CAN bus (any combination of CAN_ERROR_BIT, CAN_ERROR_STUFF,...
size_t io_tqueue_abort_wait(io_tqueue_t *tq, struct io_tqueue_wait *wait)
Aborts the specified timer queue wait operation if it is pending.
#define CAN_ERR_INIT
The static initializer for a can_err struct.
unsigned wait_confirm_submitted
A flag indicating whether wait_confirm has been submitted to tq.
int state
The state of the CAN node (one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE or CAN_STATE_BUSOFF).
void io_can_net_get_on_write_error_func(const io_can_net_t *net, io_can_net_on_error_func_t **pfunc, void **parg)
Retrieves the function invoked when a new CAN frame write error occurs, or when a write operation com...
void io_ctx_remove(io_ctx_t *ctx, struct io_svc *svc)
Unregisters an I/O service with an I/O context.
int write_errc
The error code of the last write operation.
io_timer_t * io_tqueue_get_timer(const io_tqueue_t *tq)
Returns a pointer to the I/O timer used by the timer queue.
void io_can_net_on_can_state_func_t(int new_state, int old_state, void *arg)
The type of function invoked when a CAN bus state change is detected by a CAN network interface.
void * on_read_error_arg
The user-specified argument for on_read_error_func.
void diag(enum diag_severity severity, int errc, const char *format,...)
Emits a diagnostic message.
static ev_exec_t * io_can_chan_get_exec(const io_can_chan_t *chan)
void thrd_yield(void)
Endeavors to permit other threads to run, even if the current thread would ordinarily continue to run...
@ CAN_ERROR_STUFF
A bit stuffing error.
void aligned_free(void *ptr)
Causes the space at ptr to be deallocated, that is, made available for further allocation.
io_tqueue_t * io_can_net_get_tqueue(const io_can_net_t *net)
Returns a pointer to the internal timer queue of a CAN network interface.
errnum_t errc2num(int errc)
Transforms a native error code to a platform-independent error number.
@ CAN_ERROR_CRC
A CRC sequence error.
void io_tqueue_destroy(io_tqueue_t *tq)
Destroys a timer queue.
can_net_t * io_can_net_get_net(const io_can_net_t *net)
Returns a pointer to the internal interface of a CAN network interface.
void can_net_set_next_func(can_net_t *net, can_timer_func_t *func, void *data)
Sets the callback function invoked when the time at which the next CAN timer triggers is updated.
io_can_chan_t * chan
A pointer to a CAN channel.
@ CAN_STATE_SLEEPING
The device is in sleep mode.
void io_can_net_set_on_can_error_func(io_can_net_t *net, io_can_net_on_can_error_func_t *func, void *arg)
Sets the function to be invoked when a CAN bus error is detected.
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.
The implementation of a CAN network interface.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
void can_net_set_send_func(can_net_t *net, can_send_func_t *func, void *data)
Sets the callback function used to send CAN frames from a network interface.
io_can_net_on_can_state_func_t * on_can_state_func
A pointer to the function to be invoked when a CAN bus state change is detected.
struct spscring tx_ring
The ring buffer used to control the transmit queue.
void io_can_net_get_on_can_state_func(const io_can_net_t *net, io_can_net_on_can_state_func_t **pfunc, void **parg)
Retrieves the function invoked when a CAN bus state change is detected.
struct io_can_chan_write write
The operation used to write CAN frames.
static io_ctx_t * io_can_chan_get_ctx(const io_can_chan_t *chan)
A single-producer, single-consumer ring buffer.
const struct io_timer_vtbl *const io_timer_t
An abstract timer.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
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.
size_t spscring_p_commit(struct spscring *ring, size_t size)
Makes the specified number of indices available to a consumer and, if this satisfies a wait operation...
io_ctx_t * io_can_net_get_ctx(const io_can_net_t *net)
Returns a pointer to the I/O context with which the CAN network interface is registered.
io_timer_t * timer
A pointer to the timer used for CAN network events.
io_can_net_on_error_func_t * on_write_error_func
A pointer to the function invoked when a new CAN frame write error occurs, or when a write operation ...
void * on_can_state_arg
The user-specified argument for #on_state_func.
const struct io_clock_vtbl *const io_clock_t
An abstract clock.
int mtx_init(mtx_t *mtx, int type)
Creates a mutex object with properties indicated by type, which must have one of the four values:
void io_can_net_on_error_func_t(int errc, size_t errcnt, void *arg)
The type of function invoked when an error occurs during a CAN network interface operations,...
int io_can_net_unlock(io_can_net_t *net)
Unlocks the mutex protecting the CAN network interface.
int io_can_net_lock(io_can_net_t *net)
Locks the mutex protecting the CAN network interface.
struct io_can_chan_read_result r
The result of the read operation.
@ mtx_plain
A mutex type that supports neither timeout nor test and return.
void io_can_net_set_on_can_state_func(io_can_net_t *net, io_can_net_on_can_state_func_t *func, void *arg)
Sets the function to be invoked when a CAN bus state change is detected.
@ ERRNUM_AGAIN
Resource unavailable, try again.
void io_can_net_set_on_queue_error_func(io_can_net_t *net, io_can_net_on_error_func_t *func, void *arg)
Sets the function invoked when a CAN frame is dropped because the transmit queue is full,...
#define _Alignof(x)
Specifies the alignment requirement of the declared object or member.
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.
io_tqueue_t * io_tqueue_create(io_timer_t *timer, ev_exec_t *exec)
Creates a new timer queue.
void * aligned_alloc(size_t alignment, size_t size)
Allocates space for an object whose alignment is specified by alignment, whose size is specified by s...