From befeb55349d512aaca71cda0958ce60b547a7e96 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 27 Feb 2021 00:57:12 +0100 Subject: [PATCH] Memory check on bus creation --- wled00/FX_fcn.cpp | 1 + wled00/bus_manager.h | 24 +++++++++++++++++++++++- wled00/cfg.cpp | 6 ++++-- wled00/const.h | 10 ++++++++-- wled00/wled.cpp | 4 +++- wled00/xml.cpp | 4 ---- 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index aa1f88a6..75157d7d 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -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; diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index e767fcc7..51965150 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -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++) { diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 2175c97b..ee8482c0 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -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); diff --git a/wled00/const.h b/wled00/const.h index 1f18d5cc..34eb650b 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -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 diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 651f484e..94a34fa1 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -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); diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 99b8b241..8e987d3c 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -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);