Skip to content

[BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS. - #401

Open
dakejahl wants to merge 4 commits into
px4_firmware_nuttx-10.3.0+from
dakejahl/imxrt-flexcan-tx-and-errors
Open

[BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS.#401
dakejahl wants to merge 4 commits into
px4_firmware_nuttx-10.3.0+from
dakejahl/imxrt-flexcan-tx-and-errors

Conversation

@dakejahl

@dakejahl dakejahl commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Backport of apache/nuttx#20008 plus apache/nuttx dd53c34 (first commit).

Commit order matches the rewritten upstream PR: SIOCSCANBITRATE requires the interface down (already on apache master, not in #20008), then the stm32h7 FDCAN filter stubs are removed, then the per-command CAN ioctl options are merged into NETDEV_CAN_IOCTL, then one TX worker for completions and deadline aborts plus SIOCGCANERRORS. PX4 side is PX4/PX4-Autopilot#28457, whose board defconfigs enable NETDEV_CAN_IOCTL (the old names are silently dropped, taking the whole CAN ioctl block with them).

The nxstyle commit on #20008 is not backported: this tree's SocketCAN drivers have diverged, and PX4/NuttX CI does not run nxstyle over whole files.

Bench (ARK FMU-v6XRT, two nodes, 2026-08-29): unplugging one node, the ioctl reports error-passive, TEC 128, REC 0 for the gap and a monotonic error count, matching ECR/ESR1 read over SWD at 20 Hz sample for sample, while the other interface stays error-active with 0 errors. UAVCAN_BITRATE 500000 through ifdown → set → ifup brings both nodes up at 500 kbit/s. The T0–T7 CAN regression suite passes with the pre-existing IOB-drop failure of T2 unchanged from main. ark_fmu-v6xrt_default rebuilt with CONFIG_NETDEV_CAN_IOCTL=y, error path confirmed linked.

Problem

imxrt_txdone_work and imxrt_txtimeout_work shared priv->irqwork. work_queue() cancels a pending callback when its work_s is reused, so whichever was queued second silently replaced the first: deadlines left set, IMASK1 TX bits left off, or expired frames never aborted.

The socket layer had no way to see the controller's error state. libuavcan's getErrorCount() / isInBusOffState() are stubs on every SocketCAN board, and the last error-passive failure on this driver was only diagnosed by reading ECR/ESR1 over SWD.

SIOCSCANBITRATE called imxrt_ifup() on a running controller. With CONFIG_IMXRT_FLEXCAN_ECC that zeroes the FlexCAN RAM outside freeze mode, which is a bus fault: imxrt_busfault in wq:uavcan on every boot once UAVCAN_BITRATE differs from the Kconfig rate.

Solution

Both paths queue imxrt_tx_work(), which retires completions before aborting expired mailboxes. SIOCGCANERRORS (_SIOC(0x0045), behind NETDEV_CAN_IOCTL) fills can_ioctl_errors_s. Bus errors are counted by sampling the clear-on-read ESR1 error flags at every driver entry (TX work, RX work, the ioctl) instead of enabling ERRINT, which fires per error frame and storms at bus rate on a dead bus. rx_overruns counts CODE=OVERRUN mailboxes. CAN frames the socket layer drops for want of an IOB now count as rx_dropped under NETDEV_STATISTICS.

SIOCSCANBITRATE stores the timings and the netdev layer returns -EBUSY while the interface is up, as upstream does since dd53c34; the caller takes the interface down, sets the rate and brings it up.

NETDEV_CAN_BITRATE_IOCTL and NETDEV_CAN_FILTER_IOCTL guarded identical option blocks, and every SIOCxCANxxx case forwarded a member of the same ifr_ifru union to d_ioctl(); one option and one case block now cover all of them (this tree has no NETDEV_CAN_STATE_IOCTL).

Upstream SIOCGCANSTATE (0x0041) is sleep/operational, not fault confinement, hence a new command. Submitted upstream as apache/nuttx#20008 (without the bitrate-down commit, which upstream already has).

@dakejahl
dakejahl marked this pull request as ready for review August 30, 2026 01:42
@dakejahl dakejahl changed the title arch/arm/src/imxrt: Unify FlexCAN TX work and expose error counters [BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and expose error counters. Aug 30, 2026
@dakejahl
dakejahl force-pushed the dakejahl/imxrt-flexcan-tx-and-errors branch from 10e032f to 93ad415 Compare August 30, 2026 03:18
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Aug 30, 2026
PX4/NuttX#401 now carries the apache-review rework that merges the
per-command CAN ioctl options into NETDEV_CAN_IOCTL. The old BITRATE
and FILTER lines stay so the bitrate ioctl keeps working on the
current NuttX gitlink, where the merged option does not exist yet and
is silently dropped.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Aug 30, 2026
PX4/NuttX#401 merges the per-command CAN ioctl options into a single
NETDEV_CAN_IOCTL, so the old BITRATE/FILTER/ERROR names no longer
exist there and would be silently dropped, disabling the whole CAN
ioctl block. Requires the NuttX gitlink to include PX4/NuttX#401;
until that bump the option is dropped against the old tree and the
bitrate/error ioctls are inert at runtime (the code builds either
way). mr-canhubk3 is included so its bitrate ioctl survives the bump.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
csanchezdll and others added 4 commits August 30, 2026 18:37
Previously, SIOCSCANBITRATE brought the iterface up to ensure changes
where immediately applied. This was confusing, see
https://lists.apache.org/thread/g8d0m6yp7noywhroby5br4hxt3r4og2c
Now SIOCSCANBITRATE fails is interface is up.
All existing SocketCAN drivers updated.

Signed-off-by: Carlos Sanchez <carlossanchez@geotab.com>
(cherry picked from commit dd53c34)

Backport note: imx9 is not in this tree. On i.MX RT the old behaviour
is a bus fault, not just confusing: imxrt_ifup() from the ioctl runs
imxrt_init_eccram() on a running controller, and the FlexCAN RAM it
zeroes is only writable in freeze mode. Measured on an ARK FMU-v6XRT
with UAVCAN_BITRATE 500000 (PX4/PX4-Autopilot#28457): imxrt_busfault
in wq:uavcan on every boot.
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>
… 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>
…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>
@dakejahl
dakejahl force-pushed the dakejahl/imxrt-flexcan-tx-and-errors branch from 23576ef to 70bd9ae Compare August 31, 2026 00:39
@dakejahl dakejahl changed the title [BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and expose error counters. [BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS. Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants