RP2350: boot_stage2 never run? resulting in incorrect flash config #1903
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#1903
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I recently noticed that
PICO_FLASH_SPI_CLKDIVwas not having any effect on my project ported to RP2350, whereas it worked fine with RP2040 before.This reproduced when using the stock Pico 2 and Pimoroni Pico Plus 2 board files, which use the same
boot2_w25q080.Sboot_stage2. It does get assembled.The QMI timing values I am seeing on a MCVE (provided below) don't match my expectations reading the boot script.
When ripping out all the code from
boot2_w25q080.S, behavior is unchanged! (Adding garbage to it, it fails to assemble, so it is still getting selected somewhere.)The lower byte of
timingshould be2(the default CLKDIV), thercmdis missing the upper byte that should have gotten configured, etc. -- so I am assuming it is inheriting whatever the bootrom had configured.(EDIT: Writing to those regs works fine; I've been doing it.)
I observed this issue both selecting the
2.0.0tag and the latestdeveloptip.Repro:
Per release notes:
boot_stage2is not needed on RP2350, but one can be included via the definePICO_EMBED_XIP_SETUP=1.Could perhaps be better documented (this is a compile definition).. also perhaps surprising that it builds without it but that is orthogonal
For clarification, by "ripping out all the code" from the stage2 I mostly meant the instructions under
_stage2_boot.But thank you,
PICO_EMBED_XIP_SETUP=1does indeed solve the problem. However, shouldn't that be the default for any non-default flash configuration?sorry can someone explain where to add the PICO_EMBED_XIP_SETUP=1 command ?
In
CMakeLists.txt, after your target is specified:Note that I had an issue enabling this where the program would immediately crash when debugging(?), which I haven't tried to test on a standard Pico 2. I haven't tried to debug it further.
I observed a weird issue where i haven't been able to enable continuous reads through the QMI registers, as it would just immediately crash upon returning to execution from flash.
If you only care about changing the clock divisor for flash, you can do this at runtime, with something like this (in C++), assuming the Pico 2 flash (including the Pimoroni Pico Plus 2) -- at least AFAIK:
Call that function before initializing the second core (if you use it at all) and before changing the clock frequency, if this is for core overclocking reasons.
@asumagic your code in the post above works if you just want to read flash after overclocking, but it didn't work for me when I start to write flash. I suspect the SDK reverts the divider at the end of each call to the write function. PICO_EMBED_XIP_SETUP=1 does however work for both.
But thanks for raising this, it helped me a lot!
You are correct: #1983
Yeah, the ROM creates a tiny stub for you in boot RAM (where the copy of the XIP setup is stored if you have one) which restores whatever flash parameters it found during startup. The SDK executes that XIP setup from boot RAM after completing a flash operation, to set flash back up again. This is mostly a big improvement over RP2040 since you can just wire up say a dual-SPI flash on your board and the ROM will figure things out and boot into your flash application without any configuration.
The intent when modifying the XIP configuration from the parameters found by the ROM is:
PICO_EMBED_XIP_SETUP=1does exactly this. It just doesn't help you out if you've done raw register accesses.We could improve the setup-less behaviour, e.g. by creating a new stub that sets your divider if you have specified a
PICO_FLASH_SPI_CLKDIVbut haven't specified a boot2. Something else I think would ease confusion is makingPICO_EMBED_XIP_SETUP=1be implied by selecting a boot2. I don't think it's going to happen for this upcoming release though.