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.
This commit is contained in:
Nic Limper
2023-09-23 18:40:28 +02:00
parent 0ba287f734
commit a91dd5c2a2
8 changed files with 93 additions and 65 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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<String>();
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 + "&current_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<String>();
cfgobj["#lon"] = doc["results"][0]["longitude"].as<String>();
@@ -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";

View File

@@ -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);

View File

@@ -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);
}
}
#endif
vTaskDelay(100 / portTICK_PERIOD_MS);
}

View File

@@ -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<JsonArray>();
for (const auto& filePath : deleteFiles) {

View File

@@ -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) {

View File

@@ -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<String>());
@@ -188,6 +194,7 @@ uint8_t wsClientCount() {
}
void init_web() {
wsMutex = xSemaphoreCreateMutex();
Storage.begin();
WiFi.mode(WIFI_STA);