From 59aa1e7331690963289af22745bd31f3785d0c5b Mon Sep 17 00:00:00 2001 From: Peter Harper Date: Fri, 12 Dec 2025 12:58:51 +0000 Subject: [PATCH] Flash functions in PICO_NO_FLASH binaries We assume that PICO_NO_FLASH binaries means the device does not have a flash chip. But it's possible that you want a ram binary AND want to mess about with flash, e.g. for flash nuke or something that uses the unique flash id. Add PICO_INCLUDE_FLASH_UTILS which forces some flash functions to be included. --- src/rp2_common/hardware_flash/flash.c | 4 ++-- src/rp2_common/hardware_flash/include/hardware/flash.h | 5 +++++ src/rp2_common/pico_unique_id/unique_id.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/rp2_common/hardware_flash/flash.c b/src/rp2_common/hardware_flash/flash.c index fbca8de2c..1008488e2 100644 --- a/src/rp2_common/hardware_flash/flash.c +++ b/src/rp2_common/hardware_flash/flash.c @@ -248,7 +248,7 @@ void __no_inline_not_in_flash_func(flash_range_program)(uint32_t flash_offs, con //----------------------------------------------------------------------------- // Lower-level flash access functions -#if !PICO_NO_FLASH +#if !PICO_NO_FLASH || PICO_INCLUDE_FLASH_UTILS // Bitbanging the chip select using IO overrides, in case RAM-resident IRQs // are still running, and the FIFO bottoms out. (the bootrom does the same) static void __no_inline_not_in_flash_func(flash_cs_force)(bool high) { @@ -334,7 +334,7 @@ void __no_inline_not_in_flash_func(flash_do_cmd)(const uint8_t *txbuf, uint8_t * static_assert(FLASH_UNIQUE_ID_SIZE_BYTES == FLASH_RUID_DATA_BYTES, ""); void flash_get_unique_id(uint8_t *id_out) { -#if PICO_NO_FLASH +#if PICO_NO_FLASH && !PICO_INCLUDE_FLASH_UTILS __unused uint8_t *ignore = id_out; panic_unsupported(); #else diff --git a/src/rp2_common/hardware_flash/include/hardware/flash.h b/src/rp2_common/hardware_flash/include/hardware/flash.h index 2bb5d5ae3..8e05a65ea 100644 --- a/src/rp2_common/hardware_flash/include/hardware/flash.h +++ b/src/rp2_common/hardware_flash/include/hardware/flash.h @@ -52,6 +52,11 @@ // PICO_CONFIG: PICO_FLASH_SIZE_BYTES, size of primary flash in bytes, type=int, default=Usually provided via board header, group=hardware_flash +// PICO_CONFIG: PICO_INCLUDE_FLASH_UTILS, Force inclusion of flash functions in PICO_NO_FLASH binaries. Has no effect in flash binaries, type=bool, default=0, group=hardware_flash +#ifndef PICO_INCLUDE_FLASH_UTILS +#define PICO_INCLUDE_FLASH_UTILS 0 +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/src/rp2_common/pico_unique_id/unique_id.c b/src/rp2_common/pico_unique_id/unique_id.c index 28204eda0..abae77a30 100644 --- a/src/rp2_common/pico_unique_id/unique_id.c +++ b/src/rp2_common/pico_unique_id/unique_id.c @@ -20,7 +20,7 @@ static pico_unique_board_id_t retrieved_id; static void __attribute__((PICO_UNIQUE_BOARD_ID_INIT_ATTRIBUTES)) _retrieve_unique_id_on_boot(void) { #if PICO_RP2040 - #if PICO_NO_FLASH + #if PICO_NO_FLASH && !PICO_INCLUDE_FLASH_UTILS // The hardware_flash call will panic() if called directly on a NO_FLASH // build. Since this constructor is pre-main it would be annoying to // debug, so just produce something well-defined and obviously wrong.