Skip to content

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

Merged
dakejahl merged 4 commits into
px4_firmware_nuttx-10.3.0+from
dakejahl/imxrt-flexcan-tx-and-errors
Sep 1, 2026
Merged

[BACKPORT] arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS.#401
dakejahl merged 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, now merged upstream as fbe3468, 60ef78f and eb40eed, cherry-picked here in that order. The first commit is apache/nuttx dd53c34, which upstream already had and #20008 therefore does not carry: SIOCSCANBITRATE requires the interface down. 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 of #20008 (3e2f28e) is not backported: this tree's SocketCAN drivers have diverged, so it is whitespace churn against files that no longer match upstream.

The same set is backported to px4_firmware_nuttx-12.12.0+ in #404.

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>
@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
csanchezdll and others added 4 commits September 1, 2026 13:17
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.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
(cherry picked from commit fbe3468)
… NETDEV_CAN_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>
(cherry picked from commit 60ef78f)

Backport note: this tree has no NETDEV_CAN_STATE_IOCTL, and the case
block keeps the netdev_ifr_dev() lookup pattern of this branch.
…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.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
(cherry picked from commit eb40eed)
@dakejahl
dakejahl force-pushed the dakejahl/imxrt-flexcan-tx-and-errors branch from 70bd9ae to e173d2f Compare September 1, 2026 19:19
@dakejahl
dakejahl merged commit b0e70b2 into px4_firmware_nuttx-10.3.0+ Sep 1, 2026
@dakejahl
dakejahl deleted the dakejahl/imxrt-flexcan-tx-and-errors branch September 1, 2026 19:39
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Sep 1, 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>
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Sep 1, 2026
Picks up PX4/NuttX#401 so SIOCGCANERRORS, SIOCSCANBITRATE-requires-ifdown
and NETDEV_CAN_IOCTL are in the tree the SocketCAN changes need. Also
includes PX4/NuttX#399 (STM32F412VG/CG chip selections), which landed
between main's gitlink and #401.

Assisted-by: Grok:grok-4.6
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Sep 1, 2026
…ketCAN (#28457)

* fix(uavcan): report FlexCAN bus state and error counters on SocketCAN

The SocketCAN platform driver returned 0 from getErrorCount(),
getRxQueueOverflowCount() and isInBusOffState(), so a controller sitting
error-passive or bus-off was invisible from `uavcan status` and the
can_interface_status topic on every i.MX RT board. Read them through
NuttX's SIOCGCANERRORS instead, and print fault confinement, TEC/REC and
RX overruns per interface. Builds without the ioctl keep the old zeros.

* fix(uavcan): apply UAVCAN_BITRATE on SocketCAN

CanDriver::init() ignored its bitrate argument, so the controller stayed
at the Kconfig rate and a bus configured for anything but 1 Mbit/s never
came up. Program the nominal rate through SIOCSCANBITRATE when it differs
from what the driver reports, keeping the data-phase settings untouched.

The driver applies the timing at the next ifup, so the interface is taken
down around the request. Older PX4/NuttX restarted a running controller
from inside the ioctl instead, which on FlexCAN with ECC RAM
initialisation is a bus fault; against that NuttX the rate is left as
configured with a warning.

* fix(boards): switch SocketCAN defconfigs to NETDEV_CAN_IOCTL

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>

* chore(nuttx): bump NuttX to the px4_firmware_nuttx-10.3.0+ tip

Picks up PX4/NuttX#401 so SIOCGCANERRORS, SIOCSCANBITRATE-requires-ifdown
and NETDEV_CAN_IOCTL are in the tree the SocketCAN changes need. Also
includes PX4/NuttX#399 (STM32F412VG/CG chip selections), which landed
between main's gitlink and #401.

Assisted-by: Grok:grok-4.6
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
dakejahl added a commit to PX4/PX4-Autopilot that referenced this pull request Sep 2, 2026
Picks up PX4/NuttX#406, which sets SRAM1_END to 0x20040000 for the
F412. The gitlink is the 10.3 tip, so this also carries PX4/NuttX#401.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
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