Reduce static RAM usage (#2140)

This commit is contained in:
Oxan van Leeuwen 2021-08-23 10:43:54 +02:00 committed by GitHub
parent 2f33cd2db5
commit d71996e58d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 82 deletions

View file

@ -8,26 +8,23 @@ namespace light {
static const char *const TAG = "light";
static const char *color_mode_to_human(ColorMode color_mode) {
switch (color_mode) {
case ColorMode::UNKNOWN:
return "Unknown";
case ColorMode::WHITE:
return "White";
case ColorMode::COLOR_TEMPERATURE:
return "Color temperature";
case ColorMode::COLD_WARM_WHITE:
return "Cold/warm white";
case ColorMode::RGB:
return "RGB";
case ColorMode::RGB_WHITE:
return "RGBW";
case ColorMode::RGB_COLD_WARM_WHITE:
return "RGB + cold/warm white";
case ColorMode::RGB_COLOR_TEMPERATURE:
return "RGB + color temperature";
default:
return "";
}
if (color_mode == ColorMode::UNKNOWN)
return "Unknown";
if (color_mode == ColorMode::WHITE)
return "White";
if (color_mode == ColorMode::COLOR_TEMPERATURE)
return "Color temperature";
if (color_mode == ColorMode::COLD_WARM_WHITE)
return "Cold/warm white";
if (color_mode == ColorMode::RGB)
return "RGB";
if (color_mode == ColorMode::RGB_WHITE)
return "RGBW";
if (color_mode == ColorMode::RGB_COLD_WARM_WHITE)
return "RGB + cold/warm white";
if (color_mode == ColorMode::RGB_COLOR_TEMPERATURE)
return "RGB + color temperature";
return "";
}
void LightCall::perform() {

View file

@ -178,28 +178,29 @@ void OTAComponent::handle_() {
#endif
if (!Update.begin(ota_size, U_FLASH)) {
uint8_t error = Update.getError();
StreamString ss;
Update.printError(ss);
#ifdef ARDUINO_ARCH_ESP8266
if (ss.indexOf("Invalid bootstrapping") != -1) {
if (error == UPDATE_ERROR_BOOTSTRAP) {
error_code = OTA_RESPONSE_ERROR_INVALID_BOOTSTRAPPING;
goto error;
}
if (ss.indexOf("new Flash config wrong") != -1 || ss.indexOf("new Flash config wsong") != -1) {
if (error == UPDATE_ERROR_NEW_FLASH_CONFIG) {
error_code = OTA_RESPONSE_ERROR_WRONG_NEW_FLASH_CONFIG;
goto error;
}
if (ss.indexOf("Flash config wrong real") != -1 || ss.indexOf("Flash config wsong real") != -1) {
if (error == UPDATE_ERROR_FLASH_CONFIG) {
error_code = OTA_RESPONSE_ERROR_WRONG_CURRENT_FLASH_CONFIG;
goto error;
}
if (ss.indexOf("Not Enough Space") != -1) {
if (error == UPDATE_ERROR_SPACE) {
error_code = OTA_RESPONSE_ERROR_ESP8266_NOT_ENOUGH_SPACE;
goto error;
}
#endif
#ifdef ARDUINO_ARCH_ESP32
if (ss.indexOf("Bad Size Given") != -1) {
if (error == UPDATE_ERROR_SIZE) {
error_code = OTA_RESPONSE_ERROR_ESP32_NOT_ENOUGH_SPACE;
goto error;
}

View file

@ -56,9 +56,8 @@ void SNTPComponent::loop() {
if (!time.is_valid())
return;
char buf[128];
time.strftime(buf, sizeof(buf), "%c");
ESP_LOGD(TAG, "Synchronized time: %s", buf);
ESP_LOGD(TAG, "Synchronized time: %d-%d-%d %d:%d:%d", time.year, time.month, time.day_of_month, time.hour,
time.minute, time.second);
this->time_sync_callback_.call();
this->has_time_ = true;
}

View file

@ -35,9 +35,8 @@ void RealTimeClock::synchronize_epoch_(uint32_t epoch) {
}
auto time = this->now();
char buf[128];
time.strftime(buf, sizeof(buf), "%c");
ESP_LOGD(TAG, "Synchronized time: %s", buf);
ESP_LOGD(TAG, "Synchronized time: %d-%d-%d %d:%d:%d", time.year, time.month, time.day_of_month, time.hour,
time.minute, time.second);
this->time_sync_callback_.call();
}

View file

@ -366,65 +366,75 @@ const char *get_op_mode_str(uint8_t mode) {
return "UNKNOWN";
}
}
// Note that this method returns PROGMEM strings, so use LOG_STR_ARG() to access them.
const char *get_disconnect_reason_str(uint8_t reason) {
/* If this were one big switch statement, GCC would generate a lookup table for it. However, the values of the
* REASON_* constants aren't continuous, and GCC will fill in the gap with the default value -- wasting 4 bytes of RAM
* per entry. As there's ~175 default entries, this wastes 700 bytes of RAM.
*/
if (reason <= REASON_CIPHER_SUITE_REJECTED) { // This must be the last constant with a value <200
switch (reason) {
case REASON_AUTH_EXPIRE:
return LOG_STR("Auth Expired");
case REASON_AUTH_LEAVE:
return LOG_STR("Auth Leave");
case REASON_ASSOC_EXPIRE:
return LOG_STR("Association Expired");
case REASON_ASSOC_TOOMANY:
return LOG_STR("Too Many Associations");
case REASON_NOT_AUTHED:
return LOG_STR("Not Authenticated");
case REASON_NOT_ASSOCED:
return LOG_STR("Not Associated");
case REASON_ASSOC_LEAVE:
return LOG_STR("Association Leave");
case REASON_ASSOC_NOT_AUTHED:
return LOG_STR("Association not Authenticated");
case REASON_DISASSOC_PWRCAP_BAD:
return LOG_STR("Disassociate Power Cap Bad");
case REASON_DISASSOC_SUPCHAN_BAD:
return LOG_STR("Disassociate Supported Channel Bad");
case REASON_IE_INVALID:
return LOG_STR("IE Invalid");
case REASON_MIC_FAILURE:
return LOG_STR("Mic Failure");
case REASON_4WAY_HANDSHAKE_TIMEOUT:
return LOG_STR("4-Way Handshake Timeout");
case REASON_GROUP_KEY_UPDATE_TIMEOUT:
return LOG_STR("Group Key Update Timeout");
case REASON_IE_IN_4WAY_DIFFERS:
return LOG_STR("IE In 4-Way Handshake Differs");
case REASON_GROUP_CIPHER_INVALID:
return LOG_STR("Group Cipher Invalid");
case REASON_PAIRWISE_CIPHER_INVALID:
return LOG_STR("Pairwise Cipher Invalid");
case REASON_AKMP_INVALID:
return LOG_STR("AKMP Invalid");
case REASON_UNSUPP_RSN_IE_VERSION:
return LOG_STR("Unsupported RSN IE version");
case REASON_INVALID_RSN_IE_CAP:
return LOG_STR("Invalid RSN IE Cap");
case REASON_802_1X_AUTH_FAILED:
return LOG_STR("802.1x Authentication Failed");
case REASON_CIPHER_SUITE_REJECTED:
return LOG_STR("Cipher Suite Rejected");
}
}
switch (reason) {
case REASON_AUTH_EXPIRE:
return "Auth Expired";
case REASON_AUTH_LEAVE:
return "Auth Leave";
case REASON_ASSOC_EXPIRE:
return "Association Expired";
case REASON_ASSOC_TOOMANY:
return "Too Many Associations";
case REASON_NOT_AUTHED:
return "Not Authenticated";
case REASON_NOT_ASSOCED:
return "Not Associated";
case REASON_ASSOC_LEAVE:
return "Association Leave";
case REASON_ASSOC_NOT_AUTHED:
return "Association not Authenticated";
case REASON_DISASSOC_PWRCAP_BAD:
return "Disassociate Power Cap Bad";
case REASON_DISASSOC_SUPCHAN_BAD:
return "Disassociate Supported Channel Bad";
case REASON_IE_INVALID:
return "IE Invalid";
case REASON_MIC_FAILURE:
return "Mic Failure";
case REASON_4WAY_HANDSHAKE_TIMEOUT:
return "4-Way Handshake Timeout";
case REASON_GROUP_KEY_UPDATE_TIMEOUT:
return "Group Key Update Timeout";
case REASON_IE_IN_4WAY_DIFFERS:
return "IE In 4-Way Handshake Differs";
case REASON_GROUP_CIPHER_INVALID:
return "Group Cipher Invalid";
case REASON_PAIRWISE_CIPHER_INVALID:
return "Pairwise Cipher Invalid";
case REASON_AKMP_INVALID:
return "AKMP Invalid";
case REASON_UNSUPP_RSN_IE_VERSION:
return "Unsupported RSN IE version";
case REASON_INVALID_RSN_IE_CAP:
return "Invalid RSN IE Cap";
case REASON_802_1X_AUTH_FAILED:
return "802.1x Authentication Failed";
case REASON_CIPHER_SUITE_REJECTED:
return "Cipher Suite Rejected";
case REASON_BEACON_TIMEOUT:
return "Beacon Timeout";
return LOG_STR("Beacon Timeout");
case REASON_NO_AP_FOUND:
return "AP Not Found";
return LOG_STR("AP Not Found");
case REASON_AUTH_FAIL:
return "Authentication Failed";
return LOG_STR("Authentication Failed");
case REASON_ASSOC_FAIL:
return "Association Failed";
return LOG_STR("Association Failed");
case REASON_HANDSHAKE_TIMEOUT:
return "Handshake Failed";
return LOG_STR("Handshake Failed");
case REASON_UNSPECIFIED:
default:
return "Unspecified";
return LOG_STR("Unspecified");
}
}
@ -448,7 +458,7 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
ESP_LOGW(TAG, "Event: Disconnected ssid='%s' reason='Probe Request Unsuccessful'", buf);
} else {
ESP_LOGW(TAG, "Event: Disconnected ssid='%s' bssid=" LOG_SECRET("%s") " reason='%s'", buf,
format_mac_addr(it.bssid).c_str(), get_disconnect_reason_str(it.reason));
format_mac_addr(it.bssid).c_str(), LOG_STR_ARG(get_disconnect_reason_str(it.reason)));
}
break;
}

View file

@ -7,6 +7,7 @@
#include "WString.h"
#endif
#include "esphome/core/macros.h"
// avoid esp-idf redefining our macros
#include "esphome/core/esphal.h"
@ -162,4 +163,28 @@ int esp_idf_log_vprintf_(const char *format, va_list args); // NOLINT
#define ONOFF(b) ((b) ? "ON" : "OFF")
#define TRUEFALSE(b) ((b) ? "TRUE" : "FALSE")
#ifdef USE_STORE_LOG_STR_IN_FLASH
#define LOG_STR(s) PSTR(s)
// From Arduino 2.5 onwards, we can pass a PSTR() to printf(). For previous versions, emulate support
// by copying the message to a local buffer first. String length is limited to 63 characters.
// https://github.com/esp8266/Arduino/commit/6280e98b0360f85fdac2b8f10707fffb4f6e6e31
#include <core_version.h>
#if defined(ARDUINO_ARCH_ESP8266) && ARDUINO_VERSION_CODE < VERSION_CODE(2, 5, 0)
#define LOG_STR_ARG(s) \
({ \
char __buf[64]; \
__buf[63] = '\0'; \
strncpy_P(__buf, s, 63); \
__buf; \
})
#else
#define LOG_STR_ARG(s) (s)
#endif
#else
#define LOG_STR(s) (s)
#define LOG_STR_ARG(s) (s)
#endif
} // namespace esphome