diff --git a/scripts/check_config_web_stack_usage.sh b/scripts/check_config_web_stack_usage.sh new file mode 100755 index 0000000..896b630 --- /dev/null +++ b/scripts/check_config_web_stack_usage.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd "$(dirname "$0")/.." + +if rg -n '^[[:space:]]+StaticJsonDocument[[:space:]]+[A-Za-z_][A-Za-z0-9_]*;' src/Config_Web.cpp; then + echo "Config_Web.cpp still allocates kConfigJsonCapacity-sized StaticJsonDocument on the stack" >&2 + exit 1 +fi + +echo "Config_Web.cpp avoids stack-local kConfigJsonCapacity StaticJsonDocument allocations" diff --git a/src/Config_Web.cpp b/src/Config_Web.cpp index 6b1f7b1..181cb38 100644 --- a/src/Config_Web.cpp +++ b/src/Config_Web.cpp @@ -9,6 +9,7 @@ namespace const size_t kConfigJsonCapacity = 4096; const byte kDnsPort = 53; const unsigned long kWifiReconnectIntervalMs = 10000; + using ConfigJsonDocument = StaticJsonDocument; WebServer server(80); DNSServer dnsServer; @@ -17,6 +18,14 @@ namespace bool staReconnectEnabled = false; bool staConnectionKnown = false; unsigned long lastStaReconnectAttemptMs = 0; + ConfigJsonDocument g_configJsonScratch; + + ConfigJsonDocument &configJsonScratch() + { + // Keep the large config JSON buffer off ESP32 Arduino's 8 KB loopTask stack. + g_configJsonScratch.clear(); + return g_configJsonScratch; + } void redirectToRoot() { @@ -371,7 +380,7 @@ bool loadConfigFromFile() return saveConfigToFile(); } - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); DeserializationError err = deserializeJson(doc, file); file.close(); if (err) @@ -424,7 +433,7 @@ bool saveConfigToFile() return false; } - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); JsonArray params = doc.createNestedArray("parameters"); for (size_t i = 0; i < configParameterCount; ++i) { @@ -461,7 +470,7 @@ bool saveConfigToFile() String buildConfigJson() { - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); JsonArray params = doc.createNestedArray("parameters"); for (size_t i = 0; i < configParameterCount; ++i) { @@ -497,7 +506,7 @@ String buildConfigJson() bool applyConfigJson(const String &payload, String &errorMessage) { - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); DeserializationError err = deserializeJson(doc, payload); if (err) {