CAN Utility function reference

timing_util.h

Functions

bool can_generate_timing_params(uint32_t system_freq, can_timing_t *timing)

Generate CAN bus timing setting for PIC microcontrollers.

Parameters:
  • system_freq – PIC Fosc frequency in Hz

  • timing – buffer to write timing parameters to

Returns:

true if system_freq is valid and parameters have been written to timing

safe_ring_buffer.h

Functions

void srb_init(srb_ctx_t *ctx, void *pool, size_t pool_size, size_t element_size)
bool srb_push(srb_ctx_t *ctx, const void *element)
bool srb_is_full(const srb_ctx_t *ctx)
bool srb_is_empty(const srb_ctx_t *ctx)
bool srb_pop(srb_ctx_t *ctx, void *element)
bool srb_peek(const srb_ctx_t *ctx, void *element)
struct srb_ctx_t

Public Members

void *memory_pool
size_t element_size
size_t max_elements
size_t rd_idx
size_t wr_idx

can_tx_buffer.h

Functions

void txb_init(void *pool, size_t pool_size, void (*can_send)(const can_msg_t*), bool (*can_tx_ready)(void))
bool txb_enqueue(const can_msg_t *msg)

Buffers message.

If there is room in the can_tx buffer, this function will not send the message. The only calls to can_send() will be made during txb_heartbeat()

Parameters:

msg – message to be buffered

Returns:

true if success, false if failed(i.e. buffer is full)

void txb_heartbeat(void)

This function is called every iteration through the main application loop.

If there are any messages that are in the “to transmit” queue, and can_tx_ready() returns true, then can_send() will be called with that message

can_rcv_buffer.h

A module for buffering CAN messages that are received from the CAN module. The module operates as a ring buffer, with the memory provided by the caller of the module.

The whole goal of this module is allowing you to write application code that doesn’t have to concern itself with ISR vs main thread code. If you set buffer_received_can_message as the can callback, then you can dequeue the buffered messages from the main thread without worrying about missing any messages from the bus.

The ring buffer is designed to be pseudo-thread safe. None of the functions are rentrant, and there are no locking or atomic mechanisms, but flags are used to show whether a particular memory element contains valid data. This should allow the writer function (buffer_received_can_message) and the reader function (get_buffered_can_message) to operate from separate contexts (the former can be run in the ISR and the latter in the main thread) without any problems.

Functions

void rcvb_init(void *pool, size_t pool_size)

Initializes the reecive buffer module.

Parameters:
  • pool – memory buffer, which must be provided by the caller

  • pool_size – the size of pool, in bytes

void rcvb_push_message(const can_msg_t *msg)

Copies msg into our internal buffering system.

This function fails silently if we’re out of memory/space to hold the CAN message. This is so that you can use this buffering system as the CAN callback, whose signature is void

Parameters:

msg – message to be sent

bool rcvb_has_overflowed(void)

returns true if the CAN receive buffer has ever overflowed.

Because the push function is meant to be called from an ISR, it won’t be able to do anything if it runs out of memory, it will just drop the message. That drop shouldn’t be silent, so this function will return true if a message has ever been dropped. You can clear this flag with rcvb_reset_overflow_flag.

void rcvb_clear_overflow_flag(void)

Clears the overflow flag, so that rcvb_has_overflowed will start returning false again. This function isn’t perfectly concurrency safe: If you call this function and during the call the receive buffer overflows again, you’ll miss that flag.

bool rcvb_is_full(void)

returns true if the receive buffer is full

This function exists to make up for the signature of rcvb_push_message. If this function returns true, then you know that we’re out of memory and we can’t enqueue your new message

bool rcvb_is_empty(void)

returns false if there’s a CAN message that has been buffered, but has not yet been read. Returns true otherwise

bool rcvb_pop_message(can_msg_t *msg)

gets the oldest buffered CAN message and puts it into msg, then dequeues that message.

Parameters:

msg – message buffer

Returns:

true if we were successfully able to grab a CAN message.

bool rcvb_peek_message(can_msg_t *msg)

gets the oldest buffered CAN message and puts it into msg, and does not dequeue it.

Parameters:

msg – message buffer

Returns:

true if we were successfully able to grab a CAN message.