Commit Graph

2218 Commits

Author SHA1 Message Date
Cade Andersen
d067ce19c3 fix(macos): trust osrf/simulation tap in --sim-tools block (#27891)
Homebrew 6.0+ refuses to load formulae from untrusted third-party taps. This adds a trusted block for OSRF taps. 

Signed-off-by: Cade Andersen <cadecandersen@gmail.com>
2026-07-14 01:55:16 -04:00
Jonas Perolini
5ea3cf8cb9 feat(navigator): extend detect and avoid module to follow regulatory standards such as ASTM F3442 (#26815)
* feat(navigator): extend detect and avoid module to follow regulatory standards such as ASTM F3442

* docs(docs): minor subedit

* refactor(navigator): reduce flash by grouping notif into same events

* docs(daa): Improve docs readability with ::: details blocks

* fix(navigator): single event when on ground with conflict

* refactor(boards): increase flash length from 4M - 128k to 5M - 128k

* rework(general): define DAA standard at build with new CONFIG_NAVIGATOR_ADSB_F3442

* clean(navigator): minor changes to clean the PR

* feat(boards): add CONFIG_NAVIGATOR_ADSB_FAKE_TRAFFIC in visionTargetEstStatic.px4board

* rework(daa): reduce amount of abstractions and minor cleaning

* refactor(boards): allyes revert flash length to 4M-128K

* refactor(boards): allyes increase flash length to 5M-128K

* rework(daa): rework event notifications to improve clarity

* docs(docs): move details inside of ::: details block

* docs(docs): run npx prettier

* refactor(daa): avoid void mutator functions

* docs(docs): Improve Python helper to decode daa unique id

* rework(daa): move encoded id handling to the adsb lib and refactor on_active

* refactor(daa): naming and zero init

* fix(daa): move dataman dep from daa level to unit test level

* refactor(daa): define common daa_input and rework process_transponder_report

* fix(daa): remove stale todo

* refactor(daa): rename crosstrack_based_daa to crosstrack_standard

* refactor(daa): rename F34_ params to DAA_

* docs(docs): revert changes to autogenerated docs

* docs(docs): Add Detect And Avoid in index.md

* refactor(daa): update message on init failed

* refactor(daa): only publish most_urgent conflict once in on_active()

* refactor(daa): move conflict buffer handling in the adsb lib

* refactor(daa): move notifications into new class ConflictNotifier and only notify once per cycle

* refactor(daa): uninit _cycle_changes to store into .bss (and save flash)

* docs(docs): remove unused image link

* refactor(daa): move automated action policy to the adsb lib

* refactor(daa): move self detection into adsb lib as DaaTrafficFilter

* refactor(daa): minor changes in unit tests

* refactor(daa): merge DaaTrafficFilter and DaaEncoding

* fix(daa): fix CI by removing navigator from the DAA deps

* refactor(daa): reduce stack size

* fix(daa): advertise _fake_traffic_pub in constructor

* refactor(daa): Comments only,  simplify and reduce comments

* fix(daa): brief comment missing end star

* Disable CONFIG_NAVIGATOR_ADSB in ark_fpv_default board

* docs(docs): General clarifications and remove the 1.18 badge

* refactor(daa): cleaning

* refactor(daa): minor cleaning

* refactor(adsb): simplify conflict tracker assuming push_back cannot fail

* build(cmake): cleaner fix to protect regex alternations

* refactor(daa): Crosstrack, remove unit test requiring finite yaw (yaw not used by standard)

* refactor(daa): minor cleaning and fix callsign to uint64

---------

Co-authored-by: jonas <jonas.perolini@rigi.tech>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-07-13 16:14:42 -06:00
Ramon Roche
ca47db5faa refactor(bench): remove the Hawkeye viewer tee
The --viewer path (tee MAVLink frames to UDP and enable the
HIL_STATE_QUATERNION/HIL_ACTUATOR_CONTROLS streams so Hawkeye could
render an SIH flight live) was never validated end to end: Hawkeye
never actually rendered from it. Rather than ship an unproven feature,
drop it.

Removes px4bench.attach_viewer_tee (and its function-local socket use),
the flight_mission --viewer/--viewer-port args, the viewer tee call and
the stream-enable block, and the now-unused --board-dev arg that only
fed those stream commands. The SIH flight logic, firmware gate,
storage/serial tests, and the arming gate are unchanged. README and the
bench testing docs page drop the Hawkeye section and all --viewer
mentions.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
bf7dcb7229 fix(bench): confirm param committed and saved before reboot in persistence test
The full-suite persistence check failed on hardware with 'after reboot
SDLOG_UTC_OFFSET = 740 (expected 777)'. Firmware persistence is solid;
this was a test race. A PARAM_SET propagates through the param system
asynchronously, and phase_persistence ran 'param save' on the strength
of the PARAM_VALUE echo alone. When save raced ahead of the commit it
persisted the PRIOR value (740, the last value Phase 2 wrote). The echo
was not even proof of the new value: wait_param_echo returned
seen=[740, 777], a stale queued PARAM_VALUE from Phase 2 having slipped
past drain_param_values.

Make persistence deterministic with two gates instead of timing:

1. After setting the marker, read it back from the board until it reports
   MARKER_VALUE (read_until) before saving. This confirms the value is
   committed to RAM and trusts the board's read over any stale echo.
2. After 'param save', confirm the saved state with 'param show <name>'
   and require the '+' (saved) flag AND the marker value before rebooting
   (retry save once first). '*' means unsaved; the test never reboots on
   an unsaved marker. Flag columns per src/systemcmds/param/param.cpp:822
   (x used, + saved, * unsaved, l locked).

phase_set_readback now also trusts read_until over the echo, so the same
stale-queued-echo does not fail it either; its pass criteria stay the
readback match. Restores in phase_persistence and the final cleanup use
read_until too.

New shared helpers in px4bench.params: read_until(mav, name, expected,
timeout) -> (ok, last_seen), and param_is_saved(shell, name) plus its
parse_param_show() parser for the 'param show' saved flag and value.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
6e2ef3345f fix(bench): reuse shell sessions and confirm prompts to stop leaking nsh tasks
A hardware run exhausted the board's task/fd table after a few probe
cycles: shell open failed while heartbeat still worked, and continued
writes eventually stalled the link. Not a firmware hang, a resource leak
the tooling drove.

The firmware spawns a new nsh task plus two pipes (four fds) on the
first SERIAL_CONTROL write of a session (Mavlink::get_shell) and only
frees them when a SERIAL_CONTROL message arrives with the RESPOND flag
cleared (Mavlink::close_shell). Two tooling bugs combined to leak them:

- MavlinkShell.open() returned True on any buffered byte, including
  leftover output from a prior session, so it reported a live shell
  without one. It now confirms an actual 'nsh>' prompt or a completed
  echo-sentinel round-trip before returning True, keeping the same
  timeout-and-report-failure behavior.
- open/close cycles reopened before the single flags=0 teardown was
  processed, spawning a second shell before the first was freed. close()
  now sends the flags=0 teardown and then briefly drains incoming
  SERIAL_CONTROL until quiet (bounded, never a hang) so the firmware
  runs close_shell before a caller can reopen.

Lifecycle: every MavlinkShell user now opens one session, runs all its
work on it, and closes it in a finally so no error path leaks a shell.
The SIH flight and storage tests run all their probes on a single shell
(shell_command_exists already takes an open shell); flight_mission no
longer opens a throwaway probe shell separate from the flight session
beyond the unavoidable reboot boundary in enter_sih.

Folds in the sentinel fix (run() sends the echo sentinels on their own
input line, because nsh aborts a ';' chain when a command fails, which
previously lost the sentinel for a failing probe and read as a stall).

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
83f68f709c docs(bench): document the arming gate, storage tests, and capability report
The flight test is now part of the default suite; both the bench README
and the bench testing guide said it ran separately. Update the sequence
description, the risk map and suite tables (storage_stress and
flight_mission rows, serial_loopback for fixtures), the SIH sections
(probe-and-skip, the typed 'arm' confirmation, --allow-arming for
automation), the production section (--allow-arming on the line,
serial_loopback with a jumper on the fixture), and the firmware gate
--build description (bench capability report with variant and config
line recommendations). Storage threshold defaults are justified where
the flags are documented.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
2f54fd101f feat(bench): add storage and serial loopback tests from existing system commands
The firmware already ships sd_bench, sd_stress, and serial_test; the
suite was not exploiting them.

bench/storage_stress.py joins the default sequence before log_transfer
(storage health first, then the test that depends on storage). It runs
sd_bench with data verification and parses write/read throughput and
fsync latency into named checks with generous FAIL floors (defaults
justified in the README: 100 KB/s write, 200 KB/s read, 500 ms fsync;
a working-but-slow card prints a WARNING instead of flapping), then
sd_stress for file churn with a short default iteration count. Both
phases probe-and-skip independently: a firmware without a command or a
board without an SD card records SKIP with a warning, never FAIL.

bench/serial_loopback.py is a standalone operator/fixture test for
manufacturing: with a TX-RX loopback jumper installed on a chosen UART,
serial_test transmits a known pattern and the session summary
(rx/tx/rx err counts) plus pattern-error lines decide the verdict. Not
in the default sequence because it needs a physical fixture.

The firmware gate's --build path now prints a bench capability report
from one shared table: after reading default.px4board plus the label
overlay (labels merge both, cmake/kconfig.cmake:47-54) it lists whether
the image will contain simulator_sih, sd_bench, sd_stress, and
serial_test and which suite tests will run or skip. For anything
missing it names a sibling variant that has it (exact --target) and
the exact config line, and interactively offers to append the line to
the local board config, stating that the edit is local and uncommitted.
All four options are 'default n' in Kconfig, so the merged .px4board
lines decide presence.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
af8bad97cc feat(bench): include SIH flight in the default suite behind an arming gate
The simulated flight is the only test that exercises commander,
navigator, and land-detector flight logic on real NuttX scheduling;
leaving it out of the default suite meant the most valuable coverage
was routinely skipped. It now runs last in the sequence.

Arming safety gets two explicit paths: on a TTY the operator sees a
prominent warning that the flight controller WILL ARM (simulated
flight, pwm_out_sim replaces the real outputs, board must be bare) and
must type 'arm'; declining records a skip, not a failure. For
automation and manufacturing lines --allow-arming bypasses the prompt,
and a non-TTY run without it skips the flight with a warning naming
the flag.

Before touching any configuration the test probes the live firmware
for the SIH module ('simulator_sih status'; NuttX nsh replies
'nsh: <cmd>: command not found', apps/nshlib/nsh_parse.c) and skips
with a warning when the module is absent.

Shared plumbing in px4bench: EXIT_SKIP (75) recorded as SKIP by the
orchestrator, shell_command_exists() for probe-and-skip, and
arming_gate() used by both the orchestrator flow and the standalone
flight test. Config mutation by the flight test is expected; it
restores the original airframe and SYS_HITL afterwards.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
d13a6e44f0 fix(bench): resolve board_id for labeled build targets
--target px4_fmu-v6xrt_bench previously skipped the early board_id
check because only bare vendor_model targets were known; a label
selects a .px4board config within the same board, so strip it and
resolve to the board dir. The uploader still enforces board_id against
the bootloader at flash time.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
c16fb3bfed feat(bench): add firmware gate so the suite knows what it is testing
Today's runs executed against whatever firmware happened to be on the
board (an old April build at first) and nothing checked. For a
qualification tool that is unacceptable: before any test starts the suite
now establishes, and can control, exactly which build it is testing.

New px4bench/firmware.py: .px4 metadata parsing and validation (fields
verified against Tools/px_mkfw.py and px4_uploader.py), board identity
via ver all over the nsh shell, flashing through Tools/px4_uploader.py
with streamed output and a hard timeout, HW-arch to build-target
inference by enumerating boards/, an early wrong-board check against
firmware.prototype board_id, and the named firmware_identity check
(git-hash prefix match against the artifact).

run_bench_suite.py preflight supports four firmware sources, all
converging on the same flash + verify path: keep what is on the board
(--any-firmware), flash a local file (--firmware), build the inferred
target from this source tree (--build, --target, --build-timeout), or
download a GitHub release artifact (--release TAG|latest, via gh;
asset naming verified against the v1.17.0 release). --expect-hash
verifies without flashing. Flags are mutually exclusive; with none
given, a TTY gets an operator menu covering the same four sources, and
automation exits with an error before touching the board. The detected
identity is printed, written to firmware.json in the suite report dir,
and stamped into every test's report dir via PX4BENCH_FIRMWARE_INFO.

If the board's mavlink is wedged the uploader cannot soft-reboot it into
the bootloader (hit live today); after repeated reboot attempts the gate
prints an operator instruction to replug USB so the uploader catches the
bootloader at power-on.

sih/flight_mission.py gains a verify-only --expect-hash and stamps the
firmware identity into its report dir; it never flashes.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
e6283bb374 docs(bench): motivate the suite by the hardware verification gap
The README opened by framing the whole suite around one merged PR
series. The value is general: CI never boots NuttX and SITL runs on a
host OS, so defects in boot ordering, link lifecycle, storage, loop
rates, and RTOS-only concurrency are invisible until a board is on a
bench. Reword the introduction around that gap and the timeout-first
design rule instead of the originating incident.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
9526efa4f6 refactor(bench): restructure suite into px4bench package with bench/ and sih/ split
Turn the flat script pile into a standalone project so contributors can
navigate and extend it:

- px4bench/ shared library package: core primitives in __init__ (Reporter,
  connect, MavlinkShell, reboot/replug, viewer tee, mavlink status parsers,
  pymavlink add_message workaround) plus protocol modules params.py,
  missions.py, and ftp.py extracted from the tests. Zero helper duplication
  remains across scripts.
- bench/ holds the real-firmware tests (boot_health, reboot_loop,
  usb_replug, link_forwarding, param_stress, mission_stress, log_transfer);
  sih/ holds the simulated flight (flight_mission), making the
  simulation/no-simulation boundary explicit.
- pyproject.toml (px4bench 0.1.0, BSD-3-Clause, pymavlink/pyserial deps,
  pyulog extra) so pip install -e Tools/bench_test works; every script
  remains directly runnable without installation via a parent-dir path shim.
- README rewritten contributor-first: architecture, per-test justification
  tied to the v1.18 risk areas, why pymavlink over MAVSDK, how to add a
  test, baseline workflow.
- Consistent CLI surface (shared connection args; --report-dir replaces
  log_transfer's --outdir); decorative section banners removed.

All hardware-learned behavior is preserved exactly: param echo drain and
match-by-value, shell sentinel strip-all, the add_message workaround,
explicit param save before reboot, mission clear before upload, RTL in
MAV_FRAME_MISSION, and the post-flight ULog download.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
8d709a5e08 test(bench): add scripted SIH flight with live Hawkeye viewer tee
sih_flight.py switches the board to a SIH airframe (SYS_HITL=2, physics
on the FMU), flies takeoff, a 3-waypoint square, and RTL as an auto
mission, asserting arming, takeoff, waypoint progression, landing, and
auto-disarm with per-phase timeouts, then restores the original config.
Covers the flight-logic paths the bench tests cannot reach; pwm_out_sim
replaces real outputs so nothing is driven on the rails.

--viewer tees every received MAVLink frame to UDP (frame per datagram,
same framing as the SITL viewer channel) and enables the
HIL_STATE_QUATERNION/HIL_ACTUATOR_CONTROLS streams on the board, so
Hawkeye renders the flight live from a serial-connected board.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
676523f683 fix(bench): harden suite against real-board MAVLink message timing
First hardware run (fmu-v6xrt over USB, macOS) surfaced three issues:

- param_torture consumed PARAM_VALUE echoes positionally; one duplicate
  broadcast desynced every subsequent check. Drain stale messages before
  each set and match the echo against the expected value, reporting all
  observed values so a genuine wrong-echo bug remains visible.
- the shell sentinel's second safety echo leaked into the next command's
  captured output; strip any sentinel line, not just the current one.
- pymavlink 2.4.49 add_message() intermittently crashes with TypeError
  when the first message of an instanced type arrives with its instance
  field unset; wrap it defensively until fixed upstream.

Full suite now passes 5/5 against fmu-v6xrt.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Ramon Roche
2ca6f2b938 test(bench): add NuttX bench smoke-test suite for release qualification
Semi-automated bench tests for qualifying v1.18 on real Pixhawk-class
hardware after the TSAN/concurrency series (#27606, #27809, #27813).
CI builds NuttX but never boots it, and the failure mode of this class
of regression is a silent hang, not a crash: every operation here has a
hard timeout and a timeout is reported as FAIL naming what stalled.

Tests map to the reworked subsystems: boot_health (WorkQueue/uORB
snapshot with baseline diffing), dual_link_forwarding (nested-send lock
path under simultaneous two-link load), param_torture (set/readback and
reboot persistence on SDLOG_UTC_OFFSET), mission_torture (dataman and
the mission shared-state mutex, 220 items, link alternation),
mavftp_log (logger on/off plus MAVFTP download and ULog verification),
reboot_loop and the operator-assisted usb_replug (mavlink instance and
RAM lifecycle across re-enumeration). run_bench_suite.py orchestrates
the non-interactive tests with a per-test watchdog.

Requires pymavlink/pyserial, pyulog optional. Nothing arms the vehicle.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-07-07 21:33:15 -07:00
Balduin
3e9841cbb6 feat(docs): sort dds topics, fix formatting (#27794) 2026-07-03 08:44:15 +10:00
Anil Kircaliali
5a7d3e4692 chore(msg): allow dB/MHz/Hz/KiB/s units and UINT max invalid value 2026-07-01 15:05:46 -07:00
Matthias Grob
25b7d627da fix(ROMFS): Safe flash pruning more unnecessary characters from ROMFS (#27775)
* refactor(ROMFS): remove trailing zeros from all airframes

* refactor(ROMFS): remove allignment whitespace from all startup scripts

* feat(romfs_pruner): strip end of line comments in startup scripts

and airframes to not waste any flash.

* feat(romfs_pruner): strip inline multi-whitespace

* fix typo

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-01 11:53:21 -08:00
Farhang
8859bf44a2 ci(dev-call): weekly Discourse post automation (#27087)
---------

Signed-off-by: FARHANG <farhang.nba@gmail.com>
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Co-authored-by: Ramon Roche <mrpollo@gmail.com>
2026-06-30 12:36:13 -07:00
Ramon Roche
3db36cb022 ci(macos): trust PX4 brew taps for Homebrew 6.0
Homebrew 6.0 (2026-06-11) makes tap-trust mandatory and refuses to load
formulae from untrusted third-party taps. This broke every macOS build:
brew install aborted with "Refusing to load formula px4/px4/fastdds from
untrusted tap px4/px4" before pouring any package, so ccache (and the
rest of the toolchain) was never installed and setup-ccache failed with
"ccache: command not found".

Trust the three required taps non-interactively before installing from
them. Guarded behind a brew trust capability check so older Homebrew,
which has no trust gate, skips it.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-06-25 13:23:29 -07:00
Jacob Dahl
4edb7d49e2 feat(tools): add DroneCAN sensor latency calibration scripts
Cross-correlation scripts to measure CAN transport delay from flight
logs. Compares CAN sensor signals against the FC's directly-connected
IMU to estimate the total pipeline latency.

- range_sensor_latency.py: cross-correlates range rate with IMU-derived
  vertical velocity
- flow_sensor_latency.py: cross-correlates flow sensor gyro with FC gyro
2026-06-23 14:27:11 -07:00
msl-dev
c9b13827d9 feat(build): support firmware upload from WSL2 (#27674)
Signed-off-by: msli-dev <747640013@qq.com>
2026-06-18 10:49:53 +12:00
Jacob Dahl
183b3e38d5 fix(bootloader): scrub uncorrectable flash ECC errors on STM32H7 before boot (#27642)
* fix(bootloader): scrub uncorrectable flash ECC errors on STM32H7 before boot

A torn write to a flash row (power lost mid program/erase) can leave it
with inconsistent ECC. On H7 a CPU read of such a row raises an
uncorrectable double-bit ECC error -> bus fault, so the application hard
faults on every boot before printing anything, and only a mass erase
recovers it: reflashing does not, because neither the app nor the
bootloader image touches the parameter sector.

Scan the application and parameter flash with DMA right after clock_init
(a DMA read latches FLASH_SR DBECCERR instead of bus-faulting the CPU)
and erase any sector that holds an uncorrectable error. A corrupt
parameter sector then re-seeds to defaults on the next app boot; corrupt
app flash fails the image check and stays in the bootloader for reflash.
Mirrors ArduPilot's bootloader ECC scrub. H7-gated; the scan runs before
the interface DMA is brought up, so DMA1 stream 0 is uncontended.

* test(tools): add STM32H7 flash ECC fault injection tool

A bench helper that deterministically plants an uncorrectable (double-bit)
flash ECC error on an STM32H7, reproducing the torn-write parameter-store
brick. Used to validate the bootloader ECC scrub and the parameter re-seed
recovery on hardware: plant the fault, then confirm the board boots clean
instead of hard-faulting every boot.

brick_ecc.c is a freestanding stub that double-programs one flash word with
two different single-bit clears (the recipe that yields an inconsistent ECC);
brick_ecc.sh builds it, loads it into AXI SRAM over ST-Link, runs it, and
resets the board. README documents usage and how to retarget another board.

* fix(bootloader): require DMA transfer-complete for a clean ECC scan chunk

The stream self-disables on both transfer-complete and transfer-error.
A non-ECC bus error (unreachable scan buffer, rejected FIFO config)
previously read as a clean chunk, silently turning the scan into a
no-op. Require TCIF so an unread chunk takes the skip-the-scan
fallback instead of passing.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>

---------

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-06-12 19:21:01 -06:00
Phil-Engljaehringer
f2eecc33f7 feat(drivers): implemented serial passthrough (#27605)
* feat: implemented serial passthrough

* fix: used make format

* fix: changed function order to match other drivers

* fix: moved passthrough from systemcmds to drivers

* fix: renamed BITBANG_TIMER to UART_BITBANG_TIMER

* fix: used make format

* feat: added PASSTHRU_EN guard to start of dshot&pwm_out

* fix: made changing ESC channels more stable

* fix: adjusted naming of guards

* fix: changed include guard of bitbang

* fix: removed unused variable SER_PASS_BAUD

* fix: adjusted comments

* fix: adjusted print_usage() to match other drivers

* fix: remove bitbang_write_byte from public API and some buffer guard

* fix: added Serialpassthrough&Bitbang to exclude list of allyesconfig.py

* fix: added missing flag to print_usage()
2026-06-12 18:27:26 +02:00
Jacob Dahl
09eec8f9ae fix(tools/uploader): handle device re-enumeration on reboot (#27635)
tcdrain()/tcflush() in pyserial's POSIX backend raise termios.error,
which derives from Exception rather than OSError, so it slipped past the
`except (OSError, serial.SerialException)` guards in flush() and
reset_buffers(). When the USB CDC node tore down during a
reboot-to-bootloader re-enumeration (reliably reproduced flashing PX4
onto a board running ArduPilot) the raw error escaped every
ConnectionError retry loop and crashed the uploader. Catch termios.error
explicitly so it surfaces as ConnectionError and the existing
identify/reboot retry loops recover.

reboot() also sent REBOOT once and silently swallowed a missing ack,
reporting success even when the board never left the bootloader. Confirm
the reboot via the bootloader's INSYNC+OK ack (sent before it jumps, per
bl.c PROTO_BOOT) or by watching the serial device re-enumerate, and
resend REBOOT if neither is observed.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-06-10 16:52:28 -06:00
Jacob Dahl
f28a3f95f0 fix(tools/uploader): only verify signature for signed firmware (#27631)
PR #27237 added an unconditional verify_signature() step between verify
and reboot, sending the VERIFY_SIG (0x39) opcode on every upload. For
unsigned firmware this injects an unknown opcode into the bootloader
command stream immediately before BOOT; bootloaders that don't silently
ignore it are left out of phase for the BOOT handshake, so the board
intermittently stays in the bootloader after an otherwise-successful
flash (app LEDs never come on).

Gate the probe on firmware.image_signed so unsigned uploads go straight
from verify to reboot, as before #27237. Signature verification still
runs for signed images.
2026-06-10 09:00:57 -06:00
Jacob Dahl
1ab0f5d2cd fix(astyle): ignore Micro-XRCE-DDS-Client-v3 submodule in format checks (#27630)
The Micro-XRCE-DDS-Client-v3 submodule was added without a corresponding
prune entry, so 'make format'/'make check_format' would reformat its
vendored sources. Add it to the exclusion list alongside the existing
Micro-XRCE-DDS-Client entry.
2026-06-10 08:21:15 -06:00
Julian Oes
05db354ac9 feat(gz): update submodule, and add ridge docs (#27600)
* feat(gz): update submodule, and add ridge docs
2026-06-10 11:24:41 +10:00
Jukka Laitinen
839b7a470f fix(CI): Prerequisites for nuttx update (#27509)
* src/drivers/cdcacm_autostart: Include posix.h for px4_close

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* platforms/nuttx/CMakeLists.txt: Fix linking of nuttx libaries for memalign

This fixes memalign not found in linking step for some boards

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* Add "flock" to macos.sh setup script

"flock" is not standard on macOS, and a dependency was missing from the
macOS setup path.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* Fix clang-tidy errors in Bitset.hpp and in src/lib/matrix

Fix the "bugprone-dynamic-static-initializers" linter errors.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* systemlib/hardfault_log: Fix clang-diagnostics error

Fix for
"[error] clang-diagnostic-error [error]
 use of undeclared identifier XCPTCONTEXT_REGS".

XCPTCONTEXT_REGS is defined in nuttx irq.h, so include that.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* uORB: Fix clang-tidy error "bugprone-dynamic-static-initializers"

Fix the clang-tidy error appearing on uORBManager _Instance variable by
adding a getter for the reference to the _Instance and using that instead.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

* CI: Add default ubuntu mirrors as fallback

In case of specified aws mirror doesn't have the package idicated by the
metadata, a the default ubuntu mirror as a backup.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>

---------

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-06-02 11:27:50 -06:00
Julian Oes
ec8718f05e feat(bootloader): Revive secure-boot with example, docs, and various fixes (#27237)
* feat(secure_bootloader): add ed25519 key and signing helpers

Scaffolding for PX4 secure-boot firmware signing, split into two
self-contained scripts:

- generate_signing_keys.py: produces <name>.json (private+public hex)
  for use by sign_firmware.py and <name>.pub (C-array public key)
  for inclusion in the bootloader build via CONFIG_PUBLIC_KEYn.
  Refuses to overwrite existing private-key files.

- sign_firmware.py: pads an input .bin to a 4-byte boundary and
  appends a 64-byte ed25519 signature, producing a file that drops
  directly into the flash slot described by the image TOC.
  Optionally appends an R&D certificate binary after the signature.

Replaces the signing path of the old Tools/cryptotools.py that was
removed along with the log-encryption cleanup; the new layout keeps
bootloader-signing tooling separate from log encryption to avoid
confusing the two independent crypto surfaces.

* fix(bootloader): panic if px4_get_secure_random is ever called

sw_crypto's crypto_open() unconditionally references
px4_get_secure_random from its XCHACHA20 path, so even a bootloader
that only performs ed25519 signature verification (and never touches
stream ciphers) pulls in an undefined symbol at link time.

The app build resolves it through nuttx_random.c, which is gated
behind CONFIG_CRYPTO_RANDOM_POOL and only compiled in when the
NuttX random pool is enabled. That config isn't on in the tiny
bootloader NuttX defconfig, and enabling it would pull in a pile
of kernel code the bootloader doesn't need.

Supply the symbol locally, but make it call up_assert() instead of
returning zeros. Silently handing out predictable bytes would be a
serious security bug if anyone later enables the XCHACHA20 path in
the bootloader without wiring up a real RNG. Aborting makes the
mistake impossible to miss.

* fix(bootloader): add PROTO_VERIFY_SIG opcode for upload-time signature check

Today a signed-boot failure is invisible to the uploader: verify_app()
runs inside jump_to_app() after PROTO_BOOT has already rebooted the
chip, so the host sees a successful upload followed by the device
silently staying in the bootloader. There is no protocol-level signal
that the image that was just written is not going to run.

Add PROTO_VERIFY_SIG (0x39) so the host can ask the bootloader to run
find_toc() + verify_app(0) *before* the reboot and get a concrete
OK / FAILED / INVALID answer back over the still-open USB connection.
The new opcode is gated on BOOTLOADER_USE_SECURITY: bootloaders built
without secure boot return cmd_bad (INSYNC/INVALID) so an uploader
can tell "I don't know this command" apart from "verification failed".

Two subtleties required care:

1. PROG_MULTI deliberately defers the very first word of the app
   image to a RAM variable (first_word) and only commits it to flash
   inside PROTO_BOOT, so a partial upload can never become bootable.
   But verify_app() reads directly from flash, so if we verified
   before committing first_word, even a valid image would always
   fail (the first four bytes at APP_LOAD_ADDRESS would still be
   0xffffffff). The handler therefore mirrors the first half of the
   PROTO_BOOT handler: gate on STATE_ALLOWS_REBOOT, program the
   deferred first word, then run the crypto check.

2. On failure we deliberately do not try to "undo" the first-word
   write — H7 flash programming granularity makes it impossible to
   revert in place, and the device was going to end up in the same
   reject state at the next boot either way. The improvement is
   purely that the uploader sees the failure before REBOOT instead
   of after.

Chose opcode 0x39 to stay clear of ArduPilot's 0x28 (READ_MULTI) and
0x40 (CHIP_FULL_ERASE), which PX4 does not currently use but which
an AP-compatible uploader might.

ArduPilot also has bootloader secure boot (monocypher ed25519, like
us) but their verification runs at boot time, not upload time — so
neither project currently solves the "upload silently wrote a bad
image" problem. This puts PX4 ahead on that.

* feat(Tools): add --image_signed to mark signed firmware for uploader

px_uploader.py only needs to run signature verification over USB for
images that actually carry a signature — asking the bootloader to
verify an unsigned image would always fail, and the extra round trip
is wasted time for the common unsigned case. It therefore needs a
reliable way to tell the two apart.

We cannot tell by inspecting the bytes: a sign_firmware.py output is
just the raw .bin with 64 bytes of ed25519 signature glued on the
end, indistinguishable in content from an unsigned image of the same
padded length. The natural place to put the flag is the .px4 JSON
envelope, which already carries board_id / version / summary / etc.

Add --image_signed to px_mkfw.py, which sets "image_signed": true
in the emitted JSON. The flag has no effect on what bytes actually
end up on the device — it just tells the uploader "this blob has a
signature, please verify it before booting".

* feat(Tools): verify firmware signature before reboot

After PROG_MULTI + GET_CRC, send a new VERIFY_SIG opcode (0x39) to
the bootloader to check the ed25519 signature over the freshly
flashed image *before* sending REBOOT. This way a signature failure
is reported as a clean error from the uploader script, instead of a
silent "device stays in bootloader after reboot" that leaves the user
guessing.

The uploader always probes VERIFY_SIG. The bootloader is the source
of truth for whether secure boot is enabled:

- INSYNC/OK         -> verification passed, proceed to REBOOT
- INSYNC/FAILED     -> raise; "Signature does not verify against any
                       trusted key" if the firmware claims to be signed,
                       "Secure bootloader rejected an unsigned image"
                       otherwise (= helpful guidance for the common
                       misconfiguration of uploading default firmware
                       to a secureboot bootloader)
- INSYNC/INVALID    -> bootloader has no secure boot. Quietly proceed
                       unless the firmware metadata says image_signed,
                       in which case raise.
- recv timeout      -> assume a pre-VERIFY_SIG bootloader, proceed.

Surfaces a "Verifying image signature... passed" line on the upload
status path when the firmware is marked signed, so users get a clear
positive signal that the secure-boot pipeline ran end-to-end.

Also drop the redundant logger.error in the upload() loop, which was
duplicating the error message printed by the top-level handler in
main() for every UploadError path (not specific to verify_signature,
but only became obvious once these clean error messages started
firing in normal usage).

* fix(cmake): fix .px4board variant resolution to require exact match

px4_config.cmake matched the requested CONFIG against each candidate
.px4board with `MATCHES`, which is a regex partial match. For a
config like `px4_fmu-v6x_bootloader_secureboot`, the iteration over
.px4board files (alphabetical glob order) would match
`bootloader.px4board` first — because "px4_fmu-v6x_bootloader" is a
prefix of "px4_fmu-v6x_bootloader_secureboot" — and stop, silently
selecting the wrong board config.

Use `STREQUAL` instead so each candidate has to match the full
requested CONFIG. Existing single-label cases (e.g. exact match on
`px4_fmu-v2_default` or `px4_fmu-v2`) are unaffected because they
were already exact in practice; this just plugs the prefix-match
hole that any future `<label>_<suffix>` variant would trip over.

* fix(nuttx): support bootloader_<variant> labels

Boards can ship bootloader variants beyond the default `bootloader`
label — e.g. a `bootloader_secureboot` that adds crypto + keystore
Kconfig on top of the same source tree. Two pieces of build glue
were hardcoded to the exact label `bootloader` and need to relax to
match any `bootloader_*` label:

1. platforms/nuttx/CMakeLists.txt picked the bootloader linker
   script and bootloader-specific library list only when the label
   was exactly `bootloader`. Any other label (including
   `bootloader_secureboot`) silently fell through to the app build,
   producing nonsensical link flags. Match `^bootloader` instead,
   and explicitly set SCRIPT_PREFIX to `bootloader_` so all
   bootloader variants share the single existing linker script
   regardless of their full label.

2. platforms/nuttx/cmake/px4_impl_os.cmake selects the NuttX config
   subdirectory by exact label match, falling back to `nsh` when no
   matching directory exists. For `bootloader_secureboot` that fell
   through to `nsh`, dragging in a full app-style NuttX with cromfs,
   networking, and the full heap subsystem — a 128 KB bootloader
   sector overflowed by ~50 KB. Add an intermediate fallback: if the
   label starts with `bootloader` and a `bootloader/` subdir exists,
   use that instead of `nsh`.

Both changes are backward-compatible: existing single-label
`bootloader` builds take exactly the same path as before. They only
gain the ability for boards to add `bootloader_<suffix>.px4board`
files without duplicating bootloader build wiring.

* feat(build): auto-sign secure-boot images via BOARD_SECUREBOOT

Add a Kconfig pair that boards can opt into:

  CONFIG_BOARD_SECUREBOOT      -- bool: sign the .px4 with ed25519
  CONFIG_BOARD_SECUREBOOT_KEY  -- string: path to JSON private key
                                  (default: Tools/test_keys/test_keys.json)

When set, the .px4 build rule inserts a Tools/secure_bootloader/sign_firmware.py
step between the unsigned .bin and px_mkfw.py, and passes --image_signed
so the .px4 envelope's metadata flags it for the uploader's VERIFY_SIG
step. The unsigned .bin is still produced alongside the .px4, so users
can sign with their own key out-of-tree if they prefer.

A BOARD_SECUREBOOT_KEY environment variable overrides the Kconfig path
at build time, mirroring the override pattern used for CONFIG_PUBLIC_KEYn
in stub_keystore. This makes release builds practical:

  BOARD_SECUREBOOT_KEY=/secure/path/release.json make px4_<board>_secureboot

Relative paths in the Kconfig are resolved against the repo root (not
the build directory) so the same value works regardless of where the
build runs from.

Default builds are byte-identical to before; the new code path is gated
on CONFIG_BOARD_SECUREBOOT being set.

* feat(boards): add secureboot demo variant + docs

Two coordinated build variants demonstrate end-to-end secure boot
on px4_fmu-v6x without touching the default builds:

  px4_fmu-v6x_secureboot              -- the app, with TOC + signing
  px4_fmu-v6x_bootloader_secureboot   -- the matching secure bootloader

App side (secureboot.px4board):
  - Selects nuttx-config/scripts/secureboot-script.ld via
    CONFIG_BOARD_LINKER_PREFIX. The script is a copy of the default
    layout plus a fixed 0x800 reservation past the vector table for
    the image TOC, and an empty .signature section at end-of-FLASH
    so sign_firmware.py knows where the appended ed25519 signature
    will land.
  - Compiles src/toc.c (a four-entry IMAGE_MAIN_TOC matching the
    layout used elsewhere in the tree) into drivers_board, gated on
    PX4_BOARD_LABEL == secureboot so the default build still
    produces the existing layout.
  - Sets CONFIG_BOARD_SECUREBOOT=y so the .px4 build rule signs the
    image with the upstream test key by default.

Bootloader side (bootloader_secureboot.px4board):
  - Enables CONFIG_BOARD_CRYPTO + DRIVERS_SW_CRYPTO + DRIVERS_STUB_KEYSTORE,
    which links monocypher and the stub keystore into the bootloader.
  - Bakes Tools/test_keys/key0.pub in as CONFIG_PUBLIC_KEY0, paired
    with the test_keys.json the app variant signs with.
  - hw_config.h gates BOOTLOADER_USE_SECURITY, BOOTLOADER_SIGNING_ALGORITHM
    (CRYPTO_ED25519), and BOARD_IMAGE_TOC_OFFSET (0x800) on PX4_CRYPTO,
    so they only activate in this variant.

Together the two variants implement the workflow:

  make px4_fmu-v6x_bootloader_secureboot     # build + flash via SWD once
  make px4_fmu-v6x_secureboot upload         # signs with test key, verifies

Bootloader fits in 128 KB (~57 KB used) thanks to --gc-sections
stripping the unused libtomcrypt code; nothing in the bootloader
binary depends on monocypher beyond the ed25519 verifier.

Replace the bundled test key for production with
Tools/secure_bootloader/generate_signing_keys.py output and update
both .px4board files (or set BOARD_SECUREBOOT_KEY at build time) —
see docs/en/advanced_config/bootloader_secure_boot.md.

* fix(boards): cap H7 bootloader linker scripts at 128 KB

Roughly half of the H7 boards in tree had `LENGTH = 2048K` for the
bootloader sector in their bootloader_script.ld, even though the
matching app linker script places APP_LOAD_ADDRESS at 0x08020000 —
i.e. the bootloader actually only owns the first 128 KB sector.

The 2048K constraint is wrong: it lets a bootloader that grew past
the 128 KB sector silently overflow into the app sector at link
time and corrupt the start of the app on flash. The linker should
fail the build instead.

The current default bootloader is ~46 KB, well under 128 KB on every
affected board, so this change is a no-op for default builds. It
just plugs a footgun for anyone adding bootloader features (secure
boot, extra UI, network boot, ...) that would have otherwise
silently grown into the app's flash range.

Boards fixed:

  3dr-style H7 reference boards: cubepilot/cubeorange,
    cubepilot/cubeorangeplus, holybro/durandal-v1, narinfc/h7
  vendor variants: corvon/743v1, cuav/nora, cuav/x7pro,
    gearup/airbrainh743, hkust/nxt-dual, hkust/nxt-v1,
    matek/h743, matek/h743-mini, matek/h743-slim,
    micoair/h743, micoair/h743-aio, micoair/h743-lite,
    micoair/h743-v2, x-mav/ap-h743r1, x-mav/ap-h743v2

Boards already correct (LENGTH = 128K) are unchanged.

* fix(ci): add pynacl to Python requirements

Tools/secure_bootloader/sign_firmware.py uses PyNaCl for ed25519
signing, and the .px4 build rule for boards with CONFIG_BOARD_SECUREBOOT
calls it as part of the normal build (e.g. px4_fmu-v6x_secureboot).
Without pynacl in the dev requirements, those builds fail in CI and
fresh dev setups.

* docs(update): Subedit

* docs(update): Fix example error I made

* fix(docs): document BOOT and SIG1 regions

* fix(platforms): style fix

* fix(ci): workaround to get pip dependency

* fix(ci): fall back to plain pip on older build containers

The voxl2 build image ships a pip that predates --break-system-packages
(added in pip 23.0.1), so the install step blew up with "no such option".
Modern containers enforce PEP 668 and need the flag; older ones don't
support it but also don't enforce PEP 668, so plain pip works there.
Try the modern flag first, fall back if pip rejects it.

Signed-off-by: Julian Oes <julian@oes.ch>

* fix(build): strip BUILD_DIR_SUFFIX from CONFIG in cmake-build

cmake-build was passing the full build-dir name (including any
BUILD_DIR_SUFFIX like _replay or _failsafe_web) as -DCONFIG=, which
the board-lookup in cmake/px4_config.cmake then tried to match
against <vendor>_<model>_<label> .px4board files. That used to work
by accident because px4_config.cmake matched with regex MATCHES, but
since the switch to STREQUAL (needed to disambiguate
bootloader_secureboot from bootloader) the suffixed CONFIG no longer
matches anything and LABEL ends up empty, tripping a CMake error in
kconfig.cmake.

Pass the bare CONFIG and keep the suffix only on the build dir so
both concerns are independent.

Signed-off-by: Julian Oes <julian@oes.ch>

---------

Signed-off-by: Julian Oes <julian@oes.ch>
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
2026-05-27 20:21:49 -06:00
Hamish Willee
dfc08eed28 docs(docs): Link fixes, _sidebar, uorb docs generator tweak (#27482) 2026-05-28 10:44:16 +10:00
Hamish Willee
b6ca5d8c77 docs(tools): Fixes for uorb docs generation (#27474)
* docs(tools): uORB parser: Comma separate multiple enums
* docs(tools): uORB parser: Backlink from enum to field
* docs(tools): uORB parser: index.md section for historic versions
* docs(tools): uORB parser: summary fragment to ease updates
2026-05-27 10:59:44 +10:00
Jacob Dahl
ee002b1db6 fix(tools/uploader): handle USB CDC reconnect race during reboot (#27419)
After sending reboot-to-bootloader, the PX4 USB CDC node briefly
disappears while the bootloader re-enumerates. Reopening the serial
port can land on a half-broken descriptor and the next tcdrain()
raises termios.error (5, 'Input/output error'). That bare OSError
escaped every retry layer and crashed the uploader, even though a
manual re-run would succeed once enumeration settled.

Convert OSError/SerialException from flush() and reset_buffers() into
the module's ConnectionError, matching how send()/recv() already
behave, and let the identify retry loops in _try_identify also catch
ConnectionError so a single transient I/O hiccup doesn't abort the
upload.

Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
2026-05-20 19:08:53 -06:00
Julian Oes
110be82e7d fix(Tools): add clarifying comment (#27403)
It wasn't clear to me why this merge_config.py was required. It is now
clear, so let me leave a comment.
2026-05-20 14:06:11 -06:00
Peter van der Perk
f16a2487ac fix(rcS): Use CONFIG_BOARD_ROOT_PATH as root path. (#27378)
Instead of hardcoded /fs/microsd use the BOARD_ROOT_PATH Kconfig
variable
2026-05-18 09:33:45 -06:00
Phil-Engljaehringer
aa7c66e0a7 feat(uavcan): flash firmware onto CAN nodes from SD card (#27043)
Place firmware .bin files at the SD card root or staging directory
(/fs/microsd/ufw_staging/); on boot the UAVCAN server migrates them
to /fs/microsd/ufw/ and updates FW.db, then flashes any connected
node whose firmware version mismatches.

- Add firmware migration from SD root and staging dir into /fs/microsd/ufw/
- Maintain FW.db flat-file database mapping board IDs to original filenames
- Use cache-aligned DMA-safe read/write buffers (required on STM32H7)
- Add Tools/auterion/remote_update_fmu.sh for SSH-based FMU+canio updates
2026-05-18 16:19:25 +02:00
Julian Oes
f81559ec64 fix(Tools and docs): PX4 Pro isn't really a thing (#27366)
These are just leftovers, probably worth cleaning up.
2026-05-17 21:25:37 -06:00
Jacob Dahl
b4b36a2748 fix(nuttx): unblock multi-board and protected builds (#27360)
* fix(ci): wipe NuttX submodule state between boards in build_all_runner

NuttX .o and lib*.a live in the shared submodule trees under
platforms/nuttx/NuttX/{nuttx,apps}, not in per-board build/<board>/.
NuttX's recursive make doesn't treat PX4's per-board defconfig changes
as a reason to recompile, so consecutive board builds in one workspace
were linking stale objects from an earlier board (e.g. stm32_spi.o from
fmu-v2 linked into fmu-v4pro, which doesn't enable SPI4).

Run git clean -dXf on both NuttX submodules between iterations to drop
gitignored build state. This mirrors what make clean already does for
submodules and preserves the incremental-build wins for single-board
use.

* fix(cmake): isolate kernel mm/libc objects with BINDIR=kbin

mm and libs/libc compile the same sources for both the kernel and user
passes in protected builds. Without separate output dirs the kernel
objects clobber bin/*.o and the user-mode libmm.a/libc.a end up pulling
in kernel-only symbols (nxsem_wait, g_current_regs, nx_read, nx_write,
g_mmheap, ...) at link time. Matches NuttX's own tools/LibTargets.mk.
2026-05-17 16:00:06 -06:00
Jacob Dahl
83d497d624 feat(boards): add ark/fmu-v6s board support (#26631)
* chore(boards): copy ark/fmu-v6x to ark/fmu-v6s

Verbatim copy of ark/fmu-v6x board support to ark/fmu-v6s to
establish a baseline. Functional changes will follow in the next commit.

* feat(boards): add ark/fmu-v6s board support

Low-cost variant of ARK V6X with:
- STM32H743IIK6 MCU (no hardware crypto)
- Single IIM-42653 IMU on SPI1 (SPI2/SPI3 removed)
- IIS2MDC magnetometer on I2C4
- BMP390 barometer on I2C4
- Single sensor power rail

Board ID 61, USB PID 0x003C.

* feat(px4_uploader): add ARK FMU v6s USB ID to the uploader

* refactor: rename SENS_IMU_TEMP to HEATER1_TEMP in rc.board_defaults

* refactor: remove unused ADC channel definitions in board_config.h

* refactor: update ADC channel definitions and remove unused sensor power control

* arkv6s sensor roations

* Add support for Murata SCH16T IMU in default.px4board configuration

* Update bootloader binary for FMU v6s

* Update boards/ark/fmu-v6s/src/hw_config.h

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Update boards/ark/fmu-v6s/src/hw_config.h

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(ark/fmu-v6s): enable CONFIG_CRYPTO for encrypted_logs build

CONFIG_CRYPTO_RANDOM_POOL was set without its parent CONFIG_CRYPTO,
so it was silently dropped and px4_get_secure_random was compiled out,
breaking the ark_fmu-v6s_encrypted_logs link.

---------

Co-authored-by: alexklimaj <alex@arkelectron.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-15 19:31:29 -06:00
Michael Fritsche
0932ad144b feat(drivers): add support for hiwonder 4 channel encoder motor module (#27229)
* driver: hiwonder encoder motor module

* fix(drivers): Change HiwonderEMM from CRTP API to non-template ModuleBase

* fix(drivers): exclude hiwonder_emm driver from sitl build, as it fails i2c dependencies

* feat(drivers, hiwonder4channel): add parameter update subsciption

* feat(drivers, hiwonder4channel): add requested changes of original PR

* fix(drivers, hiwonder4channel): add default in hiwonder_emm module.yaml

* fix(drivers, hiwonder4channel): formatting

* fix(drivers, hiwonder4channel): add the hiwonder driver to all px4board s that include the roboclaw driver

* cleanup(drivers, hiwonder4channel): update copyright year

* chore(drivers): move hiwonder driver startup call from rc.board_sensors to rc.rover

* chore(drivers): hiwonder 4 channel - improve HIWONDER_EMM_EN description

* chore(drivers): hiwonder4channel - move to int8 for internal speed values

* chore(drivers): hiwonder4channel - move unconfigurable value to initialization.

* chore(drivers): hiwonder4channel - add reboot_required to enable parameter

* chore(drivers): hiwonder4channel - add docs

---------

Co-authored-by: chfriedrich98 <chfriedrich@student.ethz.ch>
2026-05-13 15:09:39 +02:00
Julian Oes
e8d40fb843 fix(Tools): exclude PX4-OpticalFlow submodule from format checks (#27246)
It's an external submodule we don't own, same treatment as the other
third-party libs already pruned in this list.
2026-04-30 10:21:35 +12:00
Julian Oes
1a3d232e7b fix(bootloader): remove broken PROTO_SET_DELAY boot-delay feature (#27081)
The bootloader boot-delay feature has been mechanically broken on
every modern FMU board since the STM32F7/H7 transition. It has three
independent bugs that prevent it from ever working:

1. Offset mismatch: BOOT_DELAY_ADDRESS is hardcoded to 0x1a0, but the
   NuttX vector table is 504 B (F76x) to 664 B (H743) long. The
   linker places _bootdelay_signature at ALIGN(32) past end of
   vectors (e.g. 0x2a0 on CubeOrange), never at 0x1a0. The bootloader
   reads random exception_common pointers in place of the magic and
   never matches BOOT_DELAY_SIGNATURE1/2. Verified on CubeOrange with
   objdump of cubepilot_cubeorange_default.elf.

2. Flash cache never flushes: fc_write() stores arbitrary writes in
   cache line 1 and only flushes on a very specific condition tied
   to the sequential firmware upload flow. A standalone write during
   PROTO_SET_DELAY is cached forever. fc_read() then returns the
   cached value, so the post-write verify lies and the bootloader
   reports success. Nothing ever reaches flash.

3. H7 write granularity: the STM32H7 flash controller requires a
   full 32-byte program cycle per write. Single 32-bit writes from
   flash_func_write_word() would not be accepted by the controller
   even if they reached it.

The feature has been silently dead on every H7/F7 FMU board for
years and no one noticed, which is strong evidence nothing actually
depends on it. Rather than fix it (which would mean rewriting
PROTO_SET_DELAY, the flash cache path, and the H7 flash programming
path), remove it.

Changes:
- bl.c: PROTO_SET_DELAY case now immediately NACKs (goto cmd_bad)
  so clients that still send the command get a clear rejection
  instead of the previous silent fake-success. The opcode stays in
  the protocol enum for backwards compatibility.
- bl.h: drop BOOT_DELAY_SIGNATURE1/2 and BOOT_DELAY_MAX.
- stm/stm32_common/main.c, nxp/imxrt_common/main.c: drop the
  startup boot-delay sig check block.
- image_toc.c: decouple find_toc() from BOOT_DELAY_ADDRESS.
  BOARD_IMAGE_TOC_OFFSET is now the required define when
  BOOTLOADER_USE_TOC is enabled. The body is wrapped in #ifdef
  BOOTLOADER_USE_TOC and falls back to a stub returning false when
  the TOC is not in use (no upstream board currently enables it).
- Linker scripts: strip EXTERN(_bootdelay_signature) and the
  FILL/. += 8 block from all 142 affected .ld files across boards/.
- hw_config.h: strip the #define BOOT_DELAY_ADDRESS and its comment
  block entry from all 48 affected boards.
- Tools/px4_uploader.py, Tools/teensy_uploader.py: remove --boot-delay,
  set_boot_delay(), and SET_BOOT_DELAY client-side counterpart.

Smoke-built on cubepilot_cubeorange_default and
cubepilot_cubeorange_bootloader; no link errors, no unresolved
symbols, flash usage unchanged.

Tested:
- New BL, new FW
- Old BL, old FW
- Old BL, new FW
- New BL, old FW
2026-04-29 13:04:03 +12:00
Valentin Bugrov
7ac1cbd719 feat(allyes): Remove redundant filters from exception_list_sitl 2026-04-24 15:37:25 -07:00
radodim
381149fb01 build(simulation): depend on gz-harmonic for SITL deb (#27178)
* build(simulation): depend on gz-harmonic meta-package for SITL deb

* build(simulation): refresh apt lists before installing px4-gazebo .deb
2026-04-22 11:42:30 -07:00
Ramon Roche
540218857a ci(clang-tidy): drop 'file not found' diagnostics from PR review
These fire when clang-tidy analyzes a header whose including TU is not
in the active compile_commands.json (e.g. board-specific NuttX headers
against the SITL clang build), producing spurious line-anchored review
comments on every new-board PR. Real missing includes are caught by the
build_all_targets matrix, which fails the build loudly. Filter the
class of finding at the producer so it never reaches the poster.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-04-22 10:25:26 -07:00
Ramon Roche
dcedef6168 build(sim): resolve SITL runtime deps via .deb Depends
The px4-gazebo .deb already declares OpenCV and gstreamer core library
deps via dpkg-shlibdeps, but Dockerfile.gazebo uses dpkg -x which
bypasses resolution. Switch to apt install ./px4-gazebo_*.deb so Depends
are resolved automatically.

Add the 5 gstreamer plugin packages (plugins-base/good/bad/ugly/libav)
to CPACK_DEBIAN_PACKAGE_DEPENDS since they're loaded at runtime via
gst_element_factory_make() and cannot be detected by shlibdeps.

Apply the same apt-install pattern to Dockerfile.sih so both images
build consistently.

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-04-21 15:37:48 -07:00
Ramon Roche
9c2e634325 build(macos): make gz SITL work out-of-box after homebrew 4.5
The px4-sim / px4-sim-gazebo Homebrew meta-formulae can no longer
pull their Gazebo dependency chain because Homebrew 4.5+ stopped
auto-resolving cross-tap deps. PX4/homebrew-px4#104 already
deprecated px4-dev into a no-op; #111 does the same for the sim
formulae. This PR is the PX4-side counterpart: move the sim install
into Tools/setup/macos.sh with an explicit package list and tap
registration, mirroring the pattern already used for the toolchain
block. Adds xquartz install on --sim-tools.

Beyond install, three runtime and configure gaps kept make px4_sitl
gz_x500 from working on a clean macOS:

- gz-gui8 (pulled in by gz-sim8) links against Qt5, but Homebrew's
  qt@5 is keg-only so CMake cannot find it. Add a POSIX-scoped hint
  in platforms/posix/cmake/px4_impl_os.cmake that resolves
  brew --prefix qt@5 and appends it to CMAKE_PREFIX_PATH. No-ops on
  non-APPLE builds and respects a user-set Qt5_DIR.

- On macOS, dyld does not search /opt/homebrew/lib by default.
  gobject-introspection typelibs reference libs by bare basename,
  causing gst-plugin-scanner to fail to load plugins and adding
  ~90s of timeout to Gazebo's cold start. Set
  DYLD_FALLBACK_LIBRARY_PATH to the Homebrew prefix lib dir in
  gz_env.sh so the bridge launch inherits it. Darwin-scoped, no
  effect on Linux or CI.

- configure_file on gz_env.sh.in now uses @ONLY so shell ${VAR}
  references pass through untouched.

Verified locally on macOS 26.4 / arm64 / Homebrew 5.1.7: configure
clean, 1119/1119 targets compile and link, vehicle spawns in
Gazebo Harmonic 8.11.0 with a single "Waiting for Gazebo world"
wait (was ~18 before the dyld fix).

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-04-20 16:15:41 -07:00
Kristiyan Dimitrov
b5e632ccf4 build(macos): add Python venv support to setup script (#26702)
Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Co-authored-by: Ramon Roche <mrpollo@gmail.com>
2026-04-20 09:45:54 -07:00
Balduin
385828fcb3 feat(astyle): add option to only format diff with respect to HEAD (#27122)
* feat(astyle): add make format_changed for diff only style fixes

`make format` is pretty slow because it always considers the entire
source tree. For developing on top of a clean state, considering only
files that differ from HEAD should be sufficient.

* docs(astyle): document new format_changed target
2026-04-19 18:30:21 -08:00
Ramon Roche
a6d1822521 build(macos): inline homebrew deps in setup script, drop px4-dev meta-formula
Homebrew 4.5 (April 2026) stopped auto-tapping cross-tap
dependencies declared in formulae, as a security + performance
change. The px4-dev meta-formula pulled in packages from
osx-cross/arm, PX4/px4, and discoteq/discoteq, so 'brew install
px4-dev' now aborts before any real work unless every tap has been
added explicitly. On macos-latest CI runners the chain broke at the
first unreachable dep (discoteq/discoteq/flock) and subsequent make
steps failed with 'ccache: command not found'.

Since Tools/setup/macos.sh is the canonical install path and already
tapped osx-cross/arm and PX4/px4 before calling brew install, the
simplest fix is to inline the package list and call brew install
directly. The px4-dev meta-formula will be kept upstream as a
deprecated no-op so older copies of macos.sh on long-lived branches
and cached Docker images keep working.

The inlined package list is the same set px4-dev depended on, minus
the dead-weight flock dependency that hadn't been invoked in the PX4
build since the NuttX 9.1.x era. See the accompanying PX4/homebrew-px4
PR for formula changes.

Docs updated to match: docs/en/dev_setup/dev_env_mac.md no longer
names the px4-dev formula, describes the package list directly.

Verified locally on macOS ARM64:
- ./Tools/setup/macos.sh runs to completion with both taps and all 13
  packages resolving correctly
- make distclean && make px4_fmu-v6x_default builds successfully
  (1250/1250 ninja steps, 1930096 B FLASH used)

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
2026-04-18 13:04:26 -07:00