diff --git a/wled00/src/dependencies/json/AsyncJson-v6.h b/wled00/src/dependencies/json/AsyncJson-v6.h index 8fc01506..fefa154f 100644 --- a/wled00/src/dependencies/json/AsyncJson-v6.h +++ b/wled00/src/dependencies/json/AsyncJson-v6.h @@ -17,6 +17,8 @@ // global WLED memory functions (util.cpp) extern "C" { + // only allocate from internal DRAM, never uses PSRAM + void *d_malloc_only(size_t); // prefer DRAM in d_xalloc functions, PSRAM as fallback void *d_malloc(size_t); void *d_calloc(size_t, size_t); @@ -168,8 +170,9 @@ public: if (_onRequest) { _contentLength = total; if (total > 0 && request->_tempObject == NULL && (int)total < _maxContentLength) { + //request->_tempObject = malloc(total); //request->_tempObject = d_malloc(total); // seems to cause instabilities on classic esp32 with PSRAM - request->_tempObject = malloc(total); + request->_tempObject = d_malloc_only(total); } if (request->_tempObject != NULL) { memcpy((uint8_t*)(request->_tempObject) + index, data, len); diff --git a/wled00/util.cpp b/wled00/util.cpp index 39fee6d9..f9de20d0 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -732,6 +732,10 @@ void *d_malloc(size_t size) { return validateFreeHeap(buffer); } +void *d_malloc_only(size_t size) { + return d_malloc(size); +} + void *d_calloc(size_t count, size_t size) { void *buffer = calloc(count, size); return validateFreeHeap(buffer); @@ -802,7 +806,7 @@ static inline bool isOkForDRAMHeap(size_t amount) { size_t avail = d_measureContiguousFreeHeap(); if ((amount < avail) && (avail - amount > MIN_HEAP_SIZE)) return true; else { - DEBUG_PRINTF("* isOkForDRAMHeap() DRAM allocation rejected (%u bytes requested, %u available) !\n", amount, avail); + USER_PRINTF("* isOkForDRAMHeap() DRAM allocation rejected (%u bytes requested, %u-%u available).\n", amount, avail, MIN_HEAP_SIZE); return(false); } #else @@ -859,6 +863,17 @@ void *d_malloc(size_t size) { return buffer; } +void *d_malloc_only(size_t size) { + // variant of d_malloc that only allocates from "internal" DRAM (no PSRAM fallback) + void *buffer = nullptr; + if (isOkForDRAMHeap(size)) // no RTC RAM allocation allowed, always request DRAM + buffer = heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + + buffer = validateFreeHeap(buffer); // make sure there is enough free heap left + if (!buffer) { USER_PRINTF("* d_malloc_only() failed (%u bytes) !\n", size); } + return buffer; +} + void *d_calloc(size_t count, size_t size) { // similar to d_malloc but uses heap_caps_calloc void *buffer = nullptr; diff --git a/wled00/util.h b/wled00/util.h index 658adf3c..69564618 100644 --- a/wled00/util.h +++ b/wled00/util.h @@ -88,6 +88,8 @@ inline uint8_t hw_random8(uint32_t lowerlimit, uint32_t upperlimit) { uint32_t r // memory allocation wrappers (util.cpp) extern "C" { + // only allocate from internal DRAM, never uses PSRAM + void *d_malloc_only(size_t); // prefer DRAM in d_xalloc functions, PSRAM as fallback void *d_malloc(size_t); void *d_calloc(size_t, size_t);