feat(platforms): upgrade NuttX to 12.12.0 - #26215
Conversation
🔎 FLASH Analysispx4_fmu-v5x [Total VM Diff: 5336 byte (0.25 %)]px4_fmu-v6x [Total VM Diff: 7400 byte (0.36 %)]Updated: 2026-04-01T12:19:51 |
c57843c to
dc431f3
Compare
|
Hi @PetervdPerk-NXP, @AlexKlimaj, This is a very large change (around 5,000 commits in NuttX and many changes in the common code), and to be honest I’m not particularly excited about the approach:
Especially when this then requires patching and reviewing fixes like the following just to get things running: This kind of patching being needed already shows that interfaces don't behave the same anymore and we need to understand this and not start patching until it somehow works. This one was detected, but I am very sure there are a lot more of those "quirks" that will occur less often and only in specific situations. Don’t get me wrong, I like the idea of us staying up to date with NuttX. However, with a migration that appears to be largely AI-driven, it effectively shifts a significant amount of risk and workload onto the reviewers and flight testers. They now need to ensure that no low-level or timing-related issues are introduced that might only show up sporadically in real operation. With that in mind, I’d like to ask a few questions:
|
dc431f3 to
11b08f9
Compare
|
Hi @alexcekay,
Beyond Kconfig symbol churn, the PR is quite modest. My reason to upgrade is primarily to enable i.MX93/i.MX95 hardware, which depends on a more mature RPMsg that we can’t realistically backport from our 2-3 year old NuttX. But they're are various other improvements NuttX brings which makes it worthwhile to upgrade. I sense some hesitation about upgrading. If we intend to stay on the current kernel long‑term, the migration cost will only grow. I’m happy to help push this over the line, as I did myself with the previous kernel bump 2 years ago aswell, but I’d appreciate alignment and some shared ownership. If you’d prefer I step back and focus elsewhere, let me know. |
11b08f9 to
ff41669
Compare
|
Hi @PetervdPerk-NXP, Thanks for explaining your rationale and pushing this topic.
No, as stated: Don’t get me wrong, I like the idea of us staying up to date with NuttX and appreciate
I am hesitant about the risk associated with any larger OS change (and the hours needed to debug the issues afterwards) and thus want to de-risk this and emphasize:
When this has a sort of mature state where strange quirks are not needed anymore or are at least clearly understood I would be happy to assist in reviewing it and do testing with our HW. |
845fc70 to
f6d73d0
Compare
|
ARKV6X is booting and sd card works. Doesn't look like free or ps commands work. |
|
Confirmed ethernet is working on the ARKV6X. |
Good to hear SD card works, I've already removed the
This is a bit weird, maybe procfs doesn't properly mount, does
Awesome thanks for testing. |
|
Im also interested in upgrading Nuttx. Happy to assist in bench testing and flight testing to get this over the line confidently. What I will test on my bench so long. I hope to report back in the next week. |
91f6a29 to
99280e0
Compare
|
Here's a hardfault log fault_1970_01_01_02_37_59.log |
Do you have the elf? I'll leave an RT running overnight tonight and see if it faults |
|
I haven't been able to replicate this, I left Claude hacking at it all night and nothing has come up yet, I'm going to call this a documented fluke and move on. @dakejahl here's the ELF if you want to look at this in depth px4_fmu-v6xrt_default.elf.xz.zip I will move on to testing on the Pixhawk 4 and report back. |
Update git sha's for NuttX
bootloader: update main prototype for NuttX 12.12.0 platforms/nuttx: Add wrapper for queue.h For some reason the queue.h header was moved, add this wrapper so posix and nuttx builds can both still use #include <queue.h> Fix print_load to be compatible with upstream NuttX Also Change tg_filelist -> tg_fdlist as per new NuttX Co-authored-by: Ville Juven <ville.juven@unikie.com> Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
sitl: fix NuttX 11.12.0 upgrade regressions drivers: uavcan: fix TFLM c library conflict With NuttX 12.12.0 the TFLM c library causes a conflict
boards: Disable MMC_IOC_CMD ioctl NuttX default is Y, but it's not used boards: Fix meminfo/free boards: fix libc float setting boards: Reduce flash usage Using strerr short mode Don't cache DNS entries (also saves some ram) fix(boards): kakutef7 disable optical flow ekf2 to save flash kakutef7 overflows with nuttx 12.12.0 also it doesn't have optical flow drivers anyhow. Thus disable ekf2 optical flow
NuttX 12.12 changed symbols for certain calls or inlined them.
Fix a protected kernel link failure caused by static initialization of a shared uORB::Publication in AM32Settings. Which is problematic for NuttX 12.12.0. The NuttX 12.12 PX4 protected kernel does not provide __dso_handle.
NuttX 12.12.0 changed up_assert ABI
Upgrading the NuttX apps submodule (kernel bump or switching branches then `git submodule update`) updates tracked files only. When the new revision removes an application directory, the autogenerated Kconfig a previous build left inside it is untracked, so it survives `git clean -dX`. mkkconfig.sh keeps globbing that orphaned `*/Kconfig`, whose stale `source` points at a file that no longer exists, breaking `make olddefconfig`: olddefconfig: apps/gpsutils/Kconfig:9: 'apps/gpsutils/minmea/Kconfig' not found Add a `cmake -P` helper, invoked at the end of the `clean` target, that walks the apps Kconfig graph and removes only untracked Kconfig files that source a missing path. Tracked files and the nuttx tree (whose stale artifacts are all gitignored and already dropped by `git clean -dX`) are never touched, so a `make clean` before rebuilding now migrates cleanly across the upgrade. Assisted-by: Claude:claude-opus-4.8 Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
The mcp_gpio_dev_s / gpio_pin_dev_s struct layout changed in NuttX 12.12, so use designated initializers (.gp_pintype/.gp_ops) instead of positional initialization. Co-authored-by: marinauterion <224611774+marinauterion@users.noreply.github.com> Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
Stack usage of the mcp23009/mcp23017 GPIO drivers increased with NuttX 12.12, bump STACK_MAIN to 2560. Co-authored-by: marinauterion <224611774+marinauterion@users.noreply.github.com> Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
Enable ICANON and ECHO, and map CR to NL (ICRNL) so the nshterm console echoes typed characters and processes the enter key. Co-authored-by: marinauterion <224611774+marinauterion@users.noreply.github.com> Signed-off-by: Peter van der Perk <peter.vanderperk@nxp.com>
fix(mavlink_shell): no echo of commands
The nsh output path changed architecture in NuttX 12: nuttx-apps 95f32fd018 decoupled nshlib from FILE streams, so every output call now runs vdprintf() with the stream engine and full VFS write chain on the nsh task stack. On CONFIG_DEFAULT_SMALL boards the lib_get_tempbuffer() fallback additionally compiles to alloca() on the parse path. The hardcoded 2048 byte stack overflows, and because NuttX 12 keeps the TLS block at the stack base the failure is a silent mute shell rather than a hardfault. Verified on fmu-v5x hardware: shell dead at 2048, working at 4096. Mirrors the nshterm stack fix already on this branch (8a8f326). Assisted-by: Claude:claude-fable-5 Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The upgrade defconfig sweep (04c0026) replaced CONFIG_STDIO_BUFFER_SIZE=256 with CONFIG_STDIO_DISABLE_BUFFERING=y on these two boards. On NuttX 12.12 that config hits an upstream regression (62c2b1abba): task_init_stream() only assigns fs_cookie/fs_oflags inside the buffered branch, so with unbuffered stdio every spawned task's stdout FILE is left zeroed and bound to fd 0. All printf output on the board is silently discarded, including the boot log and every shell command that prints via stdio; raw fd writes (top, dmesg) still work, which made this hard to spot. Verified on fmu-v5x hardware (fileno(stdout)==0 in spawned tasks, EACCES on flush over the MAVLink shell). Restoring buffered stdio returns these boards to their pre-upgrade configuration. The upstream fix apache/nuttx 2b1cf4238756 (post-12.12.0) should additionally be backported to px4_firmware_nuttx-12.12.0+ to cure the class for any unbuffered config. Assisted-by: Claude:claude-fable-5 Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Main removed this file in f057390 (#28185) when USB autostart moved into the cdcacm_autostart driver. The NuttX upgrade rebase brought back a NuttX 12 adaptation of it, but nothing references it in any build file, so it is 370 lines of dead code. Assisted-by: Claude:claude-fable-5 Signed-off-by: Ramon Roche <mrpollo@gmail.com>
The UAVCAN_BITRATE code merged via #28457 prints the driver's arbi_bitrate (uint32_t) with %u. On the NuttX 12.12 toolchain uint32_t is unsigned long, so -Werror=format fails every SocketCAN board (imxrt, s32k). Use PRIu32 for the uint32_t; kbps stays %u as it is a uint16_t promoted to int. Assisted-by: Claude:claude-fable-5 Signed-off-by: Ramon Roche <mrpollo@gmail.com>
NuttX 12.12.0 shares one statically allocated g_kthread_group between all kernel threads, but group_leave() guards the group_release() call behind HAVE_GROUP_MEMBERS, which is only defined when pthreads are enabled. Every bootloader config sets CONFIG_DEFAULT_SMALL=y, so DISABLE_PTHREAD defaults to y, and the first kernel thread to exit tears down the shared group and calls kmm_free() on a .bss static. The bootloader died before USB enumeration. Around 64 configs in the tree share that combination. The submodule now carries the upstream fix, apache/nuttx f20f9ff19e. The bump also picks up the backport that recombines the per-command CAN ioctl Kconfig options back into NETDEV_CAN_IOCTL. Defconfigs on this branch already reference CONFIG_NETDEV_CAN_IOCTL, which does not exist at the previously pinned commit, so SocketCAN bitrate, filter and state ioctls were silently disabled on ark/fmu-v6xrt, px4/fmu-v6xrt, nxp/mr-canhubk3, nxp/tropic-community and nxp/mr-tropic. Assisted-by: Claude:claude-opus-5 Signed-off-by: Julian Oes <julian@oes.ch>
NuttX 12.12.0 added arm_initialize_stack(), which moves thread mode onto the process stack pointer whenever CONFIG_ARCH_INTERRUPTSTACK > 7. Every bootloader config qualifies, so the bootloader now reaches arch_do_jump() with CONTROL.SPSEL set, where previously it ran on the main stack. arch_do_jump() writes the MSP and branches, but never selects it. The application therefore starts on the bootloader's PSP while its own startup code initialises a stack pointer the CPU is not using. Boards booted far enough to reach NSH and start MAVLink, then hard faulted once the stale bootloader stack was overwritten, surfacing as an assertion in Idle_Task with no useful backtrace. Clear CONTROL.SPSEL so control passes on the stack the application expects. The i.MX RT bootloader performs the same jump and its configs also exceed the interrupt stack threshold, so fix both. Verified on CubePilot CubeOrange and Pixhawk 6C; the prebuilt bootloaders for both are regenerated, as the shipped binaries have the defect. Assisted-by: Claude:claude-opus-5 Signed-off-by: Julian Oes <julian@oes.ch>
The SIOCSCANBITRATE path in CanIface::setBitRate() was gated on SIOCGCANERRORS, which the NuttX submodule bump now defines. That turned on a retune sequence that had never been compiled or run in this tree: it takes the interface down, sets the bitrate and brings it back up. Two problems surfaced on a Pixhawk v6XRT. The path did not build, because it still used IFF_DOWN, which NuttX removed; SIOCSIFFLAGS now acts on the IFF_UP request bit, so clearing it is what takes an interface down. Once it built, the board booted and then crashed a few seconds later, when uavcan started and retuned the interfaces. The driver ioctl itself is harmless and only stores the timings, so the fault is in bringing a FlexCAN interface down and back up at runtime, where ECC RAM initialisation runs again on a controller that has already been started. SIOCGCANERRORS reports whether a driver can read error counters, which says nothing about whether it can be retuned; the two capabilities only happened to arrive in the same commit. Gate on the capability that is actually meant, and keep the configured rate on the FlexCAN chips. Every board in the tree that enables SocketCAN today is FlexCAN, so this restores the behaviour those boards already had before the bump. Verified on px4_fmu-v6xrt: crashes with the retune path active, stable with the configured rate kept. Assisted-by: Claude:claude-opus-5 Signed-off-by: Julian Oes <julian@oes.ch>
The fix is upstream as f20cf4aac3 but landed after the 12.12.0 tag, so moving the submodule onto 12.12.0 dropped a fix the previous branch already carried. Backport it. Without it the group address in the IGMP header, a uint16_t[2] that decays to a pointer, is compared against INADDR_ANY, which is always false. A General Query then falls through to the group-specific branch, a group is allocated for 0.0.0.0, and joined groups never have their report timers restarted, so the querier ages out the membership and multicast delivery to the device stops. CONFIG_NET_IGMP is enabled on ark/fmu-v6xrt, px4/fmu-v6xrt, nxp/mr-canhubk3, nxp/mr-tropic and nxp/tropic-community. Assisted-by: Claude:claude-opus-5 Signed-off-by: Julian Oes <julian@oes.ch>
Kernel update changed can_ioctl_data_s bitrate unit from kbit/s to bit/s Update uavcan ioctl logic accordingly
Fixes the redefinition warnings in apps/system/dd/dd_main.c.
…ork queues for NuttX 12 (#28509) * fix(uavcan): apply UAVCAN_BITRATE on FlexCAN again 58dfff0 turned the SIOCSCANBITRATE path off for i.MX RT, S32K and Kinetis, which is every board in the tree that builds SocketCAN, so UAVCAN_BITRATE stopped doing anything at all. It was written before db6f7ec, and the crash it works around is that commit's bug: the driver reports bit/s on NuttX 12 and the caller still divided by 1000, so a 1 Mbit/s board asked its controller for 1000 bit/s on every boot. Benched on an ARK FMU-v6XRT with the gate removed: 1 Mbit/s -> 500 kbit/s -> 1 Mbit/s round-trips with both DroneCAN nodes coming back OPERAT, buses error-active, no fault. Requesting a rate the controller cannot reach is also survivable now -- it is reported and the configured rate is kept, where before a negative return from here made CanDriver::init() give up and DroneCAN never started. The %u for a uint32_t is fixed as well; nothing compiled this branch while the gate was in place. * fix(work_queue): size the uavcan and TTY work queues for NuttX 12 NuttX 12.12 costs a few hundred bytes of stack on the paths that go through the file layer, and that is more than these two defaults left spare. Measured against the same PX4 tree on 10.3.0: wq:uavcan 2860/3728 -> 3184/3736 (ARK FMU-v6X, two DroneCAN GNSS nodes) wq:ttyS4 1088/1704 -> 1432/1712 (ARK FMU-v6XRT, crsf_rc) load_mon reports wq:ttyS4 low on stack with 280 bytes left, and wq:uavcan sits at 85 % of its own. 4096 and 2048 restore the margin the 10.3.0 figures had.
Advance the NuttX submodule from 1db7c59 to the fork branch tip f07832f0 (px4_firmware_nuttx-12.12.0+), pulling in three backports: - FlexCAN: store the TX deadline only once the frame is sent - FlexCAN: assign MAXMB rather than OR-ing it in - STM32F412: set SRAM1_END to 256KiB (#407) The two FlexCAN backports are the apache/nuttx#19970 follow-ups the branch was missing; they land the corrected i.MX RT TX-abort behavior. Signed-off-by: Ramon Roche <mrpollo@gmail.com> Assisted-by: Claude:claude-fable-5-1
|
Thanks @PetervdPerk-NXP and everyone else that helped push this forward 🚀 |
Continuation of #26198 but now the NuttX repo's are on the PX4 repositories.
Some reasons why to upgrade NuttX
PX4 Test Plan
sd_benchand measure write speedtopwhen the system is armeduorb topwhen the system is armedmavlink status