Config re-reading memory corruption issue fixed

This commit is contained in:
2020-01-10 13:33:22 +03:00
parent cc96e4697e
commit 9e9a3c6e7e
3 changed files with 56 additions and 12 deletions

View File

@@ -34,6 +34,7 @@ e-mail anklimov@gmail.com
extern PubSubClient mqttClient; extern PubSubClient mqttClient;
extern aJsonObject *root; extern aJsonObject *root;
extern int8_t ethernetIdleCount; extern int8_t ethernetIdleCount;
extern int8_t configLocked;
#if !defined(DHT_DISABLE) || !defined(COUNTER_DISABLE) #if !defined(DHT_DISABLE) || !defined(COUNTER_DISABLE)
static volatile unsigned long nextPollMillisValue[5]; static volatile unsigned long nextPollMillisValue[5];
@@ -462,12 +463,14 @@ bool Input::executeCommand(aJsonObject* cmd, int8_t toggle, char* defCmd)
break; break;
case aJson_Array: //array - recursive iterate case aJson_Array: //array - recursive iterate
{ {
configLocked++;
aJsonObject * command = cmd->child; aJsonObject * command = cmd->child;
while (command) while (command)
{ {
executeCommand(command,toggle,defCmd); executeCommand(command,toggle,defCmd);
command = command->next; command = command->next;
} }
configLocked--;
} }
break; break;
case aJson_Object: case aJson_Object:

View File

@@ -46,6 +46,7 @@ short modbusBusy = 0;
extern aJsonObject *pollingItem; extern aJsonObject *pollingItem;
extern PubSubClient mqttClient; extern PubSubClient mqttClient;
extern int8_t ethernetIdleCount; extern int8_t ethernetIdleCount;
extern int8_t configLocked;
static unsigned long lastctrl = 0; static unsigned long lastctrl = 0;
static aJsonObject *lastobj = NULL; static aJsonObject *lastobj = NULL;
@@ -1020,6 +1021,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
{ {
if (itemArg->type == aJson_Array) { if (itemArg->type == aJson_Array) {
aJsonObject *i = itemArg->child; aJsonObject *i = itemArg->child;
configLocked++;
while (i) { while (i) {
if (i->type == aJson_String) if (i->type == aJson_String)
{ {
@@ -1028,6 +1030,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode
} }
i = i->next; i = i->next;
} //while } //while
configLocked--;
} //if } //if
} //case } //case
break; break;

View File

@@ -157,6 +157,7 @@ aJsonObject *pollingItem = NULL;
bool owReady = false; bool owReady = false;
bool configOk = false; bool configOk = false;
int8_t ethernetIdleCount =0; int8_t ethernetIdleCount =0;
int8_t configLocked = 0;
#ifdef _modbus #ifdef _modbus
ModbusMaster node; ModbusMaster node;
@@ -177,6 +178,24 @@ void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init f
void cleanConf() void cleanConf()
{ {
if (!root) return; if (!root) return;
debugSerial<<F("Unlocking config ...");
while (configLocked)
{
//wdt_res();
cmdPoll();
#ifdef _owire
if (owReady && owArr) owLoop();
#endif
#ifdef _dmxin
DMXCheck();
#endif
if (lanStatus != RETAINING_COLLECTING) pollingLoop();
thermoLoop();
inputLoop();
}
pollingItem = NULL;;
debugSerial<<F("Deleting conf. RAM was:")<<freeRam(); debugSerial<<F("Deleting conf. RAM was:")<<freeRam();
aJson.deleteItem(root); aJson.deleteItem(root);
root = NULL; root = NULL;
@@ -304,11 +323,8 @@ lan_status lanLoop() {
break; break;
case HAVE_IP_ADDRESS: case HAVE_IP_ADDRESS:
#ifdef OTA
// start the OTEthernet library with internal (flash) based storage
ArduinoOTA.begin(Ethernet.localIP(), "Lighthub", "password", InternalStorage);
#endif
if (configLocked) return HAVE_IP_ADDRESS;
if (!configOk) if (!configOk)
lanStatus = loadConfigFromHttp(0, NULL); lanStatus = loadConfigFromHttp(0, NULL);
else lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER; else lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
@@ -452,7 +468,7 @@ void onMQTTConnect(){
strncat_P(topic, homie_P, sizeof(topic)); strncat_P(topic, homie_P, sizeof(topic));
strncpy_P(buf, homiever_P, sizeof(buf)); strncpy_P(buf, homiever_P, sizeof(buf));
mqttClient.publish(topic,buf,true); mqttClient.publish(topic,buf,true);
configLocked++;
if (items) { if (items) {
char datatype[32]="\0"; char datatype[32]="\0";
char format [64]="\0"; char format [64]="\0";
@@ -514,6 +530,7 @@ void onMQTTConnect(){
strncat_P(topic, nodes_P, sizeof(topic)); strncat_P(topic, nodes_P, sizeof(topic));
/// mqttClient.publish(topic,buf,true); /// mqttClient.publish(topic,buf,true);
} }
configLocked--;
#endif #endif
} }
@@ -715,6 +732,10 @@ wifiManager.setTimeout(30);
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED) {
debugSerial<<F("WiFi connected. IP address: ")<<WiFi.localIP()<<endl; debugSerial<<F("WiFi connected. IP address: ")<<WiFi.localIP()<<endl;
lanStatus = HAVE_IP_ADDRESS;//1; lanStatus = HAVE_IP_ADDRESS;//1;
#ifdef OTA
// start the OTEthernet library with internal (flash) based storage
ArduinoOTA.begin(Ethernet.localIP(), "Lighthub", "password", InternalStorage);
#endif
} else } else
{ {
debugSerial<<F("Problem with WiFi!"); debugSerial<<F("Problem with WiFi!");
@@ -749,6 +770,10 @@ wifiManager.setTimeout(30);
} else Ethernet.begin(mac, ip); } else Ethernet.begin(mac, ip);
debugSerial<<endl; debugSerial<<endl;
lanStatus = HAVE_IP_ADDRESS; lanStatus = HAVE_IP_ADDRESS;
#ifdef OTA
// start the OTEthernet library with internal (flash) based storage
ArduinoOTA.begin(Ethernet.localIP(), "Lighthub", "password", InternalStorage);
#endif
#ifdef _artnet #ifdef _artnet
if (artnet) artnet->begin(); if (artnet) artnet->begin();
#endif #endif
@@ -777,6 +802,10 @@ wifiManager.setTimeout(30);
debugSerial<<F("Got IP address:"); debugSerial<<F("Got IP address:");
printIPAddress(Ethernet.localIP()); printIPAddress(Ethernet.localIP());
lanStatus = HAVE_IP_ADDRESS;//1; lanStatus = HAVE_IP_ADDRESS;//1;
#ifdef OTA
// start the OTEthernet library with internal (flash) based storage
ArduinoOTA.begin(Ethernet.localIP(), "Lighthub", "password", InternalStorage);
#endif
#ifdef _artnet #ifdef _artnet
if (artnet) artnet->begin(); if (artnet) artnet->begin();
#endif #endif
@@ -894,6 +923,7 @@ void cmdFunctionReboot(int arg_cnt, char **args) {
void applyConfig() { void applyConfig() {
if (!root) return; if (!root) return;
configLocked++;
#ifdef _dmxin #ifdef _dmxin
int itemsCount; int itemsCount;
dmxArr = aJson.getObjectItem(root, "dmxin"); dmxArr = aJson.getObjectItem(root, "dmxin");
@@ -921,6 +951,7 @@ void applyConfig() {
owReady = owSetup(&Changed); owReady = owSetup(&Changed);
if (owReady) debugSerial<<F("One wire Ready\n"); if (owReady) debugSerial<<F("One wire Ready\n");
t_count = 0; t_count = 0;
while (item && owReady) { while (item && owReady) {
if ((item->type == aJson_Object)) { if ((item->type == aJson_Object)) {
DeviceAddress addr; DeviceAddress addr;
@@ -980,6 +1011,8 @@ void applyConfig() {
udpSyslogArr = aJson.getObjectItem(root, "syslog"); udpSyslogArr = aJson.getObjectItem(root, "syslog");
#endif #endif
printConfigSummary(); printConfigSummary();
configLocked--;
} }
void printConfigSummary() { void printConfigSummary() {
@@ -1703,9 +1736,9 @@ void loop_main() {
#endif #endif
if (items) { if (items) {
#ifndef MODBUS_DISABLE // #ifndef MODBUS_DISABLE
if (lanStatus != RETAINING_COLLECTING) pollingLoop(); if (lanStatus != RETAINING_COLLECTING) pollingLoop();
#endif // #endif
//#ifdef _owire //#ifdef _owire
thermoLoop(); thermoLoop();
//#endif //#endif
@@ -1771,9 +1804,10 @@ void modbusIdle(void) {
void inputLoop(void) { void inputLoop(void) {
if (!inputs) return; if (!inputs) return;
configLocked++;
if (millis() > nextInputCheck) { if (millis() > nextInputCheck) {
aJsonObject *input = inputs->child; aJsonObject *input = inputs->child;
while (input) { while (input) {
if ((input->type == aJson_Object)) { if ((input->type == aJson_Object)) {
Input in(input); Input in(input);
@@ -1795,12 +1829,12 @@ void inputLoop(void) {
} }
nextSensorCheck = millis() + INTERVAL_CHECK_SENSOR; nextSensorCheck = millis() + INTERVAL_CHECK_SENSOR;
} }
configLocked--;
} }
void inputSetup(void) { void inputSetup(void) {
if (!inputs) return; if (!inputs) return;
configLocked++;
aJsonObject *input = inputs->child; aJsonObject *input = inputs->child;
while (input) { while (input) {
if ((input->type == aJson_Object)) { if ((input->type == aJson_Object)) {
@@ -1809,11 +1843,13 @@ void inputSetup(void) {
} }
input = input->next; input = input->next;
} }
configLocked--;
} }
void pollingLoop(void) { void pollingLoop(void) {
// FAST POLLINT - as often AS possible every item // FAST POLLINT - as often AS possible every item
configLocked++;
if (items) { if (items) {
aJsonObject * item = items->child; aJsonObject * item = items->child;
while (items && item) while (items && item)
@@ -1825,7 +1861,7 @@ if (items) {
item = item->next; item = item->next;
} //if } //if
} }
configLocked--;
// SLOW POLLING // SLOW POLLING
boolean done = false; boolean done = false;
if (lanStatus == RETAINING_COLLECTING) return; if (lanStatus == RETAINING_COLLECTING) return;
@@ -1840,6 +1876,7 @@ if (items) {
done = true; done = true;
} }
}//if }//if
if (!pollingItem) return; //Config was re-readed
pollingItem = pollingItem->next; pollingItem = pollingItem->next;
if (!pollingItem) { if (!pollingItem) {
pollingItem = items->child; pollingItem = items->child;
@@ -1873,6 +1910,7 @@ void thermoLoop(void) {
return; return;
if (!items) return; if (!items) return;
bool thermostatCheckPrinted = false; bool thermostatCheckPrinted = false;
configLocked++;
for (aJsonObject *thermoItem = items->child; thermoItem; thermoItem = thermoItem->next) { for (aJsonObject *thermoItem = items->child; thermoItem; thermoItem = thermoItem->next) {
if (isThermostatWithMinArraySize(thermoItem, 5)) { if (isThermostatWithMinArraySize(thermoItem, 5)) {
aJsonObject *thermoExtensionArray = aJson.getArrayItem(thermoItem, I_EXT); aJsonObject *thermoExtensionArray = aJson.getArrayItem(thermoItem, I_EXT);
@@ -1916,7 +1954,7 @@ void thermoLoop(void) {
} }
} }
} }
configLocked--;
nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD; nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD;
publishStat(); publishStat();
#ifndef DISABLE_FREERAM_PRINT #ifndef DISABLE_FREERAM_PRINT