Skip to content

Commit 97f68b3

Browse files
committed
Merge branch 'main' into fix_UIandBusMemory
2 parents db310c6 + 76cb2e9 commit 97f68b3

File tree

15 files changed

+353
-211
lines changed

15 files changed

+353
-211
lines changed

usermods/audioreactive/audio_reactive.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ void FFTcode(void * parameter)
224224
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
225225

226226
// allocate FFT buffers on first call
227-
if (vReal == nullptr) vReal = (float*) calloc(sizeof(float), samplesFFT);
228-
if (vImag == nullptr) vImag = (float*) calloc(sizeof(float), samplesFFT);
227+
if (vReal == nullptr) vReal = (float*) calloc(samplesFFT, sizeof(float));
228+
if (vImag == nullptr) vImag = (float*) calloc(samplesFFT, sizeof(float));
229229
if ((vReal == nullptr) || (vImag == nullptr)) {
230230
// something went wrong
231231
if (vReal) free(vReal); vReal = nullptr;

wled00/FX.h

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,26 @@ extern byte realtimeMode; // used in getMappedPixelIndex()
8888
#endif
8989
#define FPS_CALC_SHIFT 7 // bit shift for fixed point math
9090

91-
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
92-
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
91+
// heap memory limit for effects data, pixel buffers try to reserve it if PSRAM is available
9392
#ifdef ESP8266
9493
#define MAX_NUM_SEGMENTS 16
9594
/* How much data bytes all segments combined may allocate */
96-
#define MAX_SEGMENT_DATA 5120
95+
#define MAX_SEGMENT_DATA (6*1024) // 6k by default
9796
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
98-
#define MAX_NUM_SEGMENTS 20
99-
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*512) // 10k by default (S2 is short on free RAM)
97+
#define MAX_NUM_SEGMENTS 32
98+
#define MAX_SEGMENT_DATA (20*1024) // 20k by default (S2 is short on free RAM), limit does not apply if PSRAM is available
10099
#else
101-
#define MAX_NUM_SEGMENTS 32 // warning: going beyond 32 may consume too much RAM for stable operation
102-
#define MAX_SEGMENT_DATA (MAX_NUM_SEGMENTS*1280) // 40k by default
100+
#ifdef BOARD_HAS_PSRAM
101+
#define MAX_NUM_SEGMENTS 64
102+
#else
103+
#define MAX_NUM_SEGMENTS 32
104+
#endif
105+
#define MAX_SEGMENT_DATA (64*1024) // 64k by default, limit does not apply if PSRAM is available
103106
#endif
104107

105108
/* How much data bytes each segment should max allocate to leave enough space for other segments,
106109
assuming each segment uses the same amount of data. 256 for ESP8266, 640 for ESP32. */
107-
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / WS2812FX::getMaxSegments())
110+
#define FAIR_DATA_PER_SEG (MAX_SEGMENT_DATA / MAX_NUM_SEGMENTS)
108111

109112
#define MIN_SHOW_DELAY (_frametime < 16 ? 8 : 15)
110113

@@ -533,7 +536,6 @@ class Segment {
533536

534537
protected:
535538

536-
inline static unsigned getUsedSegmentData() { return Segment::_usedSegmentData; }
537539
inline static void addUsedSegmentData(int len) { Segment::_usedSegmentData += len; }
538540

539541
inline uint32_t *getPixels() const { return pixels; }
@@ -600,8 +602,8 @@ class Segment {
600602
, _t(nullptr)
601603
{
602604
DEBUGFX_PRINTF_P(PSTR("-- Creating segment: %p [%d,%d:%d,%d]\n"), this, (int)start, (int)stop, (int)startY, (int)stopY);
603-
// allocate render buffer (always entire segment)
604-
pixels = static_cast<uint32_t*>(d_calloc(sizeof(uint32_t), length())); // error handling is also done in isActive()
605+
// allocate render buffer (always entire segment), prefer PSRAM if DRAM is running low. Note: impact on FPS with PSRAM buffer is low (<2% with QSPI PSRAM)
606+
pixels = static_cast<uint32_t*>(allocate_buffer(length() * sizeof(uint32_t), BFRALLOC_PREFER_PSRAM | BFRALLOC_NOBYTEACCESS | BFRALLOC_CLEAR));
605607
if (!pixels) {
606608
DEBUGFX_PRINTLN(F("!!! Not enough RAM for pixel buffer !!!"));
607609
extern byte errorFlag;
@@ -623,7 +625,7 @@ class Segment {
623625
#endif
624626
clearName();
625627
deallocateData();
626-
d_free(pixels);
628+
p_free(pixels);
627629
}
628630

629631
Segment& operator= (const Segment &orig); // copy assignment
@@ -646,7 +648,7 @@ class Segment {
646648
inline uint16_t groupLength() const { return grouping + spacing; }
647649
inline uint8_t getLightCapabilities() const { return _capabilities; }
648650
inline void deactivate() { setGeometry(0,0); }
649-
inline Segment &clearName() { d_free(name); name = nullptr; return *this; }
651+
inline Segment &clearName() { p_free(name); name = nullptr; return *this; }
650652
inline Segment &setName(const String &name) { return setName(name.c_str()); }
651653

652654
inline static unsigned vLength() { return Segment::_vLength; }
@@ -672,6 +674,7 @@ class Segment {
672674
inline uint16_t dataSize() const { return _dataLen; }
673675
bool allocateData(size_t len); // allocates effect data buffer in heap and clears it
674676
void deallocateData(); // deallocates (frees) effect data buffer from heap
677+
inline static unsigned getUsedSegmentData() { return Segment::_usedSegmentData; }
675678
/**
676679
* Flags that before the next effect is calculated,
677680
* the internal segment state should be reset.
@@ -868,8 +871,8 @@ class WS2812FX {
868871
}
869872

870873
~WS2812FX() {
871-
d_free(_pixels);
872-
d_free(_pixelCCT); // just in case
874+
p_free(_pixels);
875+
p_free(_pixelCCT); // just in case
873876
d_free(customMappingTable);
874877
_mode.clear();
875878
_modeData.clear();

wled00/FX_fcn.cpp

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ Segment::Segment(const Segment &orig) {
6868
if (!stop) return; // nothing to do if segment is inactive/invalid
6969
if (orig.pixels) {
7070
// allocate pixel buffer: prefer IRAM/PSRAM
71-
pixels = static_cast<uint32_t*>(d_malloc(sizeof(uint32_t) * orig.length()));
71+
pixels = static_cast<uint32_t*>(allocate_buffer(orig.length() * sizeof(uint32_t), BFRALLOC_PREFER_PSRAM | BFRALLOC_NOBYTEACCESS));
7272
if (pixels) {
7373
memcpy(pixels, orig.pixels, sizeof(uint32_t) * orig.length());
74-
if (orig.name) { name = static_cast<char*>(d_malloc(strlen(orig.name)+1)); if (name) strcpy(name, orig.name); }
74+
if (orig.name) { name = static_cast<char*>(allocate_buffer(strlen(orig.name)+1, BFRALLOC_PREFER_PSRAM)); if (name) strcpy(name, orig.name); }
7575
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
7676
} else {
7777
DEBUGFX_PRINTLN(F("!!! Not enough RAM for pixel buffer !!!"));
@@ -97,10 +97,10 @@ Segment& Segment::operator= (const Segment &orig) {
9797
//DEBUG_PRINTF_P(PSTR("-- Copying segment: %p -> %p\n"), &orig, this);
9898
if (this != &orig) {
9999
// clean destination
100-
if (name) { d_free(name); name = nullptr; }
100+
if (name) { p_free(name); name = nullptr; }
101101
if (_t) stopTransition(); // also erases _t
102102
deallocateData();
103-
d_free(pixels);
103+
p_free(pixels);
104104
// copy source
105105
memcpy((void*)this, (void*)&orig, sizeof(Segment));
106106
// erase pointers to allocated data
@@ -111,10 +111,10 @@ Segment& Segment::operator= (const Segment &orig) {
111111
// copy source data
112112
if (orig.pixels) {
113113
// allocate pixel buffer: prefer IRAM/PSRAM
114-
pixels = static_cast<uint32_t*>(d_malloc(sizeof(uint32_t) * orig.length()));
114+
pixels = static_cast<uint32_t*>(allocate_buffer(orig.length() * sizeof(uint32_t), BFRALLOC_PREFER_PSRAM | BFRALLOC_NOBYTEACCESS));
115115
if (pixels) {
116116
memcpy(pixels, orig.pixels, sizeof(uint32_t) * orig.length());
117-
if (orig.name) { name = static_cast<char*>(d_malloc(strlen(orig.name)+1)); if (name) strcpy(name, orig.name); }
117+
if (orig.name) { name = static_cast<char*>(allocate_buffer(strlen(orig.name)+1, BFRALLOC_PREFER_PSRAM)); if (name) strcpy(name, orig.name); }
118118
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
119119
} else {
120120
DEBUG_PRINTLN(F("!!! Not enough RAM for pixel buffer !!!"));
@@ -130,10 +130,10 @@ Segment& Segment::operator= (const Segment &orig) {
130130
Segment& Segment::operator= (Segment &&orig) noexcept {
131131
//DEBUG_PRINTF_P(PSTR("-- Moving segment: %p -> %p\n"), &orig, this);
132132
if (this != &orig) {
133-
if (name) { d_free(name); name = nullptr; } // free old name
133+
if (name) { p_free(name); name = nullptr; } // free old name
134134
if (_t) stopTransition(); // also erases _t
135135
deallocateData(); // free old runtime data
136-
d_free(pixels); // free old pixel buffer
136+
p_free(pixels); // free old pixel buffer
137137
// move source data
138138
memcpy((void*)this, (void*)&orig, sizeof(Segment));
139139
orig.name = nullptr;
@@ -147,35 +147,38 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
147147

148148
// allocates effect data buffer on heap and initialises (erases) it
149149
bool Segment::allocateData(size_t len) {
150-
if (len == 0) return false; // nothing to do
151-
if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
150+
if (len == 0) return false; // nothing to do
151+
if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
152152
if (call == 0) {
153-
//DEBUG_PRINTF_P(PSTR("-- Clearing data (%d): %p\n"), len, this);
154-
memset(data, 0, len); // erase buffer if called during effect initialisation
153+
if (_dataLen < FAIR_DATA_PER_SEG) { // segment data is small
154+
//DEBUG_PRINTF_P(PSTR("-- Clearing data (%d): %p\n"), len, this);
155+
memset(data, 0, len); // erase buffer if called during effect initialisation
156+
return true; // no need to reallocate
157+
}
155158
}
156-
return true;
159+
else
160+
return true;
157161
}
158162
//DEBUG_PRINTF_P(PSTR("-- Allocating data (%d): %p\n"), len, this);
163+
// limit to MAX_SEGMENT_DATA if there is no PSRAM, otherwise prefer functionality over speed
164+
#ifndef BOARD_HAS_PSRAM
159165
if (Segment::getUsedSegmentData() + len - _dataLen > MAX_SEGMENT_DATA) {
160166
// not enough memory
161-
DEBUG_PRINTF_P(PSTR("!!! Not enough RAM: %d/%d !!!\n"), len, Segment::getUsedSegmentData());
167+
DEBUG_PRINTF_P(PSTR("SegmentData limit reached: %d/%d\n"), len, Segment::getUsedSegmentData());
162168
errorFlag = ERR_NORAM;
163169
return false;
164170
}
165-
// prefer DRAM over SPI RAM on ESP32 since it is slow
171+
#endif
172+
166173
if (data) {
167-
data = (byte*)d_realloc_malloc(data, len); // realloc with malloc fallback
168-
if (!data) {
169-
data = nullptr;
170-
Segment::addUsedSegmentData(-_dataLen); // subtract original buffer size
171-
_dataLen = 0; // reset data length
172-
}
174+
d_free(data); // free data and try to allocate again (segment buffer may be blocking contiguous heap)
175+
Segment::addUsedSegmentData(-_dataLen); // subtract buffer size
173176
}
174-
else data = (byte*)d_malloc(len);
177+
178+
data = static_cast<byte*>(allocate_buffer(len, BFRALLOC_PREFER_DRAM | BFRALLOC_CLEAR)); // prefer DRAM over PSRAM for speed
175179

176180
if (data) {
177-
memset(data, 0, len); // erase buffer
178-
Segment::addUsedSegmentData(len - _dataLen);
181+
Segment::addUsedSegmentData(len);
179182
_dataLen = len;
180183
//DEBUG_PRINTF_P(PSTR("--- Allocated data (%p): %d/%d -> %p\n"), this, len, Segment::getUsedSegmentData(), data);
181184
return true;
@@ -209,7 +212,11 @@ void Segment::deallocateData() {
209212
void Segment::resetIfRequired() {
210213
if (!reset || !isActive()) return;
211214
//DEBUG_PRINTF_P(PSTR("-- Segment reset: %p\n"), this);
212-
if (data && _dataLen > 0) memset(data, 0, _dataLen); // prevent heap fragmentation (just erase buffer instead of deallocateData())
215+
if (data && _dataLen > 0) {
216+
if (_dataLen > FAIR_DATA_PER_SEG) deallocateData(); // do not keep large allocations
217+
else memset(data, 0, _dataLen); // can prevent heap fragmentation
218+
DEBUG_PRINTF_P(PSTR("-- Segment %p reset, data cleared\n"), this);
219+
}
213220
if (pixels) for (size_t i = 0; i < length(); i++) pixels[i] = BLACK; // clear pixel buffer
214221
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
215222
reset = false;
@@ -466,7 +473,7 @@ void Segment::setGeometry(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, ui
466473
if (length() != oldLength) {
467474
// allocate render buffer (always entire segment), prefer IRAM/PSRAM. Note: impact on FPS with PSRAM buffer is low (<2% with QSPI PSRAM) on S2/S3
468475
p_free(pixels);
469-
pixels = static_cast<uint32_t*>(d_malloc(sizeof(uint32_t) * length()));
476+
pixels = static_cast<uint32_t*>(allocate_buffer(length() * sizeof(uint32_t), BFRALLOC_PREFER_PSRAM | BFRALLOC_NOBYTEACCESS));
470477
if (!pixels) {
471478
DEBUGFX_PRINTLN(F("!!! Not enough RAM for pixel buffer !!!"));
472479
deallocateData();
@@ -581,8 +588,8 @@ Segment &Segment::setName(const char *newName) {
581588
if (newName) {
582589
const int newLen = min(strlen(newName), (size_t)WLED_MAX_SEGNAME_LEN);
583590
if (newLen) {
584-
if (name) d_free(name); // free old name
585-
name = static_cast<char*>(d_malloc(newLen+1));
591+
if (name) p_free(name); // free old name
592+
name = static_cast<char*>(allocate_buffer(newLen+1, BFRALLOC_PREFER_PSRAM));
586593
if (mode == FX_MODE_2DSCROLLTEXT) startTransition(strip.getTransition(), true); // if the name changes in scrolling text mode, we need to copy the segment for blending
587594
if (name) strlcpy(name, newName, newLen+1);
588595
return *this;
@@ -1215,10 +1222,11 @@ void WS2812FX::finalizeInit() {
12151222
deserializeMap(); // (re)load default ledmap (will also setUpMatrix() if ledmap does not exist)
12161223

12171224
// allocate frame buffer after matrix has been set up (gaps!)
1218-
d_free(_pixels); // using realloc on large buffers can cause additional fragmentation instead of reducing it
1219-
_pixels = static_cast<uint32_t*>(d_malloc(getLengthTotal() * sizeof(uint32_t)));
1225+
p_free(_pixels); // using realloc on large buffers can cause additional fragmentation instead of reducing it
1226+
// use PSRAM if available: there is no measurable perfomance impact between PSRAM and DRAM on S2/S3 with QSPI PSRAM for this buffer
1227+
_pixels = static_cast<uint32_t*>(allocate_buffer(getLengthTotal() * sizeof(uint32_t), BFRALLOC_ENFORCE_PSRAM | BFRALLOC_NOBYTEACCESS | BFRALLOC_CLEAR));
12201228
DEBUG_PRINTF_P(PSTR("strip buffer size: %uB\n"), getLengthTotal() * sizeof(uint32_t));
1221-
DEBUG_PRINTF_P(PSTR("Heap after strip init: %uB\n"), ESP.getFreeHeap());
1229+
DEBUG_PRINTF_P(PSTR("Heap after strip init: %uB\n"), getFreeHeapSize());
12221230
}
12231231

12241232
void WS2812FX::service() {
@@ -1558,7 +1566,11 @@ void WS2812FX::blendSegment(const Segment &topSegment) const {
15581566
}
15591567

15601568
void WS2812FX::show() {
1561-
if (!_pixels) return; // no pixels allocated, nothing to show
1569+
if (!_pixels) {
1570+
DEBUGFX_PRINTLN(F("Error: no _pixels!"));
1571+
errorFlag = ERR_NORAM;
1572+
return; // no pixels allocated, nothing to show
1573+
}
15621574

15631575
unsigned long showNow = millis();
15641576
size_t diff = showNow - _lastShow;
@@ -1568,7 +1580,7 @@ void WS2812FX::show() {
15681580
// we need to keep track of each pixel's CCT when blending segments (if CCT is present)
15691581
// and then set appropriate CCT from that pixel during paint (see below).
15701582
if ((hasCCTBus() || correctWB) && !cctFromRgb)
1571-
_pixelCCT = static_cast<uint8_t*>(d_malloc(totalLen * sizeof(uint8_t))); // allocate CCT buffer if necessary
1583+
_pixelCCT = static_cast<uint8_t*>(allocate_buffer(totalLen * sizeof(uint8_t), BFRALLOC_PREFER_PSRAM)); // allocate CCT buffer if necessary, prefer PSRAM
15721584
if (_pixelCCT) memset(_pixelCCT, 127, totalLen); // set neutral (50:50) CCT
15731585

15741586
if (realtimeMode == REALTIME_MODE_INACTIVE || useMainSegmentOnly || realtimeOverride > REALTIME_OVERRIDE_NONE) {
@@ -1602,7 +1614,7 @@ void WS2812FX::show() {
16021614
}
16031615
Bus::setCCT(oldCCT); // restore old CCT for ABL adjustments
16041616

1605-
d_free(_pixelCCT);
1617+
p_free(_pixelCCT);
16061618
_pixelCCT = nullptr;
16071619

16081620
// some buses send asynchronously and this method will return before

wled00/bus_manager.cpp

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,29 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
3939
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, const byte *buffer, uint8_t bri=255, bool isRGBW=false);
4040

4141
//util.cpp
42-
// PSRAM allocation wrappers
43-
#if !defined(ESP8266) && !defined(CONFIG_IDF_TARGET_ESP32C3)
42+
// memory allocation wrappers
4443
extern "C" {
45-
void *p_malloc(size_t); // prefer PSRAM over DRAM
46-
void *p_calloc(size_t, size_t); // prefer PSRAM over DRAM
47-
void *p_realloc(void *, size_t); // prefer PSRAM over DRAM
48-
void *p_realloc_malloc(void *ptr, size_t size); // realloc with malloc fallback, prefer PSRAM over DRAM
49-
inline void p_free(void *ptr) { heap_caps_free(ptr); }
50-
void *d_malloc(size_t); // prefer DRAM over PSRAM
51-
void *d_calloc(size_t, size_t); // prefer DRAM over PSRAM
52-
void *d_realloc(void *, size_t); // prefer DRAM over PSRAM
53-
void *d_realloc_malloc(void *ptr, size_t size); // realloc with malloc fallback, prefer DRAM over PSRAM
44+
// prefer DRAM over PSRAM (if available) in d_ alloc functions
45+
void *d_malloc(size_t);
46+
void *d_calloc(size_t, size_t);
47+
void *d_realloc_malloc(void *ptr, size_t size);
48+
#ifndef ESP8266
5449
inline void d_free(void *ptr) { heap_caps_free(ptr); }
50+
#else
51+
inline void d_free(void *ptr) { free(ptr); }
52+
#endif
53+
#if defined(BOARD_HAS_PSRAM)
54+
// prefer PSRAM over DRAM in p_ alloc functions
55+
void *p_malloc(size_t);
56+
void *p_calloc(size_t, size_t);
57+
void *p_realloc_malloc(void *ptr, size_t size);
58+
inline void p_free(void *ptr) { heap_caps_free(ptr); }
59+
#else
60+
#define p_malloc d_malloc
61+
#define p_calloc d_calloc
62+
#define p_free d_free
63+
#endif
5564
}
56-
#else
57-
extern "C" {
58-
void *realloc_malloc(void *ptr, size_t size);
59-
}
60-
#define p_malloc malloc
61-
#define p_calloc calloc
62-
#define p_realloc realloc
63-
#define p_realloc_malloc realloc_malloc
64-
#define p_free free
65-
#define d_malloc malloc
66-
#define d_calloc calloc
67-
#define d_realloc realloc
68-
#define d_realloc_malloc realloc_malloc
69-
#define d_free free
70-
#endif
7165

7266
//color mangling macros
7367
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
@@ -902,7 +896,7 @@ void BusManager::esp32RMTInvertIdle() {
902896
else if (lvl == RMT_IDLE_LEVEL_LOW) lvl = RMT_IDLE_LEVEL_HIGH;
903897
else continue;
904898
rmt_set_idle_level(ch, idle_out, lvl);
905-
u++
899+
u++;
906900
}
907901
}
908902
#endif

wled00/cfg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
201201
}
202202
#endif
203203

204-
DEBUG_PRINTF_P(PSTR("Heap before buses: %d\n"), ESP.getFreeHeap());
204+
DEBUG_PRINTF_P(PSTR("Heap before buses: %d\n"), getFreeHeapSize());
205205
JsonArray ins = hw_led["ins"];
206206
if (!ins.isNull()) {
207207
int s = 0; // bus iterator

wled00/const.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,21 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
546546
#endif
547547
#endif
548548

549-
// minimum heap size required to process web requests
550-
#define MIN_HEAP_SIZE 8192
549+
// minimum heap size required to process web requests: try to keep free heap above this value
550+
#ifdef ESP8266
551+
#define MIN_HEAP_SIZE (9*1024)
552+
#else
553+
#define MIN_HEAP_SIZE (15*1024) // WLED allocation functions (util.cpp) try to keep this much contiguous heap free for other tasks
554+
#endif
555+
// threshold for PSRAM use: if heap is running low, requests to allocate_buffer(prefer DRAM) above PSRAM_THRESHOLD may be put in PSRAM
556+
// if heap is depleted, PSRAM will be used regardless of threshold
557+
#if defined(CONFIG_IDF_TARGET_ESP32S3)
558+
#define PSRAM_THRESHOLD (12*1024) // S3 has plenty of DRAM
559+
#elif defined(CONFIG_IDF_TARGET_ESP32)
560+
#define PSRAM_THRESHOLD (5*1024)
561+
#else
562+
#define PSRAM_THRESHOLD (2*1024) // S2 does not have a lot of RAM. C3 and ESP8266 do not support PSRAM: the value is not used
563+
#endif
551564

552565
// Web server limits
553566
#ifdef ESP8266

0 commit comments

Comments
 (0)