RANGING_BEACON.time_usec is in the sender's clock domain (Unix epoch or
sender boot time, per the MAVLink spec). handle_message_ranging_beacon copied
it straight into timestamp_sample, unlike every other external-aiding handler
in this file (mocap, vision odometry, landing_target_pose, gps_input target),
which all call _mavlink_timesync.sync_stamp() first.
EKF2 trusts the uORB producer to have already normalized the timestamp: the
ranging beacon ring buffer and controlRangingBeaconFusion() compare
sample.time_us directly against imu_delayed.time_us, both expected to be in
the local hrt_absolute_time() domain. Left unsynced, the mismatch starves or
corrupts beacon fusion depending on which clock domain is larger.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: kofemolka <kubovich@gmail.com>
The fixed wing loiter tests were not running because the test filter did not match.
Also the test was failing because the altitude threshold when to stop checking the "established on loiter" criteria was lower than the fixed wing altitude acceptance radius, so the test was always failing.
* Add handling for COMMAND_LONG & TIMESYNC
* mavlink: handle COMMAND_INT and scope TIMESYNC in gimbal mode
Address review feedback: TIMESYNC is now handled inside the switch so SYSTEM_TIME can no longer reach MavlinkTimesync and adjust the system clock from a gimbal-mode port. COMMAND_INT is handled through the same allowlist as COMMAND_LONG, factored into a shared helper.
The ark_fmu-v6xrt_allyes target overflows its 4M-128K flash region since
the NuttX 12.12.0 upgrade grew the image to 99.94% and the next small
module change (https://github.com/PX4/PX4-Autopilot/pull/28476) tipped
it over. The ARK board was copied from px4/fmu-v6xrt before that upgrade
raised the px4 allyes region to 6M, so the copy kept the old limit.
allyes is a CI coverage build that compiles every module and is never
flashed. The region length is only an artificial cap on programming
time.
Set both allyes scripts to 8M-128K so they stay identical and leave
headroom for the coverage build to keep growing.
After recent modification to the SIH lockstep, the rover modules were not working anymore.
This commit fixes the issues and makes the rover modules work with the SIH lockstep again.
* fix(commander): allow VTOL to register fixed-wing setpoint type from MC form
isSetpointTypeValid() rejected SetpointType::FixedwingLateralLongitudinal
whenever vehicle_type != VEHICLE_TYPE_FIXED_WING. Since a VTOL always
boots (and stays, until it actually transitions) in ROTARY_WING form,
this made it impossible for an external mode to register this setpoint
type up front in order to command the vehicle's own first transition to
fixed-wing - registration is a one-time, synchronous step performed at
mode construction, before the vehicle has ever flown.
Thread the vehicle's is_vtol flag down to isSetpointTypeValid() and
accept FixedwingLateralLongitudinal when is_vtol is true, regardless of
the vehicle's current dynamic form. A VTOL is capable of fixed-wing
control even while currently multicopter, precisely because it is about
to transition.
* Update src/modules/commander/ModeUtil/setpoint_types.cpp
Co-authored-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
* Update src/modules/commander/ModeUtil/setpoint_types.hpp
Co-authored-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
---------
Co-authored-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
* fix(can-flow-mr): use STM32F412VG and 960K of app flash
The part is STM32F412VGH6 (100-pin, 1MB), not the 48-pin 512KB CE.
App flash starts at 0x08010000 after the 64K bootloader+params window,
so the region is 960K, not 928K.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(boards): select STM32F412VG on the 100-pin 1MB ARK cannodes
Teseo, X20, F9P, and Septentrio/MOSAIC/G5 GPS modules use
STM32F412VGH6, same as Flow MR. They were still selecting the
48-pin 512KB CE and a 928K app region that double-counted params.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ark/cannode): use STM32F412CG and 960K of app flash
The part is STM32F412CGU6, not the 512KB CE. App flash starts at
0x08010000 after the 64K bootloader+params window, so the region is
960K, not 928K.
* fix(ark/mag): use STM32F412VG and 960K of app flash
The part is STM32F412VGH6, not the 48-pin 512KB CE, and the app region
after the 64K bootloader+params reservation is 960K, not 928K.
* docs(boards): fix the F412 SRAM description in the cannode linker scripts
The F412 has one contiguous 256KB SRAM at 0x20000000. The block list
these scripts carried is F42x boilerplate and describes memory the part
does not have.
* fix(ark/dist): use STM32F412VG and 960K of app flash
The part is STM32F412VGH6, not the 48-pin 512KB CE. App flash starts at
0x08010000 after the 64K bootloader+params window, so the region is
960K, not 928K.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(boards): give F412 cannodes a 256K SRAM region (#28498)
NuttX now ends the F412 heap at 0x20040000. The linker scripts still
capped .data/.bss at 192K, leftover from the F42x split.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* docs(boards): fix the F412 SRAM description on the 512K ARK cannodes
The F412 has one contiguous 256KB SRAM at 0x20000000. The block list
these scripts carried is F42x boilerplate and describes memory the part
does not have.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(ark/cannode): drop the PH1 boot jumper defines
PH1 is OSC_OUT for the HSE crystal. The jumper option was already
undefined, so these defines could not be enabled without stopping
the clock.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(boards): correct ARK cannode I2C bitbang pins
The bitbang GPIO defines did not match the schematic nets, so a bus reset would drive the wrong pins.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
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
* fix(uavcan): apply UAVCAN_BITRATE on FlexCAN again
58dfff0de7 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 db6f7ec304, 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.
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>
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>
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>
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>
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>
Main removed this file in f05739035e (#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 upgrade defconfig sweep (04c00266e5) 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>
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 (8a8f32699b).
Assisted-by: Claude:claude-fable-5
Signed-off-by: Ramon Roche <mrpollo@gmail.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>
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>
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.
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
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>
* fix(navigator): preserve VTOL mode in direct mission RTL
Remove the unconditional multicopter-to-fixed-wing transition from direct mission-land RTL so the return uses the VTOL mode active when RTL starts. This allows an MC-mode vehicle to proceed through the mission landing sequence instead of becoming stuck after an unnecessary forward transition.
Add module-level and MAVSDK SITL regressions covering an airborne multicopter-mode VTOL with a planned mission landing.
Refs #27817
Refs #24323
Assisted-by: Codex:gpt-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
* fix(navigator): drop the fixed wing transition from the fast RTL modes too
The fast and the reverse mission RTL carried the same request for a
transition to fixed wing as the direct mission land RTL. The VTOL
attitude controller rejects that command during RTL, so a VTOL in
multicopter mode waited on it forever instead of flying the mission.
Remove both. A VTOL in multicopter mode now flies the mission RTL as a
multicopter, the same as direct RTL does. Reported in #24323.
Two unit tests pin the active item to a waypoint for a VTOL in
multicopter mode, and two MAVSDK cases fly it on the standard VTOL in
SIH: the mission landing and the reverse mission both stay in
multicopter mode to touchdown, within 5 m of the land item and of home.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
---------
Signed-off-by: Saibernard Yogendran <bernie97@seas.upenn.edu>
Commit af3cfaea25 introduced a small semantic change in _actuator_sp:
- prior to that commit it was always the output of the allocation
algorithm, i.e. if 0 thrust was allocated the _actuator_sp was 0, and
the NaN needed to stop some motors only entered the picture when
populating the actuator_motors message in publish_actuator_controls
- after that commit, we change _actuator_sp itself to be NaN when the
corresponding motor should be stopped
This breaks consumers of _actuator_sp that expect there to be a finite,
physical thrust in _actuator_sp. One such consumer is
publish_control_allocator_status, which produces NaN if the _actuator_sp
is NaN and is thus currently useless.
Fix: Convert NaNs back to zero in getAllocatedControl so all consumers
of that work as before.
* fix(dshot): emit the DShot rate that was asked for on STM32
io_timer_set_dshot_burst_mode() wrote the tick count into ARR, but an STM32 timer
period is ARR + 1 ticks, and the prescaler divided by that same tick count. Every
bit came out one tick long, so the output ran at 21/20 of the requested rate and
the 7/14 compare counts -- betaflight's, where the period really is 20 ticks --
landed on 21 and gave 33.3 %/66.7 % instead of the protocol's 37.5 %/75 %.
Measured on an ARK FMU-v6X (240 MHz timer, BDShot300) with a logic analyser:
bit period 3.500 us (+5.00 %) -> 3.333 us (-0.01 %)
bit 0 high 33.2 % -> 37.3 %
bit 1 high 66.5 % -> 74.9 %
Subtracting one from ARR alone is not enough. A tick count fixed at 20 (19, 18)
cannot divide every timer clock by every rate: 200 MHz at DShot600 would go from
+0.80 % to -4.00 % and 90 MHz from -2.00 % to -6.67 %. Choose the tick count and
the prescaler together instead, scoring the emitted rate first and the two high
times second, and derive the compare counts from the tick count that wins. That
is exact on 84, 90, 96, 108, 168, 180, 216 and 240 MHz at all three rates, and
within 0.25 % on 160 MHz and 0.80 % on 200 MHz, where no integer pair is exact.
The search only depends on the timer clock and the rate, so io_timer.c caches its
answer per timer and recomputes only if the rate changes, which is once. That
leaves the transmit path with no arithmetic at all where it previously ran a
modulo loop and two divisions on every burst and every capture.
The capture prescaler comes out of the same struct and no longer follows the
transmit tick count. It only sets the resolution of a free-running counter, so it
aims for a fixed 20 ticks per response bit, which is what keeps a one-to-three bit
run inside the interval window convert_edge_intervals_to_bitstream() accepts.
* fix(dshot): search up to 40 ticks per bit and keep the search in 32 bits
333 cycles per bit (200 MHz at DShot600, 100 MHz at DShot300) is 9 x 37, so a
ceiling of 32 ticks left those clocks at 0.79 % when 37 x 9 lands within 0.10 %.
The wider range also moves the clocks that were settling on a 39-40 % bit-0
duty onto 37.5 %.
The rounded prescaler keeps ticks * prescaler * rate within half a bit of the
timer clock, so the 64-bit compare bought nothing. The timing cache now starts
on a rate nobody asks for, so its zero-rate guard is reachable instead of
returning a zeroed struct.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
---------
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
* fix(uploader): shorten the wait for a bootloader after reboot
Reboot-to-bootloader is immediate, so this wait only has to cover USB
re-enumeration, not the reboot. Five seconds of it meant a port that was
never going to answer held up every other port on the list, and it could
outlast the window it was trying to catch: a board sits in its bootloader
for BOOTLOADER_DELAY, 3s on some boards and 5s on most, before it jumps to
the application.
With an FMU-v6C and a Black Magic probe attached, a pass over the probe's
two CDC nodes drops from 14.75s to 5.45s, and a running application is in
its bootloader 3.52s after the uploader starts.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
* fix(uploader): report ports by their /dev/serial/by-id name
A ttyACM number is handed out in plug order and says nothing about which
device it belongs to, which is awkward as soon as there is more than one
CDC device on the bus -- "Attempting reboot on /dev/ttyACM0" gives no hint
that it is a debug probe rather than the board.
Resolve each detected port back to its by-id symlink when one exists, so
every message names the device. This also collapses a duplicate: a board
is matched both by a by-id pattern and by the /dev/ttyACM* catch-all, so
it was being probed twice per pass. With an FMU-v6C and a Black Magic
probe attached, detection goes from four entries with two naming the same
board to three, each identifying itself.
Linux only; elsewhere, and for ports with no symlink, paths are unchanged.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julian Oes <julian@oes.ch>
---------
Signed-off-by: Julian Oes <julian@oes.ch>
The 24LC64T on I2C3_BASE is wired to LPI2C6 (X1_8/10). Manifest MTD talks I2C, so it has to run after those pins are I2C and VDD_5V_PERIPH is on, or the chip does not attach and netman cannot save.
The driver only hard-resets when SPI6_nRESET_EXTERNAL1 / SPI6_RESET are defined. v6xrt named the pin GPIO_SPI6_nRESET_EXTERNAL1, so SCH16T never left software reset.