dakejahl opened a new pull request, #19957: URL: https://github.com/apache/nuttx/pull/19957
## Summary `imxrt_transmit()` picks the lowest free TX mailbox. FlexCAN breaks an arbitration tie between mailboxes holding *equal* CAN IDs by taking the lowest mailbox number, so refilling a just-drained low mailbox while older frames are still pending in higher ones puts the newer frame on the wire first. Every frame of a multi-frame transport transfer carries the same CAN ID, so this reorders transfers. `imxrt_txdone_work()` re-polls after each individual TX completion, which is exactly the condition that triggers it. This hands out a mailbox above every pending one instead, and wraps back to the bottom only once the ring has drained. Ordering is then guaranteed regardless of transfer length; the cost is that the ring stalls at a wrap instead of refilling immediately. ## Impact i.MX RT boards using SocketCAN with any multi-frame protocol on top. Single-frame traffic is unaffected — it cannot be reordered. `s32k1xx_flexcan.c` and `s32k3xx_flexcan.c` select a mailbox the same way and look to have the same defect, but I have no S32K hardware and have deliberately left them alone. ## Testing i.MX RT1176 (ARK FMU-v6XRT), FlexCAN1 at 1 Mbit, DroneCAN, measured on the wire with a separate USB-CAN analyser decoding CAN-ID and tail byte per frame. A GNSS node on the same bus acted as the control: its 10-frame transfers were flawless in every capture, which rules out the bus and the analyser and places the fault on the i.MX RT transmit path. Before, over 60 s: | stream from the i.MX RT | frames | transfers | corrupt | |---|---|---|---| | 4-frame message | 240 | 60 | 6.7% | | 6-frame message | 360 | 60 | **81.7%** | | single-frame messages | 897 | 897 | 0% | After this patch the 4-frame stream is clean. The 6-frame stream drops to 40%, and the rest was two further bugs above this driver (frames discarded on a full ring rather than retried, and a queue bypass in the CAN stack) — with all three fixed: **0 corrupt transfers in 84 594 frames over 5 minutes**, then 35 029 more. Sanity-checked that constraining allocation further is not an option: `CONFIG_IMXRT_FLEXCAN_TXMB=1`, or serialising to one frame in flight, stops transmission entirely, because a 1-deep ring makes every overflow frame hit the discard path in `imxrt_transmit()`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
