RTEMS CAN/CAN FD Stack
Loading...
Searching...
No Matches
Classes | Macros | Functions
can-queue.h File Reference

This file is part of CAN/CAN FD bus common support and implements CAN FIFOs and generic hubs/ends for chip and caracter driver interface sides. More...

#include <stdatomic.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <rtems.h>
#include <rtems/timespec.h>
#include <rtems/status-checks.h>
#include <rtems/thread.h>
#include <dev/can/can-frame.h>
#include <dev/can/can-filter.h>
Include dependency graph for can-queue.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  canque_slot_t
 This structure represents one CAN message slot in the CAN FIFO queue. More...
 
struct  canque_fifo_t
 This structure represents CAN FIFO queue. It is implemented as a single linked list of slots prepared for processing. The empty slots are stored in single linked list. More...
 
struct  canque_edge_t
 This structure represents one direction connection from messages source ( inends) to message consumer ( outends) fifo ends hub. The edge contains canque_fifo_t for message fifo implementation-. More...
 
struct  canque_ends_t
 This structure represents place to connect edges to for CAN communication entity. The zero, one or more incoming and outgoing edges can be connected to this structure. More...
 

Macros

#define RTEMS_CAN_SLOTF_CMD   ( 0x00ff )
 Macro for command associated with allocated slot.
 
#define RTEMS_CAN_QUEUE_PRIO_NR   ( 3 )
 This macro contains maximum number of priorites for queues.
 
#define CAN_FIFOF_DESTROY   ( 1 << 15 )
 
#define CAN_FIFOF_ERROR   ( 1 << 14 )
 
#define CAN_FIFOF_ERR2BLOCK   ( 1 << 13 )
 
#define CAN_FIFOF_BLOCK   ( 1 << 12 )
 
#define CAN_FIFOF_OVERRUN   ( 1 << 11 )
 
#define CAN_FIFOF_FULL   ( 1 << 10 )
 
#define CAN_FIFOF_EMPTY   ( 1 << 9 )
 
#define CAN_FIFOF_DEAD   ( 1 << 8 )
 
#define CAN_FIFOF_INACTIVE   ( 1 << 7 )
 
#define CAN_FIFOF_FREEONEMPTY   ( 1 << 6 )
 
#define CAN_FIFOF_READY   ( 1 << 5 )
 
#define CAN_FIFOF_NOTIFYPEND   ( 1 << 4 )
 
#define CAN_FIFOF_RTL_MEM   ( 1 << 3 )
 
#define CANQUEUE_NOTIFY_EMPTY   ( 1 )
 out-> in all slots are processed by FIFO out side.
 
#define CANQUEUE_NOTIFY_SPACE   ( 2 )
 out -> in - full state negated => there is space for new message.
 
#define CANQUEUE_NOTIFY_PROC   ( 3 )
 out -> in - full state negated => there is space for new message.
 
#define CANQUEUE_NOTIFY_NOUSR   ( 4 )
 Notify, that the last user has released the edge usage called with some lock to prevent edge disappear.
 
#define CANQUEUE_NOTIFY_DEAD   ( 5 )
 Edge is in progress of deletion.
 
#define CANQUEUE_NOTIFY_DEAD_WANTED   ( 6 )
 Edge should be deleted.
 
#define CANQUEUE_NOTIFY_ATTACH   ( 7 )
 Edge is in progress of deletion.
 
#define canque_for_each_inedge(qends, edge)    for ( edge = canque_first_inedge( qends ); edge; edge = canque_next_inedge( qends, edge ) )
 
#define canque_for_each_outedge(qends, edge)    for ( edge = canque_first_outedge( qends ); edge; edge = canque_next_outedge( qends, edge ) )
 

Functions

int canque_fifo_flush_slots (struct canque_fifo_t *fifo)
 This function frees all ready slots from the FIFO.
 
int canque_fifo_init_slots (struct canque_fifo_t *fifo)
 This function initializes slot chain of one CAN FIFO.
 
 TAILQ_HEAD (canqueue_edges_list_t, canque_edge_t)
 
 TAILQ_HEAD (canqueue_ends_list_t, canque_ends_t)
 
int canque_get_inslot (struct canque_ends_t *qends, struct canque_edge_t **qedgep, struct canque_slot_t **slotp, int cmd)
 This function finds one outgoing edge and allocates slot from it.
 
int canque_get_inslot4prio (struct canque_ends_t *qends, struct canque_edge_t **qedgep, struct canque_slot_t **slotp, const struct can_frame_header *header, int cmd, int prio)
 This function finds best outgoing edge and slot for given ID.
 
int canque_test_inslot (struct canque_ends_t *qends)
 This function tests whether there is a free space in any outgoing edge.
 
int canque_put_inslot (struct canque_ends_t *qends, struct canque_edge_t *qedge, struct canque_slot_t *slot)
 This function schedules filled slot for processing.
 
int canque_abort_inslot (struct canque_ends_t *qends, struct canque_edge_t *qedge, struct canque_slot_t *slot)
 This function aborts preparation of the message in the slot.
 
int canque_filter_frame2edges (struct canque_ends_t *qends, struct canque_edge_t *src_edge, struct can_frame *frame, unsigned int flags2add)
 This function sends message into all edges which accept its ID.
 
int canque_test_outslot (struct canque_ends_t *qends, struct canque_edge_t **qedgep, struct canque_slot_t **slotp)
 This function tests and retrieves ready slot for given ends.
 
int canque_pending_outslot_prio (struct canque_ends_t *qends, int prio_min)
 This function tests ready outslot with minimum priority.
 
int canque_free_outslot (struct canque_ends_t *qends, struct canque_edge_t *qedge, struct canque_slot_t *slot)
 This function frees processed output slot.
 
int canque_again_outslot (struct canque_ends_t *qends, struct canque_edge_t *qedge, struct canque_slot_t *slot)
 This function reschedules output slot to process it again later.
 
int canque_flush (struct canque_edge_t *qedge)
 This function flushes all ready slots in the edge.
 
int canqueue_disconnect_edge (struct canque_edge_t *qedge)
 This function disconnects edge from communication entities.
 
int canqueue_connect_edge (struct canque_edge_t *qedge, struct canque_ends_t *inends, struct canque_ends_t *outends)
 This function connects edge between two communication entities.
 
int canqueue_ends_init_gen (struct canque_ends_t *qends)
 This function implements subsystem independent routine to initialize ends state.
 
void canqueue_block_inlist (struct canque_ends_t *qends)
 This function blocks slot allocation of all outgoing edges of specified ends.
 
void canqueue_block_outlist (struct canque_ends_t *qends)
 This function blocks slot allocation of all incoming edges of specified ends.
 
int canqueue_ends_kill_inlist (struct canque_ends_t *qends, int send_rest)
 This function sends request to die to all outgoing edges.
 
int canqueue_ends_kill_outlist (struct canque_ends_t *qends)
 This function sends request to die to all incomming edges.
 
int canqueue_ends_flush_inlist (struct canque_ends_t *qends)
 
int canqueue_ends_flush_outlist (struct canque_ends_t *qends)
 This function flushes all messages in outgoing edges.
 
void canque_edge_do_dead (struct canque_edge_t *edge)
 
void __canque_edge_decref (struct canque_edge_t *edge)
 
int canque_fifo_init_kern (struct canque_fifo_t *fifo, int slotsnr, int maxdlen)
 This function initializes one CAN FIFO.
 
int canque_fifo_done_kern (struct canque_fifo_t *fifo)
 This function frees slots allocated for CAN FIFO.
 
struct canque_edge_tcanque_new_edge_kern (int slotsnrm, int maxdlen)
 This function allocates new edge structure.
 
int canqueue_ends_sync_all_kern (struct canque_ends_t *qends, struct timespec *ts)
 This function waits for all ends to TX their messages.
 
int canque_sync_wait_kern (struct canque_ends_t *qends, struct canque_edge_t *qedge, bool nowait, rtems_interval timeout)
 This function waits for all slots processing.
 
int canqueue_ends_dispose_kern (struct canque_ends_t *qends, bool nonblock)
 This function provides finalizing of the ends structure for clients.
 
int canqueue_kern_initialize (void)
 This function provides initialization of kernel queue side.
 

Detailed Description

This file is part of CAN/CAN FD bus common support and implements CAN FIFOs and generic hubs/ends for chip and caracter driver interface sides.

Function Documentation

◆ canque_abort_inslot()

int canque_abort_inslot ( struct canque_ends_t qends,
struct canque_edge_t qedge,
struct canque_slot_t slot 
)

This function aborts preparation of the message in the slot.

Frees slot previously acquired by canque_get_inslot() or canque_get_inslot4prio() function call. Used when message copying into slot fails.

Parameters
qendsEnds structure belonging to calling communication object.
qedgeEdge the slot belongs to.
slotPointer to the preprared slot.
Returns
Positive value informs, that queue full state has been negated.

◆ canque_again_outslot()

int canque_again_outslot ( struct canque_ends_t qends,
struct canque_edge_t qedge,
struct canque_slot_t slot 
)

This function reschedules output slot to process it again later.

Function reschedules slot previously acquired by canque_test_outslot() function call for second time processing.

Parameters
qendsEnds structure belonging to calling communication object.
qedgeEdge the slot belongs to.
slotPointer to the processed slot.
Returns
Function cannot fail.

◆ canque_fifo_done_kern()

int canque_fifo_done_kern ( struct canque_fifo_t fifo)

This function frees slots allocated for CAN FIFO.

Parameters
fifoPointer to the FIFO structure.
Returns
This function should not fail.

◆ canque_fifo_flush_slots()

int canque_fifo_flush_slots ( struct canque_fifo_t fifo)

This function frees all ready slots from the FIFO.

The caller should be prepared to handle situations, when some slots are held by input or output side slots processing. These slots cannot be flushed or their processing interrupted.

Parameters
fifoPointer to the FIFO structure.
Returns
The nonzero value indicates that queue has not been empty before the function call.

◆ canque_fifo_init_kern()

int canque_fifo_init_kern ( struct canque_fifo_t fifo,
int  slotsnr,
int  maxdlen 
)

This function initializes one CAN FIFO.

Parameters
fifoPointer to the FIFO structure.
slotsnrNumber of requested slots.
maxdlenMaximum size of data in one slot/frame.
Returns
The negative value indicates, that there is no memory to allocate space for the requested number of the slots.

◆ canque_fifo_init_slots()

int canque_fifo_init_slots ( struct canque_fifo_t fifo)

This function initializes slot chain of one CAN FIFO.

The caller should be prepared to handle situations, when some slots are held by input or output side slots processing. These slots cannot be flushed or their processing interrupted.

Parameters
fifoPointer to the FIFO structure.
Returns
The negative value indicates that there is no memory to allocate space for the requested number of the slots.

◆ canque_filter_frame2edges()

int canque_filter_frame2edges ( struct canque_ends_t qends,
struct canque_edge_t src_edge,
struct can_frame frame,
unsigned int  flags2add 
)

This function sends message into all edges which accept its ID.

Sends message to all outgoing edges connected to the given ends, which accepts message communication ID.

Parameters
qendsEnds structure belonging to calling communication object
src_edgeOptional source edge for echo detection
framePointer to CAN frame.
flags2addOptional additional CAN Frame flags.
Returns
Returns number of edges message has been send to.

◆ canque_flush()

int canque_flush ( struct canque_edge_t qedge)

This function flushes all ready slots in the edge.

Tries to flush all allocated slots from the edge, but there could exist some slots associated to edge which are processed by input or output side and cannot be flushed at this moment

Parameters
qedgePointer to the edge.
Returns
The nonzero value indicates, that queue has not been empty before the function call

◆ canque_free_outslot()

int canque_free_outslot ( struct canque_ends_t qends,
struct canque_edge_t qedge,
struct canque_slot_t slot 
)

This function frees processed output slot.

Function releases processed slot previously acquired by canque_test_outslot() function call.

Parameters
qendsEnds structure belonging to calling communication object.
qedgeEdge the slot belongs to.
slotPointer to the processed slot.
Returns
Informs if input side has been notified to know about change of edge state

◆ canque_get_inslot()

int canque_get_inslot ( struct canque_ends_t qends,
struct canque_edge_t **  qedgep,
struct canque_slot_t **  slotp,
int  cmd 
)

This function finds one outgoing edge and allocates slot from it.

Function looks for the first non-blocked outgoing edge in @qends structure and tries to allocate slot from it.

Parameters
qendsEnds structure belonging to calling communication object.
qedgepPlace to store pointer to found edge.
slotpPlace to store pointer to allocated slot.
cmdCommand type for slot.
Returns
If there is no usable edge or there is no free slot in edge negative value is returned.

◆ canque_get_inslot4prio()

int canque_get_inslot4prio ( struct canque_ends_t qends,
struct canque_edge_t **  qedgep,
struct canque_slot_t **  slotp,
const struct can_frame_header header,
int  cmd,
int  prio 
)

This function finds best outgoing edge and slot for given ID.

Function looks for the non-blocked outgoing edge accepting messages with given ID. If edge is found, slot is allocated from that edge. The edges with non-zero mask are preferred over edges open to all messages. If more edges with mask accepts given message ID, the edge with highest priority below or equal to required priority is selected.

Parameters
qendsEnds structure belonging to calling communication object.
qedgepPlace to store pointer to found edge.
slotpPlace to store pointer to allocated slot.
cmdCommand type for slot.
idCommunication ID of message to send into edge.
prioOptional priority of message,
Returns
If there is no usable edge or there is no free slot in edge negative value is returned.

◆ canque_new_edge_kern()

struct canque_edge_t * canque_new_edge_kern ( int  slotsnr,
int  maxdlen 
)

This function allocates new edge structure.

Parameters
slotsnrRequired number of slots in the newly allocated edge structure.
maxdlenMaximul data length of one CAN frame.
Returns
Pointer to canque_edge_t structure on success, NULL on error.

◆ canque_pending_outslot_prio()

int canque_pending_outslot_prio ( struct canque_ends_t qends,
int  prio_min 
)

This function tests ready outslot with minimum priority.

Function searches for ready slot in active incoming edge. The difference from canque_test_outslot function is that this function does not retreive the slot from FIFO, it just checks its existence. This can be used to determined whether there is a slot with higher priority class in the infrastruce.

Parameters
qendsEnds structure belonging to calling communication object.
prio_minMinimum slot priority to be considered
Returns
Negative value informs, that there is no ready output slot for given ends and minimum priority. Positive value informs about the available slot priority.

◆ canque_put_inslot()

int canque_put_inslot ( struct canque_ends_t qends,
struct canque_edge_t qedge,
struct canque_slot_t slot 
)

This function schedules filled slot for processing.

Puts slot previously acquired by canque_get_inslot() or canque_get_inslot4prio() function call into FIFO queue and activates edge processing if needed.

Parameters
qendsEnds structure belonging to calling communication object.
qedgeEdge the slot belongs to.
slotPointer to the preprared slot.
Returns
Positive value informs, that activation of output end has been necessary

◆ canque_sync_wait_kern()

int canque_sync_wait_kern ( struct canque_ends_t qends,
struct canque_edge_t qedge,
bool  nowait,
rtems_interval  timeout 
)

This function waits for all slots processing.

Parameters
qendsEnds structure belonging to calling communication object.
qedgePointer to edge.
nowaitTrue if semaphore should not wait
timeoutNumber of clock ticks to wait for semaphore
Returns
Positive value indicates, that edge empty state has been reached. Negative or zero value informs the semaphore timeouted.

◆ canque_test_inslot()

int canque_test_inslot ( struct canque_ends_t qends)

This function tests whether there is a free space in any outgoing edge.

Function looks for the first non-blocked outgoing edge in @qends structure with free space for slot.

Parameters
qendsEnds structure belonging to calling communication object.
Returns
0 if there is usable edge with free space available, -1 otherwise.

◆ canque_test_outslot()

int canque_test_outslot ( struct canque_ends_t qends,
struct canque_edge_t **  qedgep,
struct canque_slot_t **  slotp 
)

This function tests and retrieves ready slot for given ends.

Function takes highest priority active incoming edge and retrieves oldest ready slot from it.

Parameters
qendsEnds structure belonging to calling communication object.
qedgepPlace to store pointer to found edge.
slotpPlace to store pointer to received slot.
Returns
Negative value informs, that there is no ready output slot for given ends. Positive value is equal to the command slot has been allocated by the input side.

◆ canqueue_block_inlist()

void canqueue_block_inlist ( struct canque_ends_t qends)

This function blocks slot allocation of all outgoing edges of specified ends.

Parameters
qendsPointer to ends structure.
Returns
None.

◆ canqueue_block_outlist()

void canqueue_block_outlist ( struct canque_ends_t qends)

This function blocks slot allocation of all incoming edges of specified ends.

Parameters
qendsPointer to ends structure.
Returns
None.

◆ canqueue_connect_edge()

int canqueue_connect_edge ( struct canque_edge_t qedge,
struct canque_ends_t inends,
struct canque_ends_t outends 
)

This function connects edge between two communication entities.

Parameters
qedgePointer to edge.
inendsPointer to ends the input of the edge should be connected to.
outendsPointer to ends the output of the edge should be connected to.
Returns
Negative value informs about failed operation.

◆ canqueue_disconnect_edge()

int canqueue_disconnect_edge ( struct canque_edge_t qedge)

This function disconnects edge from communication entities.

Parameters
qedgePointer to edge.
Returns
Negative value means, that edge is used by somebody other and cannot be disconnected. Operation has to be delayed.

◆ canqueue_ends_dispose_kern()

int canqueue_ends_dispose_kern ( struct canque_ends_t qends,
bool  nonblock 
)

This function provides finalizing of the ends structure for clients.

Parameters
qendsPointer to ends structure.
nonblockFlag indicating that user does not want to wait for processing of all remaining messages.
Returns
Function should be designed such way to not fail.

◆ canqueue_ends_flush_inlist()

int canqueue_ends_flush_inlist ( struct canque_ends_t qends)

canqueue_ends_flush_inlist - flushes all messages in incoming edges @qends: pointer to ends structure

Return Value: Negative value informs about unsuccessful result

◆ canqueue_ends_flush_outlist()

int canqueue_ends_flush_outlist ( struct canque_ends_t qends)

This function flushes all messages in outgoing edges.

Parameters
qendsPointer to ends structure.
Returns
Negative value informs about unsuccessful result.

◆ canqueue_ends_init_gen()

int canqueue_ends_init_gen ( struct canque_ends_t qends)

This function implements subsystem independent routine to initialize ends state.

Parameters
qendsPointer to the end.
Returns
This fucntion cannot fail.

◆ canqueue_ends_kill_inlist()

int canqueue_ends_kill_inlist ( struct canque_ends_t qends,
int  send_rest 
)

This function sends request to die to all outgoing edges.

Parameters
qendsPointer to ends structure.
send_restSelect, whether already allocated slots should be processed by FIFO output side.
Returns
Non-zero value means, that not all edges could be immediately disconnected and that ends structure memory release has to be delayed.

◆ canqueue_ends_kill_outlist()

int canqueue_ends_kill_outlist ( struct canque_ends_t qends)

This function sends request to die to all incomming edges.

Parameters
qendsPointer to ends structure.
Returns
Non-zero value means, that not all edges could be immediately disconnected and that ends structure memory release has to be delayed.

◆ canqueue_ends_sync_all_kern()

int canqueue_ends_sync_all_kern ( struct canque_ends_t qends,
struct timespec *  ts 
)

This function waits for all ends to TX their messages.

Parameters
qendsPointer to ends structure.
tsAbsolute time againts CLOCK_MONOTONIC that informs canque_sync_wait_kern how long to wait.
Returns
0 on success, -ETIME in case of timeout.

◆ canqueue_kern_initialize()

int canqueue_kern_initialize ( void  )

This function provides initialization of kernel queue side.

Returns
Zero on success.