Flash memory overflow message on pico lipo 16MB

Hello,
I’m trying to turn a 16 MB pico lipo into a Chinese-English dictionary. My code works fine when there are only 1,000 entries in the dictionary, but when there are 10,000 entries, I get the following error when running make:

[ 97%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/lib/tinyusb/src/class/video/video_device.c.obj
[ 97%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c.obj
[ 97%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/lib/tinyusb/src/tusb.c.obj
[ 98%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/lib/tinyusb/src/common/tusb_fifo.c.obj
[ 98%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c.obj
[ 98%] Building C object CMakeFiles/epd.dir/home/astra/pico/pico-sdk/src/rp2_common/hardware_spi/spi.c.obj
[100%] Linking CXX executable epd.elf
/usr/lib/gcc/arm-none-eabi/10.3.1/…/…/…/arm-none-eabi/bin/ld: epd.elf section .rodata' will not fit in region FLASH’
/usr/lib/gcc/arm-none-eabi/10.3.1/…/…/…/arm-none-eabi/bin/ld: region `FLASH’ overflowed by 638420 bytes
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/epd.dir/build.make:1212: epd.elf] Error 1
make[1]: *** [CMakeFiles/Makefile2:1604: CMakeFiles/epd.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Currently, the file containing font data for the Chinese characters is about 4.6 MB, and the file containing dictionary entries is about 800 kB, so it should be well within the space requirements.

I’m running cmake with the -D PICO_BOARD=“pimoroni_picolipo_16mb” option. Here’s what cmake spits out:

mycomputer@LAPTOP-61HUGN86:~/pyCode/dictForPico/build$ cmake -D PICO_BOARD=“pimoroni_picolipo_16mb” …
Using PICO_SDK_PATH from environment (‘/home/mycomputer/pico/pico-sdk’)
PICO_SDK_PATH is /home/mycomputer/pico/pico-sdk
Defaulting PICO_PLATFORM to rp2040 since not specified.
Defaulting PICO platform compiler to pico_arm_gcc since not specified.
– Defaulting build type to ‘Release’ since not specified.
PICO compiler is pico_arm_gcc
– The CXX compiler identification is GNU 10.3.1
– The C compiler identification is GNU 10.3.1
– The ASM compiler identification is GNU
– Found assembler: /usr/bin/arm-none-eabi-gcc
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Check for working CXX compiler: /usr/bin/arm-none-eabi-g++ - skipped
– Detecting CXX compile features
– Detecting CXX compile features - done
– Detecting C compiler ABI info
– Detecting C compiler ABI info - done
– Check for working C compiler: /usr/bin/arm-none-eabi-gcc - skipped
– Detecting C compile features
– Detecting C compile features - done
Build type is Release
PICO target board is pimoroni_picolipo_16mb.
Using board configuration from /home/mycomputer/pico/pico-sdk/src/boards/include/boards/pimoroni_picolipo_16mb.h
– Found Python3: /usr/bin/python3.10 (found version “3.10.6”) found components: Interpreter
TinyUSB available at /home/mycomputer/pico/pico-sdk/lib/tinyusb/src/portable/raspberrypi/rp2040; enabling build support for USB.
BTstack available at /home/mycomputer/pico/pico-sdk/lib/btstack
cyw43-driver available at /home/mycomputer/pico/pico-sdk/lib/cyw43-driver
Pico W Bluetooth build support available.
lwIP available at /home/mycomputer/pico/pico-sdk/lib/lwip
mbedtls available at /home/mycomputer/pico/pico-sdk/lib/mbedtls
– Configuring done
– Generating done
– Build files have been written to: /home/mycomputer/pyCode/dictForPico/build

I know that pico-sdk/src/boards/include/boards/pimoroni_picolipo_16mb.h has

#ifndef PICO_FLASH_SIZE_BYTES
#define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024)
#endif

I changed the PICO_FLASH_SIZE_BYTES to be 166 MB instead of 16 just to see what would happen, and there was no effect - I still got the message that region `FLASH’ overflowed by 638420 bytes. How can I get my code to recognize that my pico actually does have 16MB of flash?

Answer here - the 2MB limit needs to be changed in …/pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld.
Now my code compiles, but it still won’t run if the dictionary is too large. Is there anything else that I’m missing?

Flash is one thing, RAM the other. The latter is much smaller (264kB). So if you load a large dictionary, this will probably be too much.

The linker seems to indicate that it was using flash. How can I control how much gets loaded into RAM at a time? The dictionary is currently stored in three C++ vectors of (C++) strings:

vector chineseEntries = {
“一”,
“一丁不识”,
“一丁点”,
“一下”,
“一下子”,
“一不小心”
}

If I later access, say, chineseEntries[3], does it try to load the entire vector into RAM at once?

The linker will put your vector (as part of your code) into flash. And the RP2040 can execute code directly from flash. But the vector content isn’t code, it is not executed.

Two options I can think of: partition your vector, but I’m not sure this would really work (no idea how to remove loaded code again). Or use a file-system on part of the flash and load the data from there. I haven’t done that with C++, but it must be possible since MicroPython/CircuitPython do that (and the python-interpreter is nothing but C-code).