Memory check on bus creation

This commit is contained in:
cschwinne 2021-02-27 00:57:12 +01:00
parent 746a8badac
commit befeb55349
6 changed files with 39 additions and 10 deletions

View File

@ -70,6 +70,7 @@ void WS2812FX::finalizeInit(bool supportWhite, uint16_t countPixels, bool skipFi
deserializeMap();
//make segment 0 cover the entire strip
_segments[0].start = 0;
_segments[0].stop = _length;

View File

@ -297,6 +297,29 @@ class BusManager {
BusManager() {
};
//utility to get the approx. memory usage of a given BusConfig
uint32_t memUsage(BusConfig &bc) {
uint8_t type = bc.type;
uint16_t len = bc.count;
if (type < 32) {
#ifdef ESP8266
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
if (type > 29) return len*20; //RGBW
return len*15;
}
if (type > 29) return len*4; //RGBW
return len*3;
#else //ESP32 RMT uses double buffer?
if (type > 29) return len*8; //RGBW
return len*6;
#endif
}
if (type > 31 && type < 48) return 5;
if (type == 44 || type == 45) return len*4; //RGBW
return len*3;
}
int add(BusConfig &bc) {
if (numBusses >= WLED_MAX_BUSSES) return -1;
@ -317,7 +340,6 @@ class BusManager {
for (uint8_t i = 0; i < numBusses; i++) delete busses[i];
numBusses = 0;
}
//void remove(uint8_t id);
void show() {
for (uint8_t i = 0; i < numBusses; i++) {

View File

@ -99,9 +99,10 @@ void deserializeConfig() {
CJSON(strip.rgbwMode, hw_led[F("rgbwm")]);
JsonArray ins = hw_led["ins"];
uint8_t s = 0;
uint8_t s = 0; //bus iterator
useRGBW = false;
busses.removeAll();
uint32_t mem = 0;
for (JsonObject elm : ins) {
if (s >= WLED_MAX_BUSSES) break;
uint8_t pins[5] = {255, 255, 255, 255, 255};
@ -130,7 +131,8 @@ void deserializeConfig() {
useRGBW = (useRGBW || BusManager::isRgbw(ledType));
s++;
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed);
busses.add(bc);
mem += busses.memUsage(bc);
if (mem <= MAX_LED_MEMORY) busses.add(bc);
}
strip.finalizeInit(useRGBW, ledCount, skipFirstLed);

View File

@ -188,13 +188,19 @@
// maximum number of LEDs - more than 1500 LEDs (or 500 DMA "LEDPIN 3" driven ones) will cause a low memory condition on ESP8266
#ifndef MAX_LEDS
#ifdef ESP8266
#define MAX_LEDS 1536
#define MAX_LEDS 2048
#else
#define MAX_LEDS 8192
#endif
#endif
#define MAX_LEDS_DMA 500
#ifndef MAX_LED_MEMORY
#ifdef ESP8266
#define MAX_LED_MEMORY 5000
#else
#define MAX_LED_MEMORY 64000
#endif
#endif
// string temp buffer (now stored in stack locally)
#define OMAX 2048

View File

@ -218,9 +218,11 @@ void WLED::loop()
//LED settings have been saved, re-init busses
if (busConfigs[0] != nullptr) {
busses.removeAll();
uint32_t mem = 0;
for (uint8_t i = 0; i < WLED_MAX_BUSSES; i++) {
if (busConfigs[i] == nullptr) break;
busses.add(*busConfigs[i]);
mem += busses.memUsage(*busConfigs[i]);
if (mem <= MAX_LED_MEMORY) busses.add(*busConfigs[i]);
delete busConfigs[i]; busConfigs[i] = nullptr;
}
strip.finalizeInit(useRGBW, ledCount, skipFirstLed);

View File

@ -279,11 +279,7 @@ void getSettingsJS(byte subPage, char* dest)
#endif
oappend(SET_F("d.Sf.LC.max=")); //TODO Formula for max LEDs on ESP8266 depending on types. 500 DMA or 1500 UART (about 4kB mem usage)
#if defined(ESP8266) && LEDPIN == 3
oappendi(MAX_LEDS_DMA);
#else
oappendi(MAX_LEDS);
#endif
oappend(";");
sappend('v',SET_F("LC"),ledCount);