[ESP8266] Fix stability issues when using 2nd heap

This commit is contained in:
TD-er
2023-11-15 11:44:41 +01:00
parent 69103b1d0d
commit 3475de24ca
42 changed files with 264 additions and 185 deletions
+1
View File
@@ -13,6 +13,7 @@ platform_packages = ${regular_platform.platform_packages}
build_flags = ${regular_platform.build_flags}
-DBUILD_NO_DEBUG
-DPLUGIN_BUILD_CUSTOM
-DFEATURE_DEFINE_SERIAL_CONSOLE_PORT=0
[esp8266_custom_common]
+4
View File
@@ -61,6 +61,10 @@ bool CPlugin_001(CPlugin::Function function, struct EventStruct *event, String&
{
// We now create a URI for the request
const Sensor_VType sensorType = event->getSensorType();
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String url;
const size_t expectedSize = sensorType == Sensor_VType::SENSOR_TYPE_STRING ? 64 + event->String2.length() : 128;
+4
View File
@@ -197,6 +197,10 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String&
if (event->idx != 0)
{
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String json = serializeDomoticzJson(event);
# ifndef BUILD_NO_DEBUG
+13 -7
View File
@@ -53,15 +53,21 @@ bool CPlugin_003(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
// We now create a URI for the request
String url = F("variableset ");
url += event->idx;
url += ',';
url += formatUserVarNoCheck(event, 0);
url += '\n';
std::unique_ptr<C003_queue_element> element(new C003_queue_element(event->ControllerIndex, event->TaskIndex, std::move(url)));
String url = strformat(
F("variableset %d,%s\n"),
event->idx,
formatUserVarNoCheck(event, 0).c_str());
std::unique_ptr<C003_queue_element> element(
new C003_queue_element(
event->ControllerIndex,
event->TaskIndex,
std::move(url)));
success = C003_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C003_DELAY_QUEUE, C003_DelayHandler->getNextScheduleTime());
+4
View File
@@ -71,6 +71,10 @@ bool CPlugin_004(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
std::unique_ptr<C004_queue_element> element(new C004_queue_element(event));
success = C004_DelayHandler->addToQueue(std::move(element));
+19 -6
View File
@@ -94,6 +94,10 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String&
if (getTaskValueName(event->TaskIndex, x).isEmpty()) {
continue; // we skip values with empty labels
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String tmppubname = pubname;
parseSingleControllerVariable(tmppubname, event, x, false);
String value;
@@ -156,6 +160,10 @@ bool C005_parse_command(struct EventStruct *event) {
// Message: gpio,14,0
// Full command: gpio,14,0
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
cmd = event->String2;
// SP_C005a: string= ;cmd=gpio,12,0 ;taskIndex=12 ;string1=ESPT12/cmd ;string2=gpio,12,0
@@ -176,6 +184,9 @@ bool C005_parse_command(struct EventStruct *event) {
if (!topic_folder.isEmpty()) {
int32_t cmd_arg_nr = -1;
if (validIntFromString(topic_folder.substring(7), cmd_arg_nr)) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
int constructed_cmd_arg_nr = 0;
++topic_index;
topic_folder = parseStringKeepCase(event->String1, topic_index, '/');
@@ -215,12 +226,14 @@ bool C005_parse_command(struct EventStruct *event) {
if (validFloatFromString(event->String2, value_f) &&
validIntFromString(lastPartTopic, lastPartTopic_int)) {
int prevLastindex = event->String1.lastIndexOf('/', lastindex - 1);
cmd = event->String1.substring(prevLastindex + 1, lastindex);
cmd += ',';
cmd += lastPartTopic_int;
cmd += ',';
cmd += event->String2; // Just use the original format
const int prevLastindex = event->String1.lastIndexOf('/', lastindex - 1);
cmd = strformat(
F("%s,%d,%s"),
event->String1.substring(prevLastindex + 1, lastindex).c_str(),
lastPartTopic_int,
event->String2.c_str() // Just use the original format
);
validTopic = true;
}
}
+4
View File
@@ -68,6 +68,10 @@ bool CPlugin_007(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
std::unique_ptr<C007_queue_element> element(new C007_queue_element(event));
success = C007_DelayHandler->addToQueue(std::move(element));
+3
View File
@@ -77,6 +77,9 @@ bool CPlugin_008(CPlugin::Function function, struct EventStruct *event, String&
pubname = ControllerSettings->Publish;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
uint8_t valueCount = getValueCountForTask(event->TaskIndex);
std::unique_ptr<C008_queue_element> element(new C008_queue_element(event, valueCount));
+4
View File
@@ -80,6 +80,10 @@ bool CPlugin_009(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
std::unique_ptr<C009_queue_element> element(new C009_queue_element(event));
success = C009_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C009_DELAY_QUEUE, C009_DelayHandler->getNextScheduleTime());
+3
View File
@@ -103,6 +103,9 @@ bool CPlugin_010(CPlugin::Function function, struct EventStruct *event, String&
}
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
success = C010_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C010_DELAY_QUEUE, C010_DelayHandler->getNextScheduleTime());
+4
View File
@@ -261,6 +261,10 @@ boolean Create_schedule_HTTP_C011(struct EventStruct *event)
}
//LoadTaskSettings(event->TaskIndex); // FIXME TD-er: This can probably be removed
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
// Add a new element to the queue with the minimal payload
std::unique_ptr<C011_queue_element> element(new C011_queue_element(event));
bool success = C011_DelayHandler->addToQueue(std::move(element));
+4
View File
@@ -57,6 +57,10 @@ bool CPlugin_012(CPlugin::Function function, struct EventStruct *event, String&
}
//LoadTaskSettings(event->TaskIndex); // FIXME TD-er: This can probably be removed
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
// Collect the values at the same run, to make sure all are from the same sample
uint8_t valueCount = getValueCountForTask(event->TaskIndex);
std::unique_ptr<C012_queue_element> element(new C012_queue_element(event, valueCount));
+4
View File
@@ -841,6 +841,10 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
if ((equals(command, F("event"))) || (equals(command, F("asyncevent"))))
{
if (Settings.UseRules) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String newEvent = parseStringToEnd(cmd, 2);
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
+8
View File
@@ -181,6 +181,10 @@ bool CPlugin_015(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
// Collect the values at the same run, to make sure all are from the same sample
uint8_t valueCount = getValueCountForTask(event->TaskIndex);
@@ -460,6 +464,10 @@ BLYNK_WRITE_DEFAULT() {
}
if (Settings.UseRules) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String eventCommand = F("blynkv");
eventCommand += vPin;
eventCommand += '=';
+4
View File
@@ -67,6 +67,10 @@ bool CPlugin_017(CPlugin::Function function, struct EventStruct *event, String&
break;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
std::unique_ptr<C017_queue_element> element(new C017_queue_element(event));
success = C017_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C017_DELAY_QUEUE, C017_DelayHandler->getNextScheduleTime());
+10 -4
View File
@@ -202,10 +202,16 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String&
}
if (C018_data != nullptr) {
std::unique_ptr<C018_queue_element> element(new C018_queue_element(event, C018_data->getSampleSetCount(event->TaskIndex)));
success = C018_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C018_DELAY_QUEUE,
C018_DelayHandler->getNextScheduleTime());
{
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
std::unique_ptr<C018_queue_element> element(new C018_queue_element(event, C018_data->getSampleSetCount(event->TaskIndex)));
success = C018_DelayHandler->addToQueue(std::move(element));
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_C018_DELAY_QUEUE,
C018_DelayHandler->getNextScheduleTime());
}
if (!C018_data->isInitialized()) {
// Sometimes the module does need some time after power on to respond.
+3 -1
View File
@@ -220,7 +220,9 @@ boolean Plugin_077(uint8_t function, struct EventStruct *event, String& string)
P077_QUERY4 = static_cast<uint8_t>(P077_QUERY4_DFLT);
}
# ifdef USE_SECOND_HEAP
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
initPluginTaskData(event->TaskIndex, new (std::nothrow) P077_data_struct());
P077_data_struct *P077_data = static_cast<P077_data_struct *>(getPluginTaskData(event->TaskIndex));
+2 -7
View File
@@ -466,16 +466,11 @@ boolean Plugin_082(uint8_t function, struct EventStruct *event, String& string)
// Add sanity check for distance travelled
if (distance > static_cast<ESPEASY_RULES_FLOAT_TYPE>(P082_DISTANCE)) {
if (Settings.UseRules) {
String eventString = F("GPS#travelled=");
eventString += distance;
eventQueue.addMove(std::move(eventString));
eventQueue.addMove(strformat(F("GPS#travelled=%f"), distance));
}
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("GPS: Distance trigger : ");
log += distance;
log += F(" m");
addLogMove(LOG_LEVEL_INFO, log);
addLogMove(LOG_LEVEL_INFO, strformat(F("GPS: Distance trigger : %f m"), distance));
}
}
}
@@ -18,7 +18,7 @@ bool init_mqtt_delay_queue(controllerIndex_t ControllerIndex, String& pubname, b
if (MQTTDelayHandler == nullptr) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
MQTTDelayHandler = new (std::nothrow) ControllerDelayHandlerStruct;
+1 -1
View File
@@ -70,7 +70,7 @@
} \
bool init_c##NNN####M##_delay_queue(controllerIndex_t ControllerIndex) { \
if (C##NNN####M##_DelayHandler == nullptr) { \
HeapSelectIram ephemeral; \
HeapSelectDram ephemeral; \
C##NNN####M##_DelayHandler = new (std::nothrow) (ControllerDelayHandlerStruct); \
} \
if (C##NNN####M##_DelayHandler == nullptr) { return false; } \
+4 -19
View File
@@ -2,6 +2,8 @@
#if FEATURE_MQTT
#include "../Helpers/StringConverter.h"
MQTT_queue_element::MQTT_queue_element(int ctrl_idx,
taskIndex_t TaskIndex,
const String& topic, const String& payload,
@@ -35,25 +37,8 @@ MQTT_queue_element::MQTT_queue_element(int ctrl_idx,
_call_PLUGIN_PROCESS_CONTROLLER_DATA = callbackTask;
// Copy in the scope of the constructor, so we might store it in the 2nd heap
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
if (topic.length() && !mmu_is_iram(&(topic[0]))) {
_topic = topic;
} else {
_topic = std::move(topic);
}
if (payload.length() && !mmu_is_iram(&(payload[0]))) {
_payload = payload;
} else {
_payload = std::move(payload);
}
# else // ifdef USE_SECOND_HEAP
_topic = std::move(topic);
_payload = std::move(payload);
# endif // ifdef USE_SECOND_HEAP
move_special(_topic, std::move(topic));
move_special(_payload, std::move(payload));
removeEmptyTopics();
}
@@ -60,17 +60,7 @@ SimpleQueueElement_formatted_Strings& SimpleQueueElement_formatted_Strings::oper
valueCount = rval.valueCount;
for (size_t i = 0; i < VARS_PER_TASK; ++i) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
if (rval.txt[i].length() && !mmu_is_iram(&(rval.txt[i][0]))) {
txt[i] = rval.txt[i];
} else {
txt[i] = std::move(rval.txt[i]);
}
#else // ifdef USE_SECOND_HEAP
txt[i] = std::move(rval.txt[i]);
#endif // ifdef USE_SECOND_HEAP
move_special(txt[i], std::move(rval.txt[i]));
}
return *this;
}
@@ -1,22 +1,13 @@
#include "../ControllerQueue/SimpleQueueElement_string_only.h"
#include "../Helpers/StringConverter.h"
simple_queue_element_string_only::simple_queue_element_string_only(int ctrl_idx, taskIndex_t TaskIndex, String&& req)
{
_controller_idx = ctrl_idx;
_taskIndex = TaskIndex;
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
if ((req.length() > 0) && !mmu_is_iram(&(req[0]))) {
// The string was not allocated on the 2nd heap, so copy instead of move
txt = req;
} else {
txt = std::move(req);
}
#else // ifdef USE_SECOND_HEAP
txt = std::move(req);
#endif // ifdef USE_SECOND_HEAP
move_special(txt, std::move(req));
}
size_t simple_queue_element_string_only::getSize() const {
+4
View File
@@ -265,6 +265,10 @@ void Caches::updateExtraTaskSettingsCache()
const taskIndex_t TaskIndex = ExtraTaskSettings.TaskIndex;
if (validTaskIndex(TaskIndex)) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
ExtraTaskSettings_cache_t tmp;
auto it = extraTaskSettings_cache.find(TaskIndex);
+21 -17
View File
@@ -4,15 +4,17 @@
#include "../Globals/Settings.h"
#include "../Helpers/Misc.h"
#include "../Helpers/StringConverter.h"
void EventQueueStruct::add(const String& event, bool deduplicate)
{
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif // ifdef USE_SECOND_HEAP
if (!deduplicate || !isDuplicate(event)) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif // ifdef USE_SECOND_HEAP
_eventQueue.push_back(event);
}
}
@@ -22,11 +24,7 @@ void EventQueueStruct::add(const __FlashStringHelper *event, bool deduplicate)
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif // ifdef USE_SECOND_HEAP
// Wrap in String() constructor to make sure it is using the 2nd heap allocator if present.
if (!deduplicate || !isDuplicate(event)) {
_eventQueue.push_back(String(event));
}
add(String(event), deduplicate);
}
void EventQueueStruct::addMove(String&& event, bool deduplicate)
@@ -52,16 +50,22 @@ void EventQueueStruct::addMove(String&& event, bool deduplicate)
void EventQueueStruct::add(taskIndex_t TaskIndex, const String& varName, const String& eventValue)
{
if (Settings.UseRules) {
String eventCommand = getTaskDeviceName(TaskIndex);
eventCommand.reserve(eventCommand.length() + 2 + varName.length() + eventValue.length());
eventCommand += '#';
eventCommand += varName;
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
if (!eventValue.isEmpty()) {
eventCommand += '='; // Add arguments
eventCommand += eventValue;
if (eventValue.isEmpty()) {
addMove(strformat(
F("%s#%s"),
getTaskDeviceName(TaskIndex).c_str(),
varName.c_str()));
} else {
addMove(strformat(
F("%s#%s=%s"),
getTaskDeviceName(TaskIndex).c_str(),
varName.c_str(),
eventValue.c_str()));
}
addMove(std::move(eventCommand));
}
}
+2 -14
View File
@@ -1,6 +1,7 @@
#include "../DataStructs/LogEntry.h"
#include "../Helpers/ESPEasy_time_calc.h"
#include "../Helpers/StringConverter.h"
#define LOG_STRUCT_MESSAGE_SIZE 128
@@ -46,20 +47,7 @@ bool LogEntry_t::add(const uint8_t loglevel, String&& line)
#endif // ifdef USE_SECOND_HEAP
_message = std::move(line.substring(0, LOG_STRUCT_MESSAGE_SIZE - 1));
} else {
#ifdef USE_SECOND_HEAP
// Allow to store the logs in 2nd heap if present.
HeapSelectIram ephemeral;
if (!mmu_is_iram(&(line[0]))) {
// The log entry was not allocated on the 2nd heap, so copy instead of move
_message = line;
} else {
_message = std::move(line);
}
#else // ifdef USE_SECOND_HEAP
_message = std::move(line);
#endif // ifdef USE_SECOND_HEAP
move_special(_message, std::move(line));
}
_loglevel = loglevel;
_timestamp = millis();
+4
View File
@@ -65,6 +65,10 @@ bool NodesHandler::addNode(const NodeStruct& node)
}
{
_nodes_mutex.lock();
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
_nodes[node.unit] = node;
_ntp_candidate.set(node);
_nodes[node.unit].lastUpdated = millis();
+1 -1
View File
@@ -8,7 +8,7 @@
UserVarStruct::UserVarStruct()
{
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
_data.resize(TASKS_MAX);
+2 -1
View File
@@ -24,8 +24,9 @@ Web_StreamingBuffer::Web_StreamingBuffer(void) : lowMemorySkip(false),
initialRam(0), beforeTXRam(0), duringTXRam(0), finalRam(0), maxCoreUsage(0),
maxServerUsage(0), sentBytes(0), flashStringCalls(0), flashStringData(0)
{
// Make sure this is allocated on the DRAM since access to primary heap is faster
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
buf.reserve(CHUNKED_BUFFER_SIZE + 50);
+13 -10
View File
@@ -28,7 +28,7 @@
#include <math.h>
#include <vector>
#ifdef WEBSERVER_NEW_RULES
String EventToFileName(const String& eventName) {
int size = eventName.length();
int index = eventName.indexOf('=');
@@ -58,6 +58,7 @@ String FileNameToEvent(const String& fileName) {
eventName.replace(RULE_FILE_SEPARAROR, '#');
return eventName;
}
#endif
void checkRuleSets() {
Cache.rulesHelper.closeAllFiles();
@@ -98,9 +99,7 @@ void rulesProcessing(const String& event) {
#endif // ifndef BUILD_NO_DEBUG
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("EVENT: ");
log += event;
addLogMove(LOG_LEVEL_INFO, log);
addLogMove(LOG_LEVEL_INFO, concat(F("EVENT: "), event));
}
if (Settings.OldRulesEngine()) {
@@ -139,12 +138,7 @@ void rulesProcessing(const String& event) {
#ifndef BUILD_NO_DEBUG
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log = F("EVENT: ");
log += event;
log += F(" Processing time:");
log += timePassedSince(timer);
log += F(" milliSeconds");
addLogMove(LOG_LEVEL_DEBUG, log);
addLogMove(LOG_LEVEL_DEBUG, strformat(F("EVENT: %s Processing: %d ms"), event.c_str(), timePassedSince(timer)));
}
#endif // ifndef BUILD_NO_DEBUG
STOP_TIMER(RULES_PROCESSING);
@@ -1315,6 +1309,11 @@ void createRuleEvents(struct EventStruct *event) {
expectedSize += getTaskValueName(event->TaskIndex, 0).length();
bool appendCompleteStringvalue = false;
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String eventString;
if (eventString.reserve(expectedSize + event->String2.length())) {
@@ -1339,6 +1338,10 @@ void createRuleEvents(struct EventStruct *event) {
eventString += '`';
eventQueue.addMove(std::move(eventString));
} else if (Settings.CombineTaskValues_SingleEvent(event->TaskIndex)) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String eventvalues;
eventvalues.reserve(32); // Enough for most use cases, prevent lots of memory allocations.
+2
View File
@@ -9,10 +9,12 @@
#include "../CustomBuild/ESPEasyLimits.h"
#ifdef WEBSERVER_NEW_RULES
String EventToFileName(const String& eventName);
String FileNameToEvent(const String& fileName);
#endif
void checkRuleSets();
+2 -2
View File
@@ -58,7 +58,7 @@ EspEasy_Console_t::EspEasy_Console_t()
{
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
_mainSerial._serial = new (std::nothrow) ESPeasySerial(config);
@@ -146,7 +146,7 @@ void EspEasy_Console_t::reInit()
if ((_mainSerial._serial == nullptr) && mustHaveSerial) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
_mainSerial._serial = new (std::nothrow) ESPeasySerial(
+11 -5
View File
@@ -350,6 +350,7 @@ bool PluginCallForTask(taskIndex_t taskIndex, uint8_t Function, EventStruct *Tem
}
START_TIMER;
/*
# ifdef USE_SECOND_HEAP
if (Function == PLUGIN_INIT)
{
@@ -358,10 +359,13 @@ bool PluginCallForTask(taskIndex_t taskIndex, uint8_t Function, EventStruct *Tem
retval = (PluginCall(DeviceIndex, Function, TempEvent, command));
} else {
# endif // ifdef USE_SECOND_HEAP
*/
retval = (PluginCall(DeviceIndex, Function, TempEvent, command));
/*
# ifdef USE_SECOND_HEAP
}
# endif // ifdef USE_SECOND_HEAP
*/
STOP_TIMER_TASK(DeviceIndex, Function);
@@ -581,11 +585,13 @@ bool PluginCall(uint8_t Function, struct EventStruct *event, String& str)
{
for (taskIndex_t taskIndex = 0; taskIndex < TASKS_MAX; taskIndex++)
{
if (PluginCallForTask(taskIndex, Function, &TempEvent, str)) {
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("PluginCallUDP"), taskIndex);
#endif
return true;
if (Settings.TaskDeviceEnabled[taskIndex]) {
if (PluginCallForTask(taskIndex, Function, &TempEvent, str)) {
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("PluginCallUDP"), taskIndex);
#endif
return true;
}
}
}
return false;
-4
View File
@@ -1109,10 +1109,6 @@ String LoadTaskSettings(taskIndex_t TaskIndex)
}
START_TIMER
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
ExtraTaskSettings.clear();
const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(TaskIndex);
if (!validDeviceIndex(DeviceIndex)) {
+1 -1
View File
@@ -47,7 +47,7 @@ bool ModbusRTU_struct::init(const ESPEasySerialPort port, const int16_t serial_r
reset();
{
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
HeapSelectDram ephemeral;
# endif // ifdef USE_SECOND_HEAP
easySerial = new (std::nothrow) ESPeasySerial(port, serial_rx, serial_tx);
+3 -8
View File
@@ -325,13 +325,7 @@ void checkUDP()
memcpy(&received, &packetBuffer[2], copy_length);
if (received.validate()) {
{
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
Nodes.addNode(received); // Create a new element when not present
}
Nodes.addNode(received); // Create a new element when not present
# ifndef BUILD_NO_DEBUG
@@ -355,7 +349,8 @@ void checkUDP()
TempEvent.Par1 = remoteIP[3];
TempEvent.Par2 = len;
String dummy;
PluginCall(PLUGIN_UDP_IN, &TempEvent, dummy);
// TD-er: Disabled the PLUGIN_UDP_IN call as we don't have any plugin using this.
//PluginCall(PLUGIN_UDP_IN, &TempEvent, dummy);
CPluginCall(CPlugin::Function::CPLUGIN_UDP_IN, &TempEvent);
break;
}
+4 -4
View File
@@ -9,8 +9,8 @@ void SerialWriteBuffer_t::add(const String& line)
{
#ifdef USE_SECOND_HEAP
// Allow to store the logs in 2nd heap if present.
HeapSelectIram ephemeral;
// Do not store in 2nd heap, std::dequeue cannot handle 2nd heap well
HeapSelectDram ephemeral;
#endif // ifdef USE_SECOND_HEAP
int roomLeft = getRoomLeft();
@@ -87,8 +87,8 @@ size_t SerialWriteBuffer_t::write(Stream& stream, size_t nrBytesToWrite)
int SerialWriteBuffer_t::getRoomLeft() const {
#ifdef USE_SECOND_HEAP
// If stored in 2nd heap, we must check this for space
HeapSelectIram ephemeral;
// Do not store in 2nd heap, std::dequeue cannot handle 2nd heap well
HeapSelectDram ephemeral;
#endif // ifdef USE_SECOND_HEAP
int roomLeft = getMaxFreeBlock();
+50 -45
View File
@@ -61,6 +61,21 @@ bool equals(const String& str, const char& c) {
return str.equals(String(c));
}
void move_special(String& dest, String&& source) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
if ((source.length() > 0) && !mmu_is_iram(&(source[0]))) {
// The string was not allocated on the 2nd heap, so copy instead of move
dest = source;
} else {
dest = std::move(source);
}
#else // ifdef USE_SECOND_HEAP
dest = std::move(source);
#endif // ifdef USE_SECOND_HEAP
}
/********************************************************************************************\
Format string using vsnprintf
@@ -524,29 +539,11 @@ String wrap_braces(const String& string) {
}
String wrap_String(const String& string, char wrap) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
String result;
result.reserve(string.length() + 2);
result += wrap;
result += string;
result += wrap;
return result;
return wrap_String(string, wrap, wrap);
}
String wrap_String(const String& string, char char1, char char2) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
String result;
result.reserve(string.length() + 2);
result += char1;
result += string;
result += char2;
return result;
return strformat(F("%c%s%c"), char1, string.c_str(), char2);
}
String wrapIfContains(const String& value, char contains, char wrap) {
@@ -564,10 +561,9 @@ String wrapWithQuotes(const String& text) {
char quotechar = '_';
if (!findUnusedQuoteChar(text, quotechar)) {
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
String log = F("No unused quote to wrap: _");
log += text;
log += '_';
addLogMove(LOG_LEVEL_ERROR, log);
addLogMove(LOG_LEVEL_ERROR, strformat(
F("No unused quote to wrap: _%s_"),
text.c_str()));
}
}
return wrap_String(text, quotechar);
@@ -609,16 +605,10 @@ String to_json_object_value(const __FlashStringHelper * object,
}
String to_json_object_value(const String& object, const String& value, bool wrapInQuotes) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
String result;
result.reserve(object.length() + value.length() + 6);
result = wrap_String(object, '"');
result += ':';
result += to_json_value(value, wrapInQuotes);
return result;
return strformat(
F("%s:%s"),
wrap_String(object, '"').c_str(),
to_json_value(value, wrapInQuotes).c_str());
}
String to_json_value(const String& value, bool wrapInQuotes) {
@@ -667,6 +657,10 @@ String stripWrappingChar(const String& text, char wrappingChar) {
const unsigned int length = text.length();
if ((length >= 2) && stringWrappedWithChar(text, wrappingChar)) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
return text.substring(1, length - 1);
}
return text;
@@ -753,6 +747,7 @@ bool safe_strncpy(char *dest, const char *source, size_t max_size) {
// Convert a string to lower case and replace spaces with underscores.
String to_internal_string(const String& input, char replaceSpace) {
// Do not set to 2nd heap as it is only used temporarily so prefer speed over mem usage
String result = input;
result.trim();
@@ -782,6 +777,9 @@ String parseStringKeepCaseNoTrim(const String& string, uint8_t indexFind, char s
}
String parseStringKeepCase(const String& string, uint8_t indexFind, char separator, bool trimResult) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String result;
if (!GetArgv(string.c_str(), result, indexFind, separator)) {
@@ -829,6 +827,10 @@ String parseStringToEndKeepCase(const String& string, uint8_t indexFind, char se
if (!hasArgument || (pos_begin < 0) || (pos_begin == pos_end)) {
return EMPTY_STRING;
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String result = string.substring(pos_begin, pos_end);
if (trimResult) {
@@ -858,16 +860,16 @@ String tolerantParseStringKeepCase(const String& string, uint8_t indexFind, char
* handles: 0xXX,text,0xXX," more text ",0xXX starting from index 2 (1-based)
****************************************************************************/
String parseHexTextString(const String& argument, int index) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
String result;
// Ignore these characters when used as hex-byte separators (0x01ab 23-cd:45 -> 0x01,0xab,0x23,0xcd,0x45)
const String skipChars = F(" -:,.;");
result.reserve(argument.length()); // longer than needed, most likely
{
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
result.reserve(argument.length()); // longer than needed, most likely
}
int i = index;
String arg = parseStringKeepCase(argument, i, ',', false);
@@ -903,16 +905,19 @@ String parseHexTextString(const String& argument, int index) {
* handles: 0xXX,text,0xXX," more text ",0xXX starting from index 2 (1-based)
****************************************************************************/
std::vector<uint8_t> parseHexTextData(const String& argument, int index) {
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
std::vector<uint8_t> result;
// Ignore these characters when used as hex-byte separators (0x01ab 23-cd:45 -> 0x01,0xab,0x23,0xcd,0x45)
const String skipChars = F(" -:,.;");
result.reserve(argument.length() / 2); // longer than needed, most likely
{
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
#endif
result.reserve(argument.length() / 2); // longer than needed, most likely
}
int i = index;
String arg = parseStringKeepCase(argument, i, ',', false);
+11
View File
@@ -24,6 +24,10 @@ String concat(const char& str, const String &val);
template <typename T>
String concat(const __FlashStringHelper * str, const T &val) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String res(str);
res.concat(val);
return res;
@@ -31,6 +35,10 @@ String concat(const __FlashStringHelper * str, const T &val) {
template <typename T>
String concat(const String& str, const T &val) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String res(str);
res.concat(val);
return res;
@@ -39,6 +47,9 @@ String concat(const String& str, const T &val) {
bool equals(const String& str, const __FlashStringHelper * f_str);
bool equals(const String& str, const char& c);
// Move the string to 2nd heap if present
void move_special(String& dest, String&& source);
/*
template <typename T>
bool equals(const String& str, const T &val) {
@@ -41,6 +41,10 @@ String toString(const float& value, unsigned int decimalPlaces)
// This has been fixed in ESP32 code, not (yet) in ESP8266 code
// https://github.com/espressif/arduino-esp32/pull/6138/files
// #ifdef ESP8266
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
char buf[decimalPlaces + 42];
String sValue(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf));
@@ -54,6 +58,9 @@ String toString(const float& value, unsigned int decimalPlaces)
}
String ull2String(uint64_t value, uint8_t base) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String res;
if (value == 0) {
@@ -81,6 +88,10 @@ String ull2String(uint64_t value, uint8_t base) {
}
String ll2String(int64_t value, uint8_t base) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
if (value < 0) {
String res;
res = '-';
@@ -92,6 +103,9 @@ String ll2String(int64_t value, uint8_t base) {
}
String trimTrailingZeros(const String& value) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String res(value);
int dot_pos = res.lastIndexOf('.');
@@ -144,6 +158,9 @@ String doubleToString(const double& value, unsigned int decimalPlaces, bool trim
if (nullptr == buf) {
return F("nan");
}
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
String res(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf));
free(buf);
+7 -4
View File
@@ -270,10 +270,6 @@ bool WiFi_AP_CandidatesList::SettingsIndexMatchEmergencyFallback(uint8_t index)
void WiFi_AP_CandidatesList::loadCandidatesFromScanned() {
if (scanned_new.size() > 0) {
// We have new scans to process.
#ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
// TD-er: Disabled for now as it is suspect for crashes
#endif
purge_expired();
for (auto scan = scanned_new.begin(); scan != scanned_new.end();) {
#ifndef BUILD_NO_DEBUG
@@ -322,6 +318,10 @@ void WiFi_AP_CandidatesList::loadCandidatesFromScanned() {
if (scan->isHidden) {
if (Settings.IncludeHiddenSSID()) {
if (SecuritySettings.hasWiFiCredentials()) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
candidates.push_back(*scan);
}
}
@@ -334,6 +334,9 @@ void WiFi_AP_CandidatesList::loadCandidatesFromScanned() {
tmp.isEmergencyFallback = kn_it->isEmergencyFallback;
if (tmp.usable()) {
# ifdef USE_SECOND_HEAP
HeapSelectIram ephemeral;
# endif // ifdef USE_SECOND_HEAP
candidates.push_back(tmp);
_addedKnownCandidate = true;
+1
View File
@@ -369,6 +369,7 @@ void setWebserverRunning(bool state) {
web_server.begin(Settings.WebserverPort);
addLog(LOG_LEVEL_INFO, F("Webserver: start"));
} else {
web_server.client().stop();
web_server.stop();
addLog(LOG_LEVEL_INFO, F("Webserver: stop"));
}