可用于开发和部署无人机与无人载具的自动驾驶功能。支持多旋翼、固定翼等多种平台,具备模块化架构、广泛硬件兼容性,提供 MAVLink 和 ROS 2 集成,以及完善的仿真测试工具。【此简介由AI生成】
| Files | Last commit | Last update |
|---|---|---|
chore(claude): add CLAUDE.md and tighten commit/pr skills (#27119) Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Signed-off-by: Ramon Roche <mrpollo@gmail.com> Co-authored-by: Ramon Roche <mrpollo@gmail.com> | 4 months ago | |
VSCode: add EditorConfig extension to recommended and devcontainer.json | 2 years ago | |
ci(labeler): remove auto-application of risk:safety-critical (#27567) The path globs matched a large fraction of the tree (e.g. src/modules/*_control/**, src/modules/sensors/**), so the label was applied to many PRs that aren't meaningfully safety-critical. Remove the rule so the label is applied manually during review instead. Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> | 3 months ago | |
feat(boards): add support for 3DR Control N1 flight controller (#27395) * fix(srgbled_dma): stm32_dmasetup now works with H7 boards * feat(drivers/ak09940a): add AKM AK09940A magnetometer driver * feat(boards/3dr/ctrl-n1)!: add 3DR Control-N1 flight controller * fix(boards/3dr/ctrl-n1): macro replacement list is now enclosed in parentheses * fix(boards/3dr/ctrl-n1): applying copyright changes * fix(boards/3dr/ctrl-n1): removing serial console | 3 months ago | |
feat(new_module): Static and moving vision-based target esitmator (Kalman Filter) (#23726) Co-authored-by: jonas <jonas.perolini@rigi.tech> | 3 months ago | |
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> | 3 months ago | |
feat(boards): add support for AEDROXH7 flight controller (#27226) * feat(boards): add support for AEDROXH7 flight controller STM32H743-based FPV / racing flight controller from AEDROX. Brings up: - ICM-42688-P IMU on SPI2 - DPS310 baro on internal I2C2 - W25N NAND flash on SPI3 with littlefs at /fs/flash - MAX7456 analog OSD on SPI1 - 8 motor outputs (TIM1 + TIM8) all bidirectional-DShot capable - CAN1 - External I2C1 connector for compass / sensors - 6 UARTs (TEL1, GPS1, RC, TEL2, ESC telemetry, debug console on UART8), - Two user GPIOs on the M5-M8 connector, VTX power and camera-switch GPIOs, buzzer on PA7 (active-buzzer transistor low-side switch), battery V/I sensing via ADC1. Board ID 1198 shared with ArduPilot's AP_HW_AEDROXH7 entry. USB enumerates as 0x16D0:0x14FE with VENDORSTR "AEDROX". Signed-off-by: Julian Oes <julian@oes.ch> * docs(docs): Minor subedit --------- Signed-off-by: Julian Oes <julian@oes.ch> Co-authored-by: Hamish Willee <hamishwillee@gmail.com> | 3 months ago | |
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> | 3 months ago | |
docs(i18n): PX4 guide translations (Crowdin) - zh-CN (#27596) Co-authored-by: Crowdin Bot <support+bot@crowdin.com> | 3 months ago | |
ci(mavros): remove MAVROS integration test suite Coverage overlaps with mavsdk_tests on iris (mission + offboard posctl); MAVROS plugin behavior belongs to the MAVROS project. Drops the workflow, .test launchers, rostest_px4_run.sh, and the integrationtests/ python helpers. Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 4 months ago | |
fix(fw_mode_manager/navigator): use the correct waypoint switching distance (#27571) * fix(fw_mode_manager/navigator): use the correct switch distance Before https://github.com/PX4/PX4-Autopilot/pull/24056, the fixed-wing position controller used to publish the acceptance radius (calculated depending on params and state by DirectionalGuidance::switchDistance) in the position controller status. The refactor migrated that to individual lateral/longitudinal topics, but left the receiving code in the navigator unchanged. As a consequence, fixed-wing vehicles now rely on NAV_ACC_RAD for the acceptance radius, rather than the adaptively calculated switchDistance. As NAV_ACC_RAD is only 10m by default this leads to overshoot, especially on tight corners. Fix by reintroducing the publication (now from FixedWingModeManager through fixed_wing_lateral_guidance_status) and using it in navigator. * fix(navigator_main): only listen to position controller status if rover rover_ackermann is the only remaining publisher after #24056 * style(msg): improve field description - @INVALID NaN - Describe relation with NAV_ACC_RAD * style(fw_mode_manager): remove stale include * docs(navigator): clarify acceptance logic in param description | 3 months ago | |
fix(shutdownlock): prevent external_reset_lockout from been hold for longer than 60 seconds | 3 months ago | |
fix(mavlink): remove all stale mavlink_tests references The mavlink_tests module was deleted in 1009268d311 but several references were left behind, breaking builds on all targets. Removed: - CMakeLists.txt: add_subdirectory(mavlink_tests) - mavlink_ftp.cpp: #include of deleted mavlink_ftp_test.h - mavlink_ftp.h: MavlinkFtpTest forward decl and friend class - posix-configs/SITL/init/test/test_mavlink: dead init script - sitl_tests.cmake: sitl-mavlink CTest target - install-voxl.sh: px4-mavlink_tests symlink Ref: https://github.com/PX4/PX4-Autopilot/issues/26738 Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 6 months ago | |
feat(uxrce_dds_client): allow building Micro-XRCE-DDS_Client v3 (#27597) Adds new nuttx config entry: UXRCE_DDS_CLIENT_USE_DDS_V3 Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com> | 3 months ago | |
Add srv/ folder and srv/VehicleCommand.srv update CI (github and Jenkins) to push changes of srv/ to PX4/px4_msgs repo Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com> | 2 years ago | |
ci(mavros): remove MAVROS integration test suite Coverage overlaps with mavsdk_tests on iris (mission + offboard posctl); MAVROS plugin behavior belongs to the MAVROS project. Drops the workflow, .test launchers, rostest_px4_run.sh, and the integrationtests/ python helpers. Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 4 months ago | |
lib/rc: Fix DSM2/DSMX guessing routine and DSM range checking (#18270) * Add Orangerx test case Co-authored-by: Chris Seto <chris.seto@bossanova.com> | 4 years ago | |
fix(logger): add MiB unit to SDLOG_MAX_SIZE (#27245) This required to add MiB as a unit to the parsers. While at it, I decided to clean up the MB log output and be correct using MiB instead. | 4 months ago | |
fix(ci): enable clang-tidy misc-header-include-cycle Signed-off-by: kuralme <kuralme@protonmail.com> | 4 months ago | |
build(packaging): add PX4 SITL .deb packages Add cmake/cpack infrastructure for building .deb packages from px4_sitl_sih and px4_sitl_default targets. Includes install rules, package scripts, Gazebo wrapper, and CI workflow. Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 5 months ago | |
Tools: Update macos dependencies (#25361) * tools: macos.sh update cross-compiler * tools: editor styleguide for bash scripts --------- Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 1 year ago | |
Move PX4 Guide source into /docs (#24490) * Add vitepress tree * Update existing workflows so they dont trigger on changes in the docs path * Add nojekyll, package.json, LICENCE etc * Add crowdin docs upload/download scripts * Add docs flaw checker workflows * Used docs prefix for docs workflows * Crowdin obvious fixes * ci: docs move to self hosted runner runs on a beefy server for faster builds Signed-off-by: Ramon Roche <mrpollo@gmail.com> * ci: don't run build action for docs or ci changes Signed-off-by: Ramon Roche <mrpollo@gmail.com> * ci: update runners Signed-off-by: Ramon Roche <mrpollo@gmail.com> * Add docs/en * Add docs assets and scripts * Fix up editlinks to point to PX4 sources * Download just the translations that are supported * Add translation sources for zh, uk, ko * Update latest tranlsation and uorb graphs * update vitepress to latest --------- Signed-off-by: Ramon Roche <mrpollo@gmail.com> Co-authored-by: Ramon Roche <mrpollo@gmail.com> | 1 year ago | |
fix(ci): remove accidentally committed local settings file .claude/settings.local.json contains user-specific Claude Code permissions and should never be in the repo. Remove it and add a .gitignore entry to prevent it from being committed again. Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 5 months ago | |
feat(uxrce_dds_client): allow building Micro-XRCE-DDS_Client v3 (#27597) Adds new nuttx config entry: UXRCE_DDS_CLIENT_USE_DDS_V3 Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com> | 3 months ago | |
docs(project): add CITATION.cff with Zenodo DOI Add a CITATION.cff file so GitHub shows a "Cite this repository" button. Lists the project founder and "The PX4 Contributors", linking to the Zenodo concept DOI (10.5281/zenodo.595432). Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 6 months ago | |
chore(claude): add CLAUDE.md and tighten commit/pr skills (#27119) Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com> Signed-off-by: Ramon Roche <mrpollo@gmail.com> Co-authored-by: Ramon Roche <mrpollo@gmail.com> | 4 months ago | |
fix(cmake): pin Python to project-local .venv on macOS (#27361) PR #27324 swapped find_package(PythonInterp) for find_package(Python3), whose macOS defaults (FRAMEWORK=FIRST, STRATEGY=VERSION) override Python3_ROOT_DIR and PATH to resolve the highest-versioned framework Python. CI then matched Homebrew's 3.14 while pip installed kconfiglib into the actions/setup-python 3.10 venv, breaking make px4_sitl configure with "No module named menuconfig". Pin Python3_EXECUTABLE to .venv/bin/python when present (macos.sh creates the venv but neither it nor CI exports VIRTUAL_ENV), and set FIND_STRATEGY=LOCATION + FIND_FRAMEWORK=LAST so dev machines and Linux containers without a venv still pick the interpreter that has the project's pip dependencies. | 3 months ago | |
fix(readme): remove trailing whitespace | 5 months ago | |
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 | 4 months ago | |
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> | 3 months ago | |
Update copyright year to 2025 in LICENSE file (#25778) | 10 months ago | |
docs(maintainers): add Jonas Perolini as Reviewer | 3 months ago | |
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> | 3 months ago | |
docs(docs): correct broken link (#27564) Co-authored-by: Wael Karman <wael.karman@agile-robots.com> | 3 months ago | |
docs(security): update policy for OpenSSF badge Update supported versions to 1.16.x, add response process with 7-day acknowledgment timeline, reporter credit policy, and secure development practices section. Signed-off-by: Ramon Roche <mrpollo@gmail.com> | 6 months ago | |
initial minimal PX4_ROS2 platform and px4_ros2_default build (#20689) - new ROS2 platform in PX4 intended for creating configs that build and run entirely in ROS2 - PX4_CONFIG defaults to px4_ros2_default if no config specified and in a colcon workspace with ROS_VERSION=2 - currently doesn't do much other than allow you to build px4 msgs interface package | 3 years ago |
行业广泛采用的自动驾驶系统。
关于
PX4 是适用于无人机和无人载具的开源自动驾驶系统。它支持多旋翼、固定翼、垂直起降(VTOL)、地面无人车以及从竞速四轴到工业测绘飞机等多种实验平台。可运行于 NuttX、Linux 和 macOS 系统。采用 BSD 3-Clause 许可协议。
选择 PX4 的理由
模块化架构。 PX4 围绕 uORB 构建,这是一种兼容 DDS 的发布/订阅中间件。各模块完全并行化且线程安全。您可以构建自定义配置,并精简掉不需要的功能。
广泛的硬件支持。 PX4 可在多种 自动驾驶飞控板 上运行,并通过 Pixhawk 生态系统支持各类传感器、数传电台和执行器。
开发者友好。 对 MAVLink 和 DDS / ROS 2 集成提供一流支持。具备全面的 SITL 仿真、硬件在环测试以及 日志分析 工具。在 Discord 和 每周开发者会议 上拥有活跃的开发者社区。
厂商中立的治理。 PX4 由 Dronecode 基金会 托管,该基金会隶属于 Linux 基金会。采用商业友好的 BSD-3 许可协议。没有任何单一厂商控制其发展路线图。
支持的载具
|
多旋翼 |
固定翼 |
垂直起降机 |
地面无人车 |
…以及更多类型:直升机、自转旋翼机、飞艇、潜艇、水面船只和其他实验平台。这些机型具备基础支持,但未纳入常规飞行测试项目。详见 完整机型参考。
试用 PX4
通过单条命令即可在仿真环境中运行 PX4。无需构建工具,仅需 Docker 环境:
docker run --rm -it -p 14550:14550/udp px4io/px4-sitl:latest
打开 QGroundControl 并飞行。更多选项请参见 PX4 仿真快速入门。
从源代码构建
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
make px4_sitl
Note
有关工具链设置和构建选项,请参见 开发指南。
文档与资源
| 资源 | 描述 |
|---|---|
| 用户指南 | PX4 的构建、配置与飞行指南 |
| 开发者指南 | 飞行栈修改、外设添加及新硬件移植指南 |
| 机架参考 | 支持的机架完整列表 |
| 自动驾驶硬件 | 兼容的飞行控制器 |
| 发布说明 | 各版本新增功能介绍 |
| 贡献指南 | 如何为 PX4 贡献代码 |
社区
- 每周开发者会议 — 对所有开发者开放(Dronecode 日历)
- Discord — 加入 Dronecode 服务器
- 讨论论坛 — PX4 Discuss
- 维护者 — 参见
MAINTAINERS.md - 贡献者统计 — LFX Insights
贡献
我们欢迎各种形式的贡献,包括错误报告、文档编写、新功能开发和代码审查。请阅读 贡献指南 以开始参与。
引用
如果您在学术工作中使用 PX4,请引用它。BibTeX 格式:
@software{px4_autopilot,
author = {Meier, Lorenz and {The PX4 Contributors}},
title = {{PX4 Autopilot}},
publisher = {Zenodo},
doi = {10.5281/zenodo.595432},
url = {https://px4.io}
}
上述 DOI 是一个 Zenodo 概念 DOI,始终指向最新版本。如需固定版本的引用,请参见 Zenodo 记录 或我们的 CITATION.cff。
治理
PX4 Autopilot 项目由 Dronecode 基金会 托管,该基金会是 Linux 基金会 的一个协作项目。Dronecode 拥有所有 PX4 商标,并作为项目的法律监护人,确保供应商中立的管理——没有任何一家公司拥有该名称或控制路线图。源代码根据 BSD 3-Clause 许可证授权,因此您可以在自己的项目中自由使用、修改和分发。
Introduction
可用于开发和部署无人机与无人载具的自动驾驶功能。支持多旋翼、固定翼等多种平台,具备模块化架构、广泛硬件兼容性,提供 MAVLink 和 ROS 2 集成,以及完善的仿真测试工具。【此简介由AI生成】
Customize your domain