From a91dd5c2a2eca73056dea52d3f9170d79583c102 Mon Sep 17 00:00:00 2001 From: Nic Limper Date: Sat, 23 Sep 2023 18:40:28 +0200 Subject: [PATCH] fix hangs on esp32-s2; refactor task runner; moved some json objects from the stack to the heap temporary, there's some extra debug info on the terminal. Will be removed again in the near future. --- ESP32_AP-Flasher/include/util.h | 21 +++++++ ESP32_AP-Flasher/include/web.h | 1 - ESP32_AP-Flasher/src/contentmanager.cpp | 16 +++-- ESP32_AP-Flasher/src/flasher.cpp | 4 +- ESP32_AP-Flasher/src/main.cpp | 79 ++++++++++++------------- ESP32_AP-Flasher/src/ota.cpp | 2 +- ESP32_AP-Flasher/src/tag_db.cpp | 4 +- ESP32_AP-Flasher/src/web.cpp | 31 ++++++---- 8 files changed, 93 insertions(+), 65 deletions(-) diff --git a/ESP32_AP-Flasher/include/util.h b/ESP32_AP-Flasher/include/util.h index 4eebe187..08b2d103 100644 --- a/ESP32_AP-Flasher/include/util.h +++ b/ESP32_AP-Flasher/include/util.h @@ -123,5 +123,26 @@ static bool isSleeping(int sleeptime1, int sleeptime2) { } } +class Timer { + public: + Timer(unsigned long interval) : interval_(interval), previousMillis_(0) {} + + void setInterval(unsigned long interval) { + interval_ = interval; + } + + bool doRun() { + unsigned long currentMillis = millis(); + if (currentMillis - previousMillis_ >= interval_) { + previousMillis_ = currentMillis; + return true; + } + return false; + } + + private: + unsigned long interval_; + unsigned long previousMillis_; +}; } // namespace util diff --git a/ESP32_AP-Flasher/include/web.h b/ESP32_AP-Flasher/include/web.h index f360a5b3..b3890378 100644 --- a/ESP32_AP-Flasher/include/web.h +++ b/ESP32_AP-Flasher/include/web.h @@ -6,7 +6,6 @@ void init_web(); void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); void doJsonUpload(AsyncWebServerRequest *request); -extern void networkProcess(void *parameter); void wsLog(String text); void wsErr(String text); void wsSendTaginfo(const uint8_t *mac, uint8_t syncMode); diff --git a/ESP32_AP-Flasher/src/contentmanager.cpp b/ESP32_AP-Flasher/src/contentmanager.cpp index 9bcc6110..e06dc97a 100644 --- a/ESP32_AP-Flasher/src/contentmanager.cpp +++ b/ESP32_AP-Flasher/src/contentmanager.cpp @@ -43,7 +43,9 @@ void contentRunner() { for (tagRecord *taginfo : tagDB) { if (taginfo->RSSI && (now >= taginfo->nextupdate || taginfo->wakeupReason == WAKEUP_REASON_GPIO || taginfo->wakeupReason == WAKEUP_REASON_NFC) && config.runStatus == RUNSTATUS_RUN && Storage.freeSpace() > 31000 && !util::isSleeping(config.sleepTime1, config.sleepTime2)) { + Serial.println("drawnew start"); drawNew(taginfo->mac, (taginfo->wakeupReason == WAKEUP_REASON_GPIO), taginfo); + Serial.println("drawnew end"); taginfo->wakeupReason = 0; } @@ -77,6 +79,7 @@ void contentRunner() { } void checkVars() { + Serial.println("checkvars begin"); DynamicJsonDocument cfgobj(500); for (tagRecord *tag : tagDB) { if (tag->contentMode == 19) { @@ -110,6 +113,7 @@ void checkVars() { for (const auto &entry : varDB) { if (entry.second.changed) varDB[entry.first].changed = false; } + Serial.println("checkvars end"); } /// @brief Draw a counter @@ -153,7 +157,7 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo taginfo->contentMode = 21; taginfo->nextupdate = 0; } else if (contentFS->exists("/tag_defaults.json")) { - StaticJsonDocument<3000> doc; + DynamicJsonDocument doc(1000); fs::File tagDefaults = contentFS->open("/tag_defaults.json", "r"); DeserializationError err = deserializeJson(doc, tagDefaults); if (!err) { @@ -408,7 +412,7 @@ void drawNew(const uint8_t mac[8], const bool buttonPressed, tagRecord *&taginfo if (!util::isEmptyOrNull(configFilename)) { String configUrl = cfgobj["url"].as(); if (!util::isEmptyOrNull(configUrl)) { - StaticJsonDocument<1000> json; + DynamicJsonDocument json(1000); Serial.println("Get json url + file"); if (util::httpGetJson(configUrl, json, 1000)) { if (getJsonTemplateFileExtractVariables(filename, configFilename, json, taginfo, imageParams)) { @@ -691,7 +695,7 @@ void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, units += "&temperature_unit=fahrenheit&windspeed_unit=mph"; } - StaticJsonDocument<1000> doc; + DynamicJsonDocument doc(1000); const bool success = util::httpGetJson("https://api.open-meteo.com/v1/forecast?latitude=" + lat + "&longitude=" + lon + "¤t_weather=true&windspeed_unit=ms&timezone=" + tz + units, doc, 5000); if (!success) { return; @@ -1139,7 +1143,7 @@ void drawAPinfo(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgPa } TFT_eSprite spr = TFT_eSprite(&tft); - StaticJsonDocument<2048> loc; + DynamicJsonDocument loc(2048); getTemplate(loc, 21, taginfo->hwType); initSprite(spr, imageParams.width, imageParams.height, imageParams); @@ -1448,7 +1452,7 @@ void getLocation(JsonObject &cfgobj) { filter["results"][0]["latitude"] = true; filter["results"][0]["longitude"] = true; filter["results"][0]["timezone"] = true; - StaticJsonDocument<1000> doc; + DynamicJsonDocument doc(1000); if (util::httpGetJson("https://geocoding-api.open-meteo.com/v1/search?name=" + urlEncode(cfgobj["location"]) + "&count=1", doc, 5000, &filter)) { cfgobj["#lat"] = doc["results"][0]["latitude"].as(); cfgobj["#lon"] = doc["results"][0]["longitude"].as(); @@ -1512,7 +1516,7 @@ void prepareConfigFile(const uint8_t *dst, const JsonObject &config) { void getTemplate(JsonDocument &json, const uint8_t id, const uint8_t hwtype) { StaticJsonDocument<80> filter; - StaticJsonDocument<2048> doc; + DynamicJsonDocument doc(2048); const String idstr = String(id); constexpr const char *templateKey = "template"; diff --git a/ESP32_AP-Flasher/src/flasher.cpp b/ESP32_AP-Flasher/src/flasher.cpp index ea17e4a9..1c99dd96 100644 --- a/ESP32_AP-Flasher/src/flasher.cpp +++ b/ESP32_AP-Flasher/src/flasher.cpp @@ -175,7 +175,7 @@ bool flasher::getInfoBlockType() { } bool flasher::findTagByMD5() { - StaticJsonDocument<3000> doc; + DynamicJsonDocument doc(3000); DynamicJsonDocument APconfig(600); fs::File readfile = contentFS->open("/tag_md5_db.json", "r"); DeserializationError err = deserializeJson(doc, readfile); @@ -205,7 +205,7 @@ bool flasher::findTagByMD5() { } bool flasher::findTagByType(uint8_t type) { - StaticJsonDocument<3000> doc; + DynamicJsonDocument doc(3000); DynamicJsonDocument APconfig(600); fs::File readfile = contentFS->open("/tag_md5_db.json", "r"); DeserializationError err = deserializeJson(doc, readfile); diff --git a/ESP32_AP-Flasher/src/main.cpp b/ESP32_AP-Flasher/src/main.cpp index cf383a60..1d33e6dd 100644 --- a/ESP32_AP-Flasher/src/main.cpp +++ b/ESP32_AP-Flasher/src/main.cpp @@ -10,6 +10,7 @@ #include "storage.h" #include "system.h" #include "tag_db.h" +#include "wifimanager.h" #ifdef HAS_USB #include "usbflasher.h" @@ -21,6 +22,13 @@ #include "util.h" #include "web.h" +util::Timer intervalSysinfo(3000); +util::Timer intervalVars(10000); +util::Timer intervalSaveDB(300000); +util::Timer intervalContentRunner(1000); + +SET_LOOP_TASK_STACK_SIZE(16 * 1024); + void pinTest(); void delayedStart(void* parameter) { @@ -33,32 +41,6 @@ void delayedStart(void* parameter) { vTaskDelete(NULL); } -void timeTask(void* parameter) { - wsSendSysteminfo(); - util::printHeap(); - while (1) { - unsigned long startMillis = millis(); - time_t now; - time(&now); - if (now % 5 == 0 || apInfo.state != AP_STATE_ONLINE || config.runStatus != RUNSTATUS_RUN) { - wsSendSysteminfo(); - } - if (now % 10 == 9 && config.runStatus != RUNSTATUS_STOP) { - checkVars(); - } - if (now % 300 == 7 && config.runStatus != RUNSTATUS_STOP) { - saveDB("/current/tagDB.json"); - } - if (apInfo.state == AP_STATE_ONLINE) { - contentRunner(); - } - - if (millis() - startMillis < 1000) { - vTaskDelay((1000 - millis() + startMillis) / portTICK_PERIOD_MS); - } - } -} - void setup() { Serial.begin(115200); Serial.print(">\n"); @@ -147,7 +129,6 @@ void setup() { loadDB("/current/tagDB.json"); cleanupCurrent(); xTaskCreate(APTask, "AP Process", 6000, NULL, 2, NULL); - xTaskCreate(networkProcess, "Wifi", 6000, NULL, configMAX_PRIORITIES - 10, NULL); vTaskDelay(10 / portTICK_PERIOD_MS); config.runStatus = RUNSTATUS_INIT; @@ -157,26 +138,39 @@ void setup() { config.runStatus = RUNSTATUS_PAUSE; } - xTaskCreate(timeTask, "timed tasks", 14000, NULL, 2, NULL); xTaskCreate(initTime, "init time", 5000, NULL, 2, NULL); xTaskCreate(delayedStart, "delaystart", 2000, NULL, 2, NULL); + + wsSendSysteminfo(); + util::printHeap(); } void loop() { - vTaskDelay(10000 / portTICK_PERIOD_MS); - // performDeviceFlash(); - while (1) { - // pinTest(); - while (1) { + ws.cleanupClients(); + wm.poll(); + + if (intervalSysinfo.doRun()) { + wsSendSysteminfo(); + } + if (intervalVars.doRun() && config.runStatus != RUNSTATUS_STOP) { + checkVars(); + } + if (intervalSaveDB.doRun() && config.runStatus != RUNSTATUS_STOP) { + saveDB("/current/tagDB.json"); + } + if (intervalContentRunner.doRun() && apInfo.state == AP_STATE_ONLINE) { + contentRunner(); + } + #ifdef YELLOW_IPS_AP - extern void yellow_ap_display_loop(void); - yellow_ap_display_loop(); -#else - vTaskDelay(10000 / portTICK_PERIOD_MS); - // pinTest(); + extern void yellow_ap_display_loop(void); + yellow_ap_display_loop(); #endif - } + #ifdef OPENEPAPERLINK_PCB + time_t tagConnectTimer = 0; + if (millis() - tagConnectTimer > 1000) { + tagConnectTimer = millis(); if (extTagConnected()) { flashCountDown(3); @@ -189,7 +183,8 @@ void loop() { pinMode(FLASHER_EXT_TEST, INPUT); vTaskDelay(1000 / portTICK_PERIOD_MS); } -#endif - vTaskDelay(100 / portTICK_PERIOD_MS); } -} \ No newline at end of file +#endif + + vTaskDelay(100 / portTICK_PERIOD_MS); +} diff --git a/ESP32_AP-Flasher/src/ota.cpp b/ESP32_AP-Flasher/src/ota.cpp index 67d4d266..46097201 100644 --- a/ESP32_AP-Flasher/src/ota.cpp +++ b/ESP32_AP-Flasher/src/ota.cpp @@ -303,7 +303,7 @@ void handleUpdateActions(AsyncWebServerRequest* request) { request->send(200, "No update actions needed"); return; } - StaticJsonDocument<1000> doc; + DynamicJsonDocument doc(1000); DeserializationError error = deserializeJson(doc, file); const JsonArray deleteFiles = doc["deletefile"].as(); for (const auto& filePath : deleteFiles) { diff --git a/ESP32_AP-Flasher/src/tag_db.cpp b/ESP32_AP-Flasher/src/tag_db.cpp index 893aa93b..9ed606ae 100644 --- a/ESP32_AP-Flasher/src/tag_db.cpp +++ b/ESP32_AP-Flasher/src/tag_db.cpp @@ -122,6 +122,7 @@ void fillNode(JsonObject& tag, const tagRecord* taginfo) { } void saveDB(const String& filename) { + Serial.println("saveDB start"); DynamicJsonDocument doc(2500); const long t = millis(); @@ -152,6 +153,7 @@ void saveDB(const String& filename) { file.close(); xSemaphoreGive(fsMutex); Serial.println("DB saved " + String(millis() - t) + "ms"); + Serial.println("saveDB end"); } void loadDB(const String& filename) { @@ -170,7 +172,7 @@ void loadDB(const String& filename) { bool parsing = true; if (readfile.find("[")) { - StaticJsonDocument<1000> doc; + DynamicJsonDocument doc(1000); while (parsing) { DeserializationError err = deserializeJson(doc, readfile); if (!err) { diff --git a/ESP32_AP-Flasher/src/web.cpp b/ESP32_AP-Flasher/src/web.cpp index 6ad6b90d..6cfa2b5e 100644 --- a/ESP32_AP-Flasher/src/web.cpp +++ b/ESP32_AP-Flasher/src/web.cpp @@ -35,15 +35,6 @@ WifiManager wm; SemaphoreHandle_t wsMutex; uint32_t lastssidscan = 0; -void networkProcess(void *parameter) { - wsMutex = xSemaphoreCreateMutex(); - while (true) { - ws.cleanupClients(); - wm.poll(); - vTaskDelay(50 / portTICK_PERIOD_MS); - } -} - void wsLog(String text) { StaticJsonDocument<250> doc; doc["logMsg"] = text; @@ -72,33 +63,47 @@ size_t dbSize() { } void wsSendSysteminfo() { + Serial.println("wsSendSysteminfo begin"); DynamicJsonDocument doc(250); JsonObject sys = doc.createNestedObject("sys"); time_t now; time(&now); + Serial.print("1"); static int freeSpaceLastRun = 0; + static size_t tagDBsize = 0; static size_t freeSpace = Storage.freeSpace(); + Serial.print("2"); sys["currtime"] = now; + Serial.print("3"); sys["heap"] = ESP.getFreeHeap(); - sys["recordcount"] = tagDB.size(); + Serial.print("4"); + sys["recordcount"] = tagDBsize; + Serial.print("5"); sys["dbsize"] = dbSize(); - if (millis() - freeSpaceLastRun > 30000) { + Serial.print("6"); + if (millis() - freeSpaceLastRun > 30000 || freeSpaceLastRun == 0) { freeSpace = Storage.freeSpace(); + tagDBsize = tagDB.size(); freeSpaceLastRun = millis(); } + Serial.print("7"); sys["littlefsfree"] = freeSpace; sys["apstate"] = apInfo.state; sys["runstate"] = config.runStatus; + Serial.print("8"); #if !defined(CONFIG_IDF_TARGET_ESP32) - sys["temp"] = temperatureRead(); + // sys["temp"] = temperatureRead(); #endif + Serial.print("9"); sys["rssi"] = WiFi.RSSI(); sys["wifistatus"] = WiFi.status(); sys["wifissid"] = WiFi.SSID(); + Serial.print("a"); setVarDB("ap_ip", WiFi.localIP().toString()); setVarDB("ap_ch", String(apInfo.channel)); + Serial.print("b"); static uint32_t tagcounttimer = 0; if (millis() - tagcounttimer > 60000 || tagcounttimer == 0) { uint32_t timeoutcount = 0; @@ -112,6 +117,7 @@ void wsSendSysteminfo() { setVarDB("ap_tagcount", result); tagcounttimer = millis(); } + Serial.println("wsSendSysteminfo end"); xSemaphoreTake(wsMutex, portMAX_DELAY); ws.textAll(doc.as()); @@ -188,6 +194,7 @@ uint8_t wsClientCount() { } void init_web() { + wsMutex = xSemaphoreCreateMutex(); Storage.begin(); WiFi.mode(WIFI_STA);