arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS. - #20008
Open
dakejahl wants to merge 4 commits into
Open
arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS.#20008dakejahl wants to merge 4 commits into
dakejahl wants to merge 4 commits into
Conversation
dakejahl
requested review from
hartmannathan,
jerpelea,
michallenc and
xiaoxiang781216
as code owners
August 30, 2026 02:56
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 30, 2026
… counters. TX-complete and the deadline watchdog each queued their own callback on the same work_s, and work_queue() cancels whatever is pending when a work_s is reused, so whichever ran second was dropped: deadlines were left set, the TX interrupt mask stayed off, or expired frames were never aborted. Both now queue imxrt_tx_work(), which retires completions before it aborts expired mailboxes. Add SIOCGCANERRORS so a socket can read fault confinement, TEC/REC, a monotonic bus error count and the RX mailbox overrun count. The error count is sampled from the clear-on-read ESR1 error flags at every driver entry rather than from ERRINT, which fires per error frame and storms at bus rate once the bus is dead. Frames the CAN socket layer drops for want of an IOB now count as rx_dropped in the netdev statistics. Upstream: apache/nuttx#20008
The SIOCxCANxxFILTER cases in fdcan_netdev_ioctl() call stm32_addextfilter(), stm32_delextfilter(), stm32_addstdfilter() and stm32_delstdfilter(), none of which exist anywhere in the tree. The block only ever compiled because no stm32h7 config enables NETDEV_CAN_FILTER_IOCTL; enabling it breaks the link. The commands now fall through to the existing -ENOTSUP default, which is also what a caller observed before. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
…_IOCTL NETDEV_CAN_BITRATE_IOCTL, NETDEV_CAN_FILTER_IOCTL and NETDEV_CAN_STATE_IOCTL guarded identical option blocks, and every SIOCxCANxxx case in netdev_ifr_ioctl() forwarded a member of the same ifr_ifru union to d_ioctl(). One option and one case block now cover all of the CAN commands; drivers and defconfigs are updated to the new name. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
TX-complete and the deadline watchdog each queued their own callback on the same work_s, and work_queue() cancels whatever is pending when a work_s is reused, so whichever ran second was dropped: deadlines were left set, the TX interrupt mask stayed off, or expired frames were never aborted. Both now queue imxrt_tx_work(), which retires completions before it aborts expired mailboxes. Add SIOCGCANERRORS so a socket can read fault confinement, TEC/REC, a monotonic bus error count and the RX mailbox overrun count. SIOCGCANSTATE reports sleep/operational, not fault confinement, hence a new command. The error count is sampled from the clear-on-read ESR1 error flags at every driver entry rather than from ERRINT, which fires per error frame and storms at bus rate once the bus is dead. Frames the CAN socket layer drops for want of an IOB now count as rx_dropped in the netdev statistics as well as in the global CAN statistics. Tested on an i.MX RT1176 (ARK FMU-v6XRT) running PX4 with two DroneCAN nodes: unplugging one node the ioctl reports error-passive, TEC 128, REC 0 and a monotonic error count, matching ECR/ESR1 read over SWD at 20 Hz, while the other interface stays error-active with zero errors. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
Whitespace only: blank lines after declarations, misindented switch bodies and brace alignment. nxstyle runs over the whole of any file a change touches, and merging the CAN ioctl options renames a config in every SocketCAN driver. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl
force-pushed
the
dakejahl/imxrt-flexcan-errors
branch
from
August 30, 2026 20:40
3f3a38b to
1a8dfc8
Compare
dakejahl
requested review from
JorgeGzm,
acassis,
anchao,
btashton,
davids5,
gustavonihei,
pussuw and
raiden00pl
as code owners
August 30, 2026 20:40
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 30, 2026
The SIOCxCANxxFILTER cases in fdcan_netdev_ioctl() call stm32_addextfilter(), stm32_delextfilter(), stm32_addstdfilter() and stm32_delstdfilter(), none of which exist anywhere in the tree. The block only ever compiled because no stm32h7 config enables NETDEV_CAN_FILTER_IOCTL; enabling it breaks the link. The commands now fall through to the existing -ENOTSUP default, which is also what a caller observed before. Backport of the same commit on apache/nuttx#20008. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 30, 2026
… NETDEV_CAN_IOCTL. NETDEV_CAN_BITRATE_IOCTL, NETDEV_CAN_FILTER_IOCTL and NETDEV_CAN_ERROR_IOCTL guarded identical option blocks, and every SIOCxCANxxx case in netdev_ifr_ioctl() forwarded a member of the same ifr_ifru union to d_ioctl(). One option and one case block now cover all of the CAN commands; drivers and defconfigs are updated to the new name. Backport of the same commit on apache/nuttx#20008, requested in its review. This tree has no NETDEV_CAN_STATE_IOCTL, and the case block keeps the netdev_ifr_dev() lookup pattern of this branch. Assisted-by: Claude:claude-fable-5 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 31, 2026
The SIOCxCANxxFILTER cases in fdcan_netdev_ioctl() call stm32_addextfilter(), stm32_delextfilter(), stm32_addstdfilter() and stm32_delstdfilter(), none of which exist anywhere in the tree. The block only ever compiled because no stm32h7 config enables NETDEV_CAN_FILTER_IOCTL; enabling it breaks the link. The commands now fall through to the existing -ENOTSUP default, which is also what a caller observed before. Backport of the same commit on apache/nuttx#20008. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 31, 2026
… NETDEV_CAN_IOCTL. NETDEV_CAN_BITRATE_IOCTL and NETDEV_CAN_FILTER_IOCTL guarded identical option blocks, and every SIOCxCANxxx case in netdev_ifr_ioctl() forwarded a member of the same ifr_ifru union to d_ioctl(). One option and one case block now cover all of the CAN commands; drivers and defconfigs are updated to the new name. Backport of the same commit on apache/nuttx#20008, requested in its review. This tree has no NETDEV_CAN_STATE_IOCTL, and the case block keeps the netdev_ifr_dev() lookup pattern of this branch. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl
added a commit
to PX4/NuttX
that referenced
this pull request
Aug 31, 2026
…ERRORS. TX-complete and the deadline watchdog each queued their own callback on the same work_s, and work_queue() cancels whatever is pending when a work_s is reused, so whichever ran second was dropped: deadlines were left set, the TX interrupt mask stayed off, or expired frames were never aborted. Both now queue imxrt_tx_work(), which retires completions before it aborts expired mailboxes. Add SIOCGCANERRORS so a socket can read fault confinement, TEC/REC, a monotonic bus error count and the RX mailbox overrun count. SIOCGCANSTATE reports sleep/operational, not fault confinement, hence a new command. The error count is sampled from the clear-on-read ESR1 error flags at every driver entry rather than from ERRINT, which fires per error frame and storms at bus rate once the bus is dead. Frames the CAN socket layer drops for want of an IOB now count as rx_dropped in the netdev statistics as well as in the global CAN statistics. Tested on an i.MX RT1176 (ARK FMU-v6XRT) running PX4 with two DroneCAN nodes: unplugging one node the ioctl reports error-passive, TEC 128, REC 0 and a monotonic error count, matching ECR/ESR1 read over SWD at 20 Hz, while the other interface stays error-active with zero errors. Upstream: apache/nuttx#20008 Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
xiaoxiang781216
approved these changes
Aug 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two changes to the i.MX RT FlexCAN SocketCAN driver, plus the network-layer plumbing the second one needs. Reworked per review: the per-command CAN ioctl options are merged into a single
NETDEV_CAN_IOCTL.NETDEV_CAN_BITRATE_IOCTL,NETDEV_CAN_FILTER_IOCTLandNETDEV_CAN_STATE_IOCTLguarded identical option blocks, and every SIOCxCANxxx case innetdev_ifr_ioctl()forwarded a member of the sameifr_ifruunion tod_ioctl(). They are merged into oneNETDEV_CAN_IOCTLoption and one case block that passes the union's address; drivers and defconfigs are updated to the new name. The stm32h7 FDCAN filter cases calledstm32_addextfilter(),stm32_delextfilter(),stm32_addstdfilter()andstm32_delstdfilter(), which exist nowhere in the tree and only ever compiled because no stm32h7 config enablesNETDEV_CAN_FILTER_IOCTL; a preparatory commit removes them so the commands fall through to the existing-ENOTSUPdefault.imxrt_txdone_work()andimxrt_txtimeout_work()sharedpriv->irqwork.work_queue()cancels a pending callback when itswork_sis reused, so whichever was queued second silently replaced the first: deadlines left set,IMASK1TX bits left off, or expired frames never aborted. Both paths now queue one worker,imxrt_tx_work(), which retires completions before aborting expired mailboxes.SIOCGCANERRORSioctl (_SIOC(0x0045), behindCONFIG_NETDEV_CAN_IOCTL) returnsstruct can_ioctl_errors_s: fault-confinement state, TEC, REC, a monotonic bus-error count and the RX mailbox overrun count.SIOCGCANSTATEreports sleep/operational, not fault confinement, so this is a distinct command. The driver counts bus errors by sampling the clear-on-readESR1error flags at every driver entry (TX work, RX work, the ioctl) instead of enablingERRINT, which fires per error frame and storms at bus rate on a dead bus. Frames the CAN socket layer drops for want of an IOB now also count asrx_droppedin the per-device netdev statistics.Impact
SIOCGCANERRORS, implemented for i.MX RT FlexCAN only; other SocketCAN drivers return-ENOTTY.NETDEV_CAN_BITRATE_IOCTL,NETDEV_CAN_FILTER_IOCTLandNETDEV_CAN_STATE_IOCTLno longer exist; configs that enabled any of them must enableNETDEV_CAN_IOCTLinstead (in-tree defconfigs are updated). A board that enabled only one command's option now compiles every CAN ioctl case its driver implements.include/net/if.hgainsstruct can_ioctl_errors_sand one union member inifreq/lifreq. The drivers touched by the rename get whole-file nxstyle fixes (whitespace only, token streams verified identical).ifreqdoes not grow). NO for the three removed config names, see User above.Testing
Build:
imxrt1170-evk:canwithCONFIG_NETDEV_CAN_IOCTL=y,nucleo-h743zi2:socketcan,imx95-evk:can,sim:dynconns, arm-none-eabi-gcc 13.2.1, host Linux.Runtime: i.MX RT1176 (ARK FMU-v6XRT) running PX4 with this change carried on the PX4 NuttX fork (PX4/NuttX#401), two DroneCAN nodes, one per FlexCAN interface, 1 Mbit/s.
Before (stub
getErrorCount(),isInBusOffState()): an error-passive controller is invisible from the socket API;uavcan statusprintsHW errors: 0regardless.After, unplugging the CAN2 node for 10 s and reading the ioctl every 2 s (console) while
ECR/ESR1were read over SWD at 20 Hz:With the two nodes moved to 500 kbit/s while the controller stayed at 1 Mbit/s, the ioctl reads
error-passive (TEC 0, REC 128)while the controller transmits nothing and(TEC 128, REC 133)while it does. WithNETDEV_STATISTICSenabled,/proc/net/can0showedDroppedadvancing (445 frames in 300 s at 3260 frames/s with a 24-buffer IOB pool), which the global CAN statistics alone did not attribute to an interface.