Reduce stack usage

This commit is contained in:
Theo Arends 2024-12-10 11:39:37 +01:00
parent bdf880cf84
commit 3c51793d5c
4 changed files with 31 additions and 12 deletions

View File

@ -18,7 +18,7 @@ All notable changes to this project will be documented in this file.
- Command `SetOption162 1` to disable adding export energy to energy today (#22578) - Command `SetOption162 1` to disable adding export energy to energy today (#22578)
- ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600) - ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 (#22600)
- Support for Sonoff POWCT Energy Export Active (#22596) - Support for Sonoff POWCT Energy Export Active (#22596)
- Improved auto-selection of LED hardware support (RMT, SPI) - Improved auto-selection of LED hardware support (RMT, SPI) (#22618)
### Breaking Changed ### Breaking Changed
- ESP32 ArtNet switches from GRB to RGB encoding (#22556) - ESP32 ArtNet switches from GRB to RGB encoding (#22556)

View File

@ -1148,6 +1148,8 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms = nullptr); bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms = nullptr);
bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms) { bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void), const uint8_t *synonyms) {
SHOW_FREE_MEM(PSTR("DecodeCommand"));
GetTextIndexed(XdrvMailbox.command, CMDSZ, 0, haystack); // Get prefix if available GetTextIndexed(XdrvMailbox.command, CMDSZ, 0, haystack); // Get prefix if available
int prefix_length = strlen(XdrvMailbox.command); int prefix_length = strlen(XdrvMailbox.command);
if (prefix_length) { if (prefix_length) {
@ -2680,9 +2682,7 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa
} }
snprintf_P(TasmotaGlobal.log_buffer, LOG_BUFFER_SIZE, PSTR("%s%c%c%s%s%s%s\1"), snprintf_P(TasmotaGlobal.log_buffer, LOG_BUFFER_SIZE, PSTR("%s%c%c%s%s%s%s\1"),
TasmotaGlobal.log_buffer, TasmotaGlobal.log_buffer_pointer++, '0'+loglevel, mxtime, log_data, log_data_payload, log_data_retained); TasmotaGlobal.log_buffer, TasmotaGlobal.log_buffer_pointer++, '0'+loglevel, mxtime, log_data, log_data_payload, log_data_retained);
if (too_long) { if (too_long) { free(too_long); }
free(too_long);
}
TasmotaGlobal.log_buffer_pointer &= 0xFF; TasmotaGlobal.log_buffer_pointer &= 0xFF;
if (!TasmotaGlobal.log_buffer_pointer) { if (!TasmotaGlobal.log_buffer_pointer) {
TasmotaGlobal.log_buffer_pointer++; // Index 0 is not allowed as it is the end of char string TasmotaGlobal.log_buffer_pointer++; // Index 0 is not allowed as it is the end of char string

View File

@ -702,15 +702,14 @@ void MqttPublishLoggingAsync(bool refresh) {
void MqttPublishPayload(const char* topic, const char* payload, uint32_t binary_length, bool retained) { void MqttPublishPayload(const char* topic, const char* payload, uint32_t binary_length, bool retained) {
// Publish <topic> payload string or binary when binary_length set with optional retained // Publish <topic> payload string or binary when binary_length set with optional retained
SHOW_FREE_MEM(PSTR("MqttPublishPayload"));
SHOW_FREE_MEM(PSTR("MqttPublish"));
bool binary_data = (binary_length > 0); bool binary_data = (binary_length > 0);
if (!binary_data) { if (!binary_data) {
binary_length = strlen(payload); binary_length = strlen(payload);
} }
if (Settings->flag4.mqtt_no_retain) { // SetOption104 - Disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant if (Settings->flag4.mqtt_no_retain) { // SetOption104 - Disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant
retained = false; // Some brokers don't support retained, they will disconnect if received retained = false; // Some brokers don't support retained, they will disconnect if received
} }
@ -794,14 +793,30 @@ void MqttPublishPayloadPrefixTopic_P(uint32_t prefix, const char* subtopic, cons
prefix 5 = stat using subtopic or RESULT prefix 5 = stat using subtopic or RESULT
prefix 6 = tele using subtopic or RESULT prefix 6 = tele using subtopic or RESULT
*/ */
char romram[64]; SHOW_FREE_MEM(PSTR("MqttPublishPayloadPrefixTopic_P"));
/*
char romram[64]; // Claim 64 bytes from 4k stack
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings->flag.mqtt_response) ? S_RSLT_RESULT : subtopic); // SetOption4 - Switch between MQTT RESULT or COMMAND snprintf_P(romram, sizeof(romram), ((prefix > 3) && !Settings->flag.mqtt_response) ? S_RSLT_RESULT : subtopic); // SetOption4 - Switch between MQTT RESULT or COMMAND
UpperCase(romram, romram); UpperCase(romram, romram);
prefix &= 3; prefix &= 3;
char stopic[TOPSZ]; char stopic[TOPSZ]; // Claim TOPSZ bytes from 4k stack
GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, romram); GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, romram);
MqttPublishPayload(stopic, payload, binary_length, retained); MqttPublishPayload(stopic, payload, binary_length, retained);
*/
// Reduce important stack usage by 200 bytes but adding 52 bytes code
char *romram = (char*)malloc(64); // Claim 64 bytes from 20k heap
strcpy_P(romram, ((prefix > 3) && !Settings->flag.mqtt_response) ? S_RSLT_RESULT : subtopic);
UpperCase(romram, romram);
prefix &= 3;
char *htopic = (char*)malloc(TOPSZ); // Claim TOPSZ bytes from 16k heap
GetTopic_P(htopic, prefix, TasmotaGlobal.mqtt_topic, romram);
char stopic[strlen_P(htopic) +1]; // Claim only strlen_P bytes from 4k stack
strcpy_P(stopic, htopic);
free(htopic); // Free 16k heap from TOPSZ bytes
free(romram); // Free 16k heap from 64 bytes
MqttPublishPayload(stopic, payload, binary_length, retained);
#if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT) #if defined(USE_MQTT_AWS_IOT) || defined(USE_MQTT_AWS_IOT_LIGHT)
if ((prefix > 0) && (Settings->flag4.awsiot_shadow) && (Mqtt.connected)) { // placeholder for SetOptionXX if ((prefix > 0) && (Settings->flag4.awsiot_shadow) && (Mqtt.connected)) { // placeholder for SetOptionXX
@ -857,6 +872,8 @@ void MqttPublishPayloadPrefixTopicRulesProcess_P(uint32_t prefix, const char* su
void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained) { void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained) {
// Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained // Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained
SHOW_FREE_MEM(PSTR("MqttPublishPrefixTopic_P"));
MqttPublishPayloadPrefixTopic_P(prefix, subtopic, ResponseData(), 0, retained); MqttPublishPayloadPrefixTopic_P(prefix, subtopic, ResponseData(), 0, retained);
} }
@ -868,6 +885,8 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic) {
void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) { void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) {
// Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained // Publish <prefix>/<device>/<RESULT or <subtopic>> default ResponseData string with optional retained
// then process rules // then process rules
SHOW_FREE_MEM(PSTR("MqttPublishPrefixTopicRulesProcess_P"));
MqttPublishPrefixTopic_P(prefix, subtopic, retained); MqttPublishPrefixTopic_P(prefix, subtopic, retained);
XdrvRulesProcess(0); XdrvRulesProcess(0);
} }

View File

@ -1105,10 +1105,10 @@ bool XdrvRulesProcess(bool teleperiod) {
#ifdef USE_DEBUG_DRIVER #ifdef USE_DEBUG_DRIVER
void ShowFreeMem(const char *where) { void ShowFreeMem(const char *where) {
char stemp[30]; char *XdrvMailboxData = XdrvMailbox.data;
snprintf_P(stemp, sizeof(stemp), where); XdrvMailbox.data = (char*)where;
XdrvMailbox.data = stemp;
XdrvCall(FUNC_FREE_MEM); XdrvCall(FUNC_FREE_MEM);
XdrvMailbox.data = XdrvMailboxData;
} }
#endif #endif