There are three layers we are dealing with which build on top of each other to provide a robust way to send and receive CAN messages.
Provide Application IO for CAN
Provide Queue based functionality
Provide interrupt-driven callbacks for HW CAN mailboxes
1. IO STREAM
High Level application code interface
Agnostic to the concept of CAN HW mailboxes, interrupts, or queues
Unaware of HW CAN mailbox filters
Allows timeouts to provide event-driven IO
io_stream_glue.c re-directs to HAL_CAN to provide polled or event driven operation
To deliberately use a polled mechanism, the timeout can be set to zero.
2. HAL CAN
Generic CAN interface for diverse CAN peripherals
Supports the concept of HW CAN mailboxes and message ID filters
Adds RTOS constructs on top of the HW CAN layer
Uses ISR callbacks to add queue capability for transmission or reception of CAN frames
3. HW CAN
Fundamentally a register writer which encapsulates a CAN peripheral
Provides interrupts and a callback function for mailbox transmission and receive events
A micro-application that wants to utilize the CAN bus can use the IO Stream interface and can be designed to be agnostic to the CAN driver. It can simply say that it wants to open a /dev/CAN0/rx_all device, which is an arbitrary string value, and the io_stream_glue.c shall associate the string to configure the HAL_CAN HW mailbox to meet the objective.
The HAL CAN Configuration sample code given below can be referenced to setup mailboxes in a way to a facilitate the IO Stream descriptors for transmission and reception. For example, if there is a UDS firmware download application, then the IO Stream descriptor of /dev/CAN0/UDS should be match the configuration of a transmission mailbox with possibly an RTOS queue.
All use cases of the CAN bus should be supported through the IO Stream interface.