espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.52k stars 7.39k forks source link

PS_malloc Functions Not Activated Despite External SPIRAM Enabled in Menuconfig for ESP32-S3 #9038

Closed Abhay-2412 closed 1 month ago

Abhay-2412 commented 10 months ago

hello there some thing wrong with functions in esp32-hal-psram.c it was going to else part of the function when i comment else part of function then everything is working fine

#include "esp32-hal.h"

// #if CONFIG_SPIRAM_SUPPORT
#include "esp_spiram.h"
#include "soc/efuse_reg.h"
#include "esp_heap_caps.h"

static volatile bool spiramDetected = false;
static volatile bool spiramFailed = false;

bool psramInit(){
    if (spiramDetected) {
        return true;
    }
#ifndef CONFIG_SPIRAM_BOOT_INIT
    if (spiramFailed) {
        return false;
    }
    uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
    uint32_t pkg_ver = chip_ver & 0x7;
    if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
        spiramFailed = true;
        log_w("PSRAM not supported!");
        return false;
    }
    esp_spiram_init_cache();
    if (esp_spiram_init() != ESP_OK) {
        spiramFailed = true;
        log_w("PSRAM init failed!");
        pinMatrixOutDetach(16, false, false);
        pinMatrixOutDetach(17, false, false);
        return false;
    }
    if (!esp_spiram_test()) {
        spiramFailed = true;
        log_e("PSRAM test failed!");
        return false;
    }
    if (esp_spiram_add_to_heapalloc() != ESP_OK) {
        spiramFailed = true;
        log_e("PSRAM could not be added to the heap!");
        return false;
    }
#endif
    spiramDetected = true;
    log_d("PSRAM enabled");
    return true;
}

bool IRAM_ATTR psramFound(){
    return spiramDetected;
}

void IRAM_ATTR *ps_malloc(size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

void IRAM_ATTR *ps_calloc(size_t n, size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

void IRAM_ATTR *ps_realloc(void *ptr, size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_realloc(ptr, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

// #else

// bool psramInit(){
//     return false;
// }

// bool IRAM_ATTR psramFound(){
//     return false;
// }

// void IRAM_ATTR *ps_malloc(size_t size){
//     return NULL;
// }

// void IRAM_ATTR *ps_calloc(size_t n, size_t size){
//     return NULL;
// }

// void IRAM_ATTR *ps_realloc(void *ptr, size_t size){
//     return NULL;
// }

// #endif

as you can see below i activated external spiram support

image image

Originally posted by @Abhay-2412 in https://github.com/espressif/arduino-esp32/issues/9023#issuecomment-1867568224

lbernstone commented 10 months ago

You should use the code that matches your version. https://github.com/espressif/arduino-esp32/blob/2.0.6/cores/esp32/esp32-hal-psram.c

Abhay-2412 commented 10 months ago

hello @lbernstone i tried your suggestion it worked for 2.0.6 due to some circumstances i need to use 2.0.13 instead of 2.0.6 and this time i use code that matches my version am getting same crash and it is working fine when i comment else part

// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "esp32-hal.h"

// #if CONFIG_SPIRAM_SUPPORT || CONFIG_SPIRAM
#include "soc/efuse_reg.h"
#include "esp_heap_caps.h"

#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/spiram.h"
#include "esp32s2/rom/cache.h"
#elif CONFIG_IDF_TARGET_ESP32S3
#include "esp32s3/spiram.h"
#include "esp32s3/rom/cache.h"
#else 
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "esp_spiram.h"
#endif

static volatile bool spiramDetected = false;
static volatile bool spiramFailed = false;

//allows user to bypass SPI RAM test routine
__attribute__((weak)) bool testSPIRAM(void) 
{ 
     return esp_spiram_test(); 
}

bool psramInit(){
    if (spiramDetected) {
        return true;
    }
#ifndef CONFIG_SPIRAM_BOOT_INIT
    if (spiramFailed) {
        return false;
    }
#if CONFIG_IDF_TARGET_ESP32
    uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
    uint32_t pkg_ver = chip_ver & 0x7;
    if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
        spiramFailed = true;
        log_w("PSRAM not supported!");
        return false;
    }
#elif CONFIG_IDF_TARGET_ESP32S2
    extern void esp_config_data_cache_mode(void);
    esp_config_data_cache_mode();
    Cache_Enable_DCache(0);
#endif
    if (esp_spiram_init() != ESP_OK) {
        spiramFailed = true;
        log_w("PSRAM init failed!");
#if CONFIG_IDF_TARGET_ESP32
        if (pkg_ver != EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
            pinMatrixOutDetach(16, false, false);
            pinMatrixOutDetach(17, false, false);
        }
#endif
        return false;
    }
    esp_spiram_init_cache();
    //testSPIRAM() allows user to bypass SPI RAM test routine
    if (!testSPIRAM()) {
        spiramFailed = true;
        log_e("PSRAM test failed!");
        return false;
    }
    if (esp_spiram_add_to_heapalloc() != ESP_OK) {
        spiramFailed = true;
        log_e("PSRAM could not be added to the heap!");
        return false;
    }
#if CONFIG_SPIRAM_USE_MALLOC && !CONFIG_ARDUINO_ISR_IRAM
    heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
#endif
#endif /* CONFIG_SPIRAM_BOOT_INIT */
    log_i("PSRAM enabled");
    spiramDetected = true;
    return true;
}

bool ARDUINO_ISR_ATTR psramFound(){
    return spiramDetected;
}

void ARDUINO_ISR_ATTR *ps_malloc(size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

void ARDUINO_ISR_ATTR *ps_calloc(size_t n, size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

void ARDUINO_ISR_ATTR *ps_realloc(void *ptr, size_t size){
    if(!spiramDetected){
        return NULL;
    }
    return heap_caps_realloc(ptr, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}

// #else

// bool psramInit(){
//     return false;
// }

// bool ARDUINO_ISR_ATTR psramFound(){
//     return false;
// }

// void ARDUINO_ISR_ATTR *ps_malloc(size_t size){
//     return NULL;
// }

// void ARDUINO_ISR_ATTR *ps_calloc(size_t n, size_t size){
//     return NULL;
// }

// void ARDUINO_ISR_ATTR *ps_realloc(void *ptr, size_t size){
//     return NULL;
// }

// #endif
lbernstone commented 10 months ago

Why are you remarking the very first #if? That is intended to turn the whole thing off if you don't have SPIRAM enabled in your sdkconfig. If you are having trouble keeping track of what #end goes with what #if remark it so you can see the matches.

Abhay-2412 commented 10 months ago

Why are you remarking the very first #if? That is intended to turn the whole thing off if you don't have SPIRAM enabled in your sdkconfig. If you are having trouble keeping track of what #end goes with what #if remark it so you can see the matches.

but i enabled external SPIRAM support in sdkconfig then it should intended to work but still it turning whole thing off so i forcibly turning it on

Jason2866 commented 9 months ago

Do you really have Octal PSRAM? When using Arduino framework, PSRAM does work for QIO and OPI RAM. So probably you have not all needed sdkconfig settings done.

lbernstone commented 9 months ago

If you hit slash in menuconfig, you can search for spiram. You will see there is an entry there for SPIRAM which is completely separate from esp32s3 specific options.

TD-er commented 9 months ago

As already suggested by @Jason2866 Please double check your required SPI settings for PSRAM. See also my overview here: https://espeasy.readthedocs.io/en/latest/ESPEasy/ESPchips.html#quad-octal-spi-mode

Espressif really made a mess of the SPI settings for the S3.

Abhay-2412 commented 9 months ago

Do you really have Octal PSRAM? When using Arduino framework, PSRAM does work for QIO and OPI RAM. So probably you have not all needed sdkconfig settings done.

yes my board has octal spiram according to here and bekow is my menuconfig settings image

Abhay-2412 commented 9 months ago

As already suggested by @Jason2866 Please double check your required SPI settings for PSRAM. See also my overview here: https://espeasy.readthedocs.io/en/latest/ESPEasy/ESPchips.html#quad-octal-spi-mode

Espressif really made a mess of the SPI settings for the S3.

image

i beleived i configured spiram properlly

Abhay-2412 commented 9 months ago

image eventhough if condition is satisfied why if part of code isn't activated yet?

Jason2866 commented 9 months ago

Since the VSC active code scanner is not always working correctly. You can't rely on.

VojtechBartoska commented 1 month ago

Hello, it looks this issue was already answered. I am closing the ticket, if needed, you can reopen it. Thanks.

cjdell commented 2 days ago

I've spend the last day trying to figure out why my PSRAM stopped working as soon as I started using the arduino-esp32 component. This code literally undefines the CONFIG_SPIRAM and CONFIG_SPIRAM_SUPPORT flag out of existence:

https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-psram.h#L29

There is no way to override them back. I even tried defining BOARD_HAS_PSRAM as a build flag but it hasn't worked. I haven't found docs on how to set global builds flags nor is there any information on the BOARD_HAS_PSRAM flag and any explanation as to why it exists when we already have flags in sdkconfig for those.

Manually removing lines 24-31 in esp32-hal-psram.h will get PSRAM working again but this is an uncomfortable workaround.

I am enjoying using the ESP-IDF from VSCode over the Arduino IDE but these little bugs do result in a lot of time lost.

Thanks