pico_set_persistent_data_loc causes incorrect RAM usage calculation in memory report (SDK 2.3.0 & 2.3.1) #3184

Closed
opened 2026-09-06 11:01:19 -05:00 by JoaoBortolace · 4 comments
JoaoBortolace commented 2026-09-06 11:01:19 -05:00 (Migrated from github.com)

Issue

When using __persistent_data and overriding its placement via pico_set_persistent_data_loc(), the generated build memory report incorrectly calculates total RAM usage.

  • In SDK 2.3.0, placing section at an absolute offset (e.g., 0x20040000) causes the memory reporter script/tool to include the memory gap into the total used RAM, artificially inflating the reported usage.
  • In SDK 2.3.1, variables placed in __persistent_data are completely excluded/ignored from the RAM used size calculation, reporting lower memory usage than actual.

To Reproduce

  1. Define a global array using __persistent_data:
    uint8_t __persistent_data(data[16384]) = {0};
    
  2. Set persistent data location in CMakeLists.txt:
    pico_set_persistent_data_loc(your_target 0x20040000)
    set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--print-memory-usage")
    
  3. Build the project and observe the memory report printed at the end of compilation.

Expected behavior

The memory report should accurately account for the 16 KB allocated in RAM under the RAM row (or a dedicated PERSISTENT memory region row), without inflating usage due to section gaps or omitting the section entirely.


Build Output Logs

Baseline (without __persistent_data):

Memory region         Used Size     Region Size     %age Used
           FLASH:       46824 B            4 MB         1.12%
           PSRAM:           0 B             0 B
         XIP_RAM:           0 B           16 KB         0.00%
             RAM:      102520 B          512 KB        19.55%
       SCRATCH_X:          2 KB            4 KB        50.00%
       SCRATCH_Y:          2 KB            4 KB        50.00%

SDK 2.3.1 Output (Omits persistent data from RAM calculation):

RAM reported drops from 102520 B to 86136 B (102520 B - 16384 B = 86136 B), completely ignoring the 16 KB array.

Memory region         Used Size     Region Size     %age Used
           FLASH:       46824 B            4 MB         1.12%
           PSRAM:           0 B             0 B
         XIP_RAM:           0 B           16 KB         0.00%
             RAM:       86136 B          512 KB        16.43%
       SCRATCH_X:          2 KB            4 KB        50.00%
       SCRATCH_Y:          2 KB            4 KB        50.00%

SDK 2.3.0 Output (Includes offset gap into RAM calculation):

RAM reported jumps to 280600 B due to the absolute address offset.

Memory region         Used Size     Region Size     %age Used
           FLASH:       46732 B            4 MB         1.11%
           PSRAM:           0 B             0 B
         XIP_RAM:           0 B           16 KB         0.00%
             RAM:      280600 B          512 KB        53.52%
       SCRATCH_X:          2 KB            4 KB        50.00%
       SCRATCH_Y:          2 KB            4 KB        50.00%

Environment Information

  • SDK Version: 2.3.0 & 2.3.1
  • Target: RP2350 ARM
  • Build System: CMake / GCC 15.2.Rel1
## Issue When using `__persistent_data` and overriding its placement via `pico_set_persistent_data_loc()`, the generated build memory report incorrectly calculates total RAM usage. * In **SDK 2.3.0**, placing section at an absolute offset (e.g., `0x20040000`) causes the memory reporter script/tool to include the memory gap into the total used RAM, artificially inflating the reported usage. * In **SDK 2.3.1**, variables placed in `__persistent_data` are completely excluded/ignored from the `RAM` used size calculation, reporting lower memory usage than actual. --- ## To Reproduce 1. Define a global array using `__persistent_data`: ```c uint8_t __persistent_data(data[16384]) = {0}; ``` 2. Set persistent data location in `CMakeLists.txt`: ```cmake pico_set_persistent_data_loc(your_target 0x20040000) set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--print-memory-usage") ``` 3. Build the project and observe the memory report printed at the end of compilation. --- ## Expected behavior The memory report should accurately account for the 16 KB allocated in RAM under the `RAM` row (or a dedicated `PERSISTENT` memory region row), without inflating usage due to section gaps or omitting the section entirely. --- ## Build Output Logs ### Baseline (without `__persistent_data`): ```text Memory region Used Size Region Size %age Used FLASH: 46824 B 4 MB 1.12% PSRAM: 0 B 0 B XIP_RAM: 0 B 16 KB 0.00% RAM: 102520 B 512 KB 19.55% SCRATCH_X: 2 KB 4 KB 50.00% SCRATCH_Y: 2 KB 4 KB 50.00% ``` ### SDK 2.3.1 Output (Omits persistent data from RAM calculation): *`RAM` reported drops from 102520 B to 86136 B (102520 B - 16384 B = 86136 B), completely ignoring the 16 KB array.* ```text Memory region Used Size Region Size %age Used FLASH: 46824 B 4 MB 1.12% PSRAM: 0 B 0 B XIP_RAM: 0 B 16 KB 0.00% RAM: 86136 B 512 KB 16.43% SCRATCH_X: 2 KB 4 KB 50.00% SCRATCH_Y: 2 KB 4 KB 50.00% ``` ### SDK 2.3.0 Output (Includes offset gap into RAM calculation): *`RAM` reported jumps to 280600 B due to the absolute address offset.* ```text Memory region Used Size Region Size %age Used FLASH: 46732 B 4 MB 1.11% PSRAM: 0 B 0 B XIP_RAM: 0 B 16 KB 0.00% RAM: 280600 B 512 KB 53.52% SCRATCH_X: 2 KB 4 KB 50.00% SCRATCH_Y: 2 KB 4 KB 50.00% ``` --- ## Environment Information * **SDK Version:** 2.3.0 & 2.3.1 * **Target:** RP2350 ARM * **Build System:** CMake / GCC 15.2.Rel1
peterharperuk commented 2026-09-07 04:41:22 -05:00 (Migrated from github.com)

"the generated build memory report incorrectly calculates total RAM usage"

What report is this? What script is generating this?

"the generated build memory report incorrectly calculates total RAM usage" What report is this? What script is generating this?
will-v-pi commented 2026-09-07 05:05:11 -05:00 (Migrated from github.com)

"the generated build memory report incorrectly calculates total RAM usage"

What report is this? What script is generating this?

It's the --print-memory-usage report from the linker

I believe this is caused by https://github.com/raspberrypi/pico-sdk/pull/3109 - in SDK 2.3.0 the heap was being placed above persistent data in this circumstance(which was incorrect), causing all of that RAM to be counted as used. With that PR, the heap is correctly placed before persistent data, so the RAM is showing as unused above the heap.

I'm not sure why the .persistent_data section isn't appearing in --print-memory-usage - my guess would be it's because the location counter gets moved backwards after it was placed, which causes --print-memory-usage to miss it. This doesn't occur for .persistent_data placed at a fixed address in XIP SRAM.

> "the generated build memory report incorrectly calculates total RAM usage" > > What report is this? What script is generating this? It's the `--print-memory-usage` report from the linker I believe this is caused by https://github.com/raspberrypi/pico-sdk/pull/3109 - in SDK 2.3.0 the heap was being placed above persistent data in this circumstance(which was incorrect), causing all of that `RAM` to be counted as used. With that PR, the heap is correctly placed before persistent data, so the `RAM` is showing as unused above the heap. I'm not sure why the `.persistent_data` section isn't appearing in `--print-memory-usage` - my guess would be it's because the location counter gets moved backwards after it was placed, which causes `--print-memory-usage` to miss it. This doesn't occur for `.persistent_data` placed at a fixed address in XIP SRAM.
will-v-pi commented 2026-09-07 14:40:01 -05:00 (Migrated from github.com)

It looks like this might not be possible to fix - --print-memory-usage looks at the final value of the location counter, so will treat the holes that placing .persistent_data creates as used space if the heap is above it (sram0 case), or will not include .persistent_data if the heap is below it (sram1 case, as the final value of the location counter has been moved back).

It might be possible to revert it to the 2.3.0 behaviour with some extra linker bits, but I don’t think that is worth it, given the current memory usage printout is a more realistic view of the situation. Instead, I think I will add some docs to pico_set_persistent_data_loc to describe this behaviour.

It looks like this might not be possible to fix - `--print-memory-usage` looks at the final value of the location counter, so will treat the holes that placing `.persistent_data` creates as used space if the heap is above it (sram0 case), or will not include `.persistent_data` if the heap is below it (sram1 case, as the final value of the location counter has been moved back). It might be possible to revert it to the 2.3.0 behaviour with some extra linker bits, but I don’t think that is worth it, given the current memory usage printout is a more realistic view of the situation. Instead, I think I will add some docs to `pico_set_persistent_data_loc` to describe this behaviour.
will-v-pi commented 2026-09-09 06:07:21 -05:00 (Migrated from github.com)

@JoaoBortolace I've opened #3191 to fix the docs here

@JoaoBortolace I've opened #3191 to fix the docs here
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#3184
No description provided.