Skip to content

boards/rp2040: support reboot bootloader via reset_usb_boot() - #20059

Merged
xiaoxiang781216 merged 1 commit into
apache:masterfrom
JianyuWang0623:rp2040/reset-usb-boot
Sep 5, 2026
Merged

boards/rp2040: support reboot bootloader via reset_usb_boot()#20059
xiaoxiang781216 merged 1 commit into
apache:masterfrom
JianyuWang0623:rp2040/reset-usb-boot

Conversation

@JianyuWang0623

Copy link
Copy Markdown
Contributor

Note: Please adhere to Contributing Guidelines.

Summary

RP2040 defines ROM_RESET_USB_BOOT in arch/arm/src/rp2040/rp2040_rom.h
(the bootrom reset_usb_boot() entry point), but it was never wired up.
board_reset() in boards/arm/rp2040/common/src/rp2040_reset.c was a
stub that always called up_systemreset() regardless of the requested
reset reason, so RP2040 boards had no way to re-enter the USB
mass-storage BOOTSEL bootloader from software.

This matches the pattern already implemented for rp23xx
(boards/arm/rp23xx/common/src/rp23xx_reset.c and
boards/risc-v/rp23xx-rv/common/src/rp23xx_reset.c), which look up a
ROM reboot function and call it when the reset reason is
BOARDIOC_SOFTRESETCAUSE_ENTER_BOOTLOADER.

Changes:

  • arch/arm/src/rp2040/rp2040_rom.h: add the rom_reset_usb_boot_fn
    function pointer typedef for the bootrom reset_usb_boot(uint32_t, uint32_t) entry (signature matches the official pico-sdk
    pico/bootrom.h).
  • boards/arm/rp2040/common/src/rp2040_reset.c: in board_reset(),
    when status == BOARDIOC_SOFTRESETCAUSE_ENTER_BOOTLOADER, look up
    ROM_RESET_USB_BOOT via ROM_LOOKUP() and call it with
    (0, 0) (no GPIO activity LED, no interfaces disabled). All other
    status values keep the existing up_systemreset() behavior.

Impact

  • The change is in boards/arm/rp2040/common/, so it affects every
    RP2040 board that selects CONFIG_BOARDCTL_RESET
    (raspberrypi-pico, raspberrypi-pico-w,
    adafruit-feather-rp2040, seeed-xiao-rp2040, w5500-evb-pico,
    waveshare-rp2040-lcd-1.28, etc.).
  • No Kconfig/defconfig changes required; behavior for
    nsh> reboot / reboot assert / reboot panic / etc. is unchanged.
  • New capability: nsh> reboot bootloader now re-enters the RP2040
    BOOTSEL USB mass-storage bootloader directly, without needing to
    hold the physical BOOTSEL button.

Testing

Host: Ubuntu, arm-none-eabi-gcc toolchain.

Build

Compiled cleanly for both:

  • raspberrypi-pico:nsh
  • waveshare-rp2040-lcd-1.28:usbnsh (the board actually flashed for
    hardware testing below)
CC:  src/rp2040_reset.c
...
LD: nuttx
Generating: nuttx.uf2
Done.

tools/nxstyle reports no issues on either changed file.

Hardware test (Waveshare RP2040-LCD-1.28, RP2040, flash id
0xE4634C65670D202F)

Flashed waveshare-rp2040-lcd-1.28:usbnsh (includes this change) via
picotool load -x. Board enumerates as expected:

$ lsusb | grep -i 0525
Bus 001 Device 127: ID 0525:a4a7 Netchip Technology, Inc. Linux-USB Serial Gadget (CDC ACM mode)
$ udevadm info -a -n /dev/ttyACM4 | grep -E "manufacturer|product"
ATTRS{manufacturer}=="NuttX"
ATTRS{product}=="CDC/ACM Serial"

Connected to /dev/ttyACM4 and got an nsh prompt:

NuttShell (NSH) NuttX-13.0.1-RC0
nsh>

Sent reboot bootloader over the USB serial console. The console
connection was torn down immediately (device disconnected):

exception: device reports readiness to read but returned no data
(device disconnected or multiple access on port?)

Polling lsusb/lsblk afterwards shows the board re-enumerated as
the RP2040 ROM USB bootloader, with no physical BOOTSEL button
pressed at any point during this test:

$ lsusb | grep -i 2e8a
Bus 001 Device 126: ID 2e8a:0003 Raspberry Pi RP2 Boot

$ lsblk
sdc           8:32   1   128M  0 disk
└─sdc1        8:33   1   128M  0 part

$ blkid /dev/sdc1
/dev/sdc1: SEC_TYPE="msdos" LABEL_FATBOOT="RPI-RP2" LABEL="RPI-RP2" TYPE="vfat"

$ udevadm info -a -n /dev/sdc1 | grep -E "idVendor|idProduct|manufacturer|product"
ATTRS{idVendor}=="2e8a"
ATTRS{idProduct}=="0003"
ATTRS{manufacturer}=="Raspberry Pi"
ATTRS{product}=="RP2 Boot"

This confirms nsh> reboot bootloader re-enters BOOTSEL purely in
software, matching the behavior of boards/arm/rp23xx /
boards/risc-v/rp23xx-rv. After the test, the same firmware image
was reflashed and the board returned to normal nsh operation.

Plain nsh> reboot (no argument) was not re-tested after the final
readability changes (using BOARDIOC_SOFTRESETCAUSE_ENTER_BOOTLOADER
instead of a raw literal is logically a no-op change), but the
else branch calling up_systemreset() is unchanged from upstream.

Add reset_usb_boot ROM function typedef and wire it into
board_reset() so that 'nsh> reboot bootloader'
(BOARDIOC_SOFTRESETCAUSE_ENTER_BOOTLOADER) on RP2040 boards enters
BOOTSEL USB mass-storage mode directly, matching the behavior
already available on rp23xx boards.  All other status values keep
the existing up_systemreset() behavior.

This affects all boards under boards/arm/rp2040/common (pico,
pico-w, feather-rp2040, xiao-rp2040, w5500-evb-pico, etc.) since
the change is in the shared board_reset() implementation.

Assisted-by: GitHubCopilot:claude-4.6-opus
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Size: S The size of the change in this PR is small Board: arm labels Sep 4, 2026
@JianyuWang0623
JianyuWang0623 marked this pull request as ready for review September 4, 2026 16:07
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@xiaoxiang781216
xiaoxiang781216 merged commit 71499bd into apache:master Sep 5, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Board: arm Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants