This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new bf651eec777 arch/rp2040: fail build when boot2 cannot be generated
bf651eec777 is described below
commit bf651eec777b2bf96a50ad1d6e498b53186ffd26
Author: Brijesh Thakkar <[email protected]>
AuthorDate: Sat Oct 17 23:30:37 2026 +0530
arch/rp2040: fail build when boot2 cannot be generated
Flash builds (CONFIG_RP2040_FLASH_BOOT=y) need the 256-byte second
stage bootloader (boot2), which is built from the pico-sdk sources.
Since commit cf72133d3c ("rp2040: Continue to build even if
PICO_SDK_PATH is not set", #2887) the Make build silently skips boot2
when PICO_SDK_PATH is not set. The vector table then lands at
0x10000000, the BOOTROM rejects the boot2 CRC and the board falls
back to BOOTSEL mode. If picotool is in $PATH a nuttx.uf2 is still
produced, without any warning.
#2887 made this non-fatal because CI had no pico-sdk at the time.
CI now provides PICO_SDK_PATH (Docker image, linux.sh, ubuntu.sh and
windows.ps1) and the CMake build already fails when it is not set.
Check in PREBUILD, before anything is compiled, that PICO_SDK_PATH
is set and that the boot2 source for CONFIG_RP2040_FLASH_CHIP exists,
and stop with an error saying how to fix it. Include boot2/Make.defs
unconditionally for flash builds so both paths cannot drift apart
again. Add the same file check to the CMake build, which only checked
that the variable was set. SRAM boot builds are not affected.
Fixes #17516
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Brijesh Thakkar <[email protected]>
---
Documentation/platforms/arm/rp2040/index.rst | 8 +++++++-
arch/arm/src/rp2040/Make.defs | 2 --
arch/arm/src/rp2040/boot2/rp2040_boot_stage2.cmake | 7 +++++++
tools/rp2040/Config.mk | 23 ++++++++++++++++++++++
4 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/Documentation/platforms/arm/rp2040/index.rst
b/Documentation/platforms/arm/rp2040/index.rst
index 64f10eb08d1..c5fee5c2673 100644
--- a/Documentation/platforms/arm/rp2040/index.rst
+++ b/Documentation/platforms/arm/rp2040/index.rst
@@ -31,7 +31,7 @@ IRQs
DMA
Clock Output
ws2812 Smart pixels (e.g. Neopixel)
-Flash ROM Boot
+Flash ROM Boot Requires the Pico SDK (``PICO_SDK_PATH``) to build the boot2
stage.
SRAM Boot If Pico SDK is available a nuttx.uf2 file will be created
BMP180 Requires I2C0
INA219 Requires I2C0
@@ -84,6 +84,12 @@ Installation
$ export PICO_SDK_PATH=<absolute_path_to_pico-sdk_directory>
+ ``PICO_SDK_PATH`` is required for flash builds
(``CONFIG_RP2040_FLASH_BOOT=y``,
+ the default): the second stage bootloader (boot2) at the start of flash is
+ built from the SDK sources, and an image without it does not boot. The build
+ stops with an error if ``PICO_SDK_PATH`` is not set or does not point to a
+ pico-sdk checkout. SRAM boot configurations do not need it.
+
You will have to do this every time you restart the terminal where you are
building NuttX, so it might be best to include this command in your
``bashrc`` so NuttX's build system always knows where to find the SDK.
diff --git a/arch/arm/src/rp2040/Make.defs b/arch/arm/src/rp2040/Make.defs
index a3ac3780095..b21d40315ab 100644
--- a/arch/arm/src/rp2040/Make.defs
+++ b/arch/arm/src/rp2040/Make.defs
@@ -98,8 +98,6 @@ CHIP_ASRCS += rp2040_flash_initialize.S
endif
ifeq ($(CONFIG_RP2040_FLASH_BOOT),y)
-ifneq ($(PICO_SDK_PATH),)
include chip/boot2/Make.defs
endif
-endif
CHIP_CSRCS += rp2040_atomic.c
diff --git a/arch/arm/src/rp2040/boot2/rp2040_boot_stage2.cmake
b/arch/arm/src/rp2040/boot2/rp2040_boot_stage2.cmake
index f6b4330e0d4..f1851c486e3 100644
--- a/arch/arm/src/rp2040/boot2/rp2040_boot_stage2.cmake
+++ b/arch/arm/src/rp2040/boot2/rp2040_boot_stage2.cmake
@@ -35,6 +35,13 @@ function(pico_define_boot_stage2 NAME path_chip)
set(PICO_BOOT_STAGE2_DIR "${PICO_SDK_PATH}/src/rp2040/boot_stage2")
set(BOOT2SRC "${PICO_BOOT_STAGE2_DIR}/boot2_${CONFIG_RP2040_FLASH_CHIP}.S")
+ if(NOT EXISTS ${BOOT2SRC})
+ message(
+ FATAL_ERROR
+ "${BOOT2SRC} not found. PICO_SDK_PATH must point to a pico-sdk
checkout, it is needed to build the boot2 stage, the image will not boot
without it."
+ )
+ endif()
+
string(REPLACE "." "-" NUTTX_BOARD_NAME "${NUTTX_BOARD}")
set(BOOT2CFLAGSLIST
diff --git a/tools/rp2040/Config.mk b/tools/rp2040/Config.mk
index 54a00132506..fa1aa4ea8f6 100644
--- a/tools/rp2040/Config.mk
+++ b/tools/rp2040/Config.mk
@@ -24,6 +24,29 @@
# and assembly source files and to insert the resulting object files into an
# archive. These replace the default definitions at tools/Config.mk
+# PREBUILD -- Perform pre build operations
+
+# Flash builds need the second stage bootloader (boot2) from the pico-sdk.
+# Without it the BOOTROM rejects the image and stays in BOOTSEL mode, so
+# stop before anything is compiled instead of producing an image that does
+# not boot.
+
+ifeq ($(CONFIG_RP2040_FLASH_BOOT),y)
+ BOOT2_FLASH_CHIP := $(patsubst "%",%,$(strip $(CONFIG_RP2040_FLASH_CHIP)))
+ BOOT2_SRC :=
$(PICO_SDK_PATH)/src/rp2040/boot_stage2/boot2_$(BOOT2_FLASH_CHIP).S
+ BOOT2_WHY := it is needed to build the boot2 stage, the image will not boot
without it
+
+ ifeq ($(PICO_SDK_PATH),)
+ define PREBUILD
+ $(error "PICO_SDK_PATH is not set, $(BOOT2_WHY). Run: export
PICO_SDK_PATH=<path to pico-sdk>")
+ endef
+ else ifeq ($(wildcard $(BOOT2_SRC)),)
+ define PREBUILD
+ $(error "$(BOOT2_SRC) not found. PICO_SDK_PATH must point to a pico-sdk
checkout, $(BOOT2_WHY)")
+ endef
+ endif
+endif
+
# POSTBUILD -- Perform post build operations
PICOTOOL_FOUND := $(shell command -v picotool 2> /dev/null)