tl;dr: do not rely on the tx buffer management services provided by your CAN controller. Make your driver manage the transmission order in software instead. Otherwise, you will run into either a priority inversion problem or data loss caused by frame reordering.
I just ran a quick survey of the TX buffer management capabilities offered by the following products:
- TI TCAN4550 — standalone CAN FD controller chip
- Microchip ATSAM D5x/E5x (FD-capable)
- FDCAN & bxCAN macrocells by ST Microelectronics
- FlexCAN macrocell by NXP Semiconductors (the reference manual is available for download after registration) (FD-capable)
- Bosch C_CAN macrocell as implemented in NXP LPC11Cxx etc.
While the details of their implementations vary significantly, all products offer more or less similar TX scheduling policies that can be generalized as follows:
Queue: the next frame is chosen based on its arbitration priority (low CAN ID wins); ties are resolved based on the frame’s index in the TX buffer. The insertion order is not respected.
FIFO: the next frame is chosen based on the insertion order. The arbitration priority and the position in the TX buffer are not respected.
UAVCAN/CAN requires that outgoing frames are prioritized based on their arbitration priority with ties broken by their insertion order. If the first condition is not satisfied, an inner priority inversion will occur. If the second condition is not satisfied, multi-frame transfers will not be emitted properly.
@davids5 and I have recently encountered a misleading piece of documentation published by ST Microelectronics that erroneously claims that their FDCAN controller supports the correct prioritization policy, but this description does not match the actual behavior implemented in hardware:
Given these limitations, a correct implementation has to manage transmission scheduling in software, keeping at most one frame with the given CAN ID in the hardware transmission buffer, which should be configured in the Queue mode. Relevant considerations are given in the UAVCAN Specification, section 184.108.40.206 Inner priority inversion.