1

I am troubleshooting my firmware (brand new but nearing dev completion) memory management: it runs on a custom PCB with a WROVER module.

I want to take advantage of the extra PSRAM/SPIRAM so that the PSRAM is used automatically by the libs.

But I have doubt that this is working as I expect.

Therefore I wanted to make sure the following features are actually triggered as I ask them from the platformio.ini:

  • SPIRAM is taken into account;
  • And all libs takes advantage of it.

[UPDATE]

According to the Espressif doc (https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/external-ram.html#external-ram-config-malloc), this should be the default behaviour (Provide External RAM via malloc() (default))

Here is my platformio.ini:

[env:esp32dev]
platform = espressif32
board = esp-wrover-kit
;esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = 
    adafruit/Adafruit NeoPixel@^1.10.0
    plerup/EspSoftwareSerial@^6.13.2
    lbernstone/Tone32@^1.0.0
    miwagner/ESP32CAN@^0.0.1


board_build.partitions = huge_app.csv
;no_ota.csv
extra_scripts = pre:build_script_versioning.py

build_flags = 
    -DBOARD_HAS_PSRAM
    -mfix-esp32-psram-cache-issue
    -DCONFIG_MBEDTLS_DYNAMIC_BUFFER=1
    -DCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=1
    -DCONFIG_SPIRAM_CACHE_WORKAROUND=1

And the information related to my ESP32 WROVER:

b1453|—| nano: Firmware v0.1 (build 1453) by Sdl
b1453|—| nano: -- only suited for PCB REV 3 --
b1453|—| nano: Free heap size: 212076
b1453|—| nano: Min free heap size: 206600
b1453|—| nano: Max alloc heap size: 113792
b1453|—| nano: PsRam size: 4194252
b1453|—| nano: Runing on chip:
b1453|—| nano: - model 1 (1 is ESP32)
b1453|—| nano: - rev. 1
b1453|—| nano: Chip has the following features:
b1453|—| nano: - has flash. 0
b1453|—| nano: - has 2.4GHz. 1
b1453|—| nano: - has BLE. 1
b1453|—| nano: - has BT classic. 1

[UPDATE]

As you can see in my platformIo ini file, I use the following flags:

  • -mfix-esp32-psram-cache-issue: passed to gcc is similar to CONFIG_SPIRAM_CACHE_WORKAROUND=1;
  • -DCONFIG_MBEDTLS_DYNAMIC_BUFFER=1: this should tell mbedTLS to allocate the buffer with a malloc, hence use my PSRAM;
  • -DCONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=1: this should let the Bluetooth to use the PSRAM for its own allocations;
  • -DCONFIG_SPIRAM_CACHE_WORKAROUND=1: and this is similar to the first point (so probably is redundant with -mfix-esp32-psram-cache-issue);
  1. How can I make sure that each and every above flag is taken into account.
  2. Additionnally, for example, how can I make sure that the iot module actually allocate the TLS from the PSRAM?

Is there any code I can run from my firmware?

And any tips on PSRAM usage is VERY WELCOME.

Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95

1 Answers1

2

According to the Espressif documentation, there are four ways to use the PSRAM. If you want to use PSRAM explicitly to store something, you need to use ps_malloc() to allocate the memory. This simple sketch will show the allocation of memory from PSRAM before, after of PSRAM memory allocation and after freeing the memory.

void setup() {
  log_d("Used PSRAM: %d", ESP.getPsramSize() - ESP.getFreePsram());  byte* psdRamBuffer = (byte*)ps_malloc(500000);
  log_d("Used PSRAM: %d", ESP.getPsramSize() - ESP.getFreePsram());
  free(psdRamBuffer);
  log_d("Used PSRAM: %d", ESP.getPsramSize() - ESP.getFreePsram());
}

Please noted that there is a threshold when a single allocation should prefer external memory, when allocating a size less than the threshold, the allocator will try internal memory first. Read the documentation for more details.

hcheung
  • 3,377
  • 3
  • 11
  • 23
  • Thanks for your help. Maybe I wasn’t clear enough (I made it clearer in the question), but from the modes your refer to, I want to use the implicit allocation one so that external libs make use of the spiram. – Stéphane de Luca Feb 13 '22 at 19:35
  • Do you think that the platformio.ini flags I set are OK and taken into account when I compile? – Stéphane de Luca Feb 13 '22 at 19:36
  • I see that the ps_malloc() works as expected: Before PSRAM allocation, used PSRAM: 0, After PSRAM allocation, used PSRAM: 500000,After PSRAM block freed, used PSRAM: 0 – Stéphane de Luca Feb 14 '22 at 13:33