diff --git a/esphome/components/rp2040/preferences.cpp b/esphome/components/rp2040/preferences.cpp index cbf2b00641..e84033bc52 100644 --- a/esphome/components/rp2040/preferences.cpp +++ b/esphome/components/rp2040/preferences.cpp @@ -8,7 +8,6 @@ #include "preferences.h" #include -#include #include "esphome/core/helpers.h" #include "esphome/core/log.h" @@ -25,6 +24,9 @@ static bool s_flash_dirty = false; // NOLINT(cppcoreguidelines-avoid-no static const uint32_t RP2040_FLASH_STORAGE_SIZE = 512; +// Stack buffer size for preferences - covers virtually all real-world preferences without heap allocation +static constexpr size_t PREF_BUFFER_SIZE = 64; + extern "C" uint8_t _EEPROM_start; template uint8_t calculate_crc(It first, It last, uint32_t type) { @@ -42,12 +44,14 @@ class RP2040PreferenceBackend : public ESPPreferenceBackend { uint32_t type = 0; bool save(const uint8_t *data, size_t len) override { - std::vector buffer; - buffer.resize(len + 1); - memcpy(buffer.data(), data, len); - buffer[buffer.size() - 1] = calculate_crc(buffer.begin(), buffer.end() - 1, type); + const size_t buffer_size = len + 1; + SmallBufferWithHeapFallback buffer_alloc(buffer_size); + uint8_t *buffer = buffer_alloc.get(); - for (uint32_t i = 0; i < len + 1; i++) { + memcpy(buffer, data, len); + buffer[len] = calculate_crc(buffer, buffer + len, type); + + for (size_t i = 0; i < buffer_size; i++) { uint32_t j = offset + i; if (j >= RP2040_FLASH_STORAGE_SIZE) return false; @@ -60,22 +64,23 @@ class RP2040PreferenceBackend : public ESPPreferenceBackend { return true; } bool load(uint8_t *data, size_t len) override { - std::vector buffer; - buffer.resize(len + 1); + const size_t buffer_size = len + 1; + SmallBufferWithHeapFallback buffer_alloc(buffer_size); + uint8_t *buffer = buffer_alloc.get(); - for (size_t i = 0; i < len + 1; i++) { + for (size_t i = 0; i < buffer_size; i++) { uint32_t j = offset + i; if (j >= RP2040_FLASH_STORAGE_SIZE) return false; buffer[i] = s_flash_storage[j]; } - uint8_t crc = calculate_crc(buffer.begin(), buffer.end() - 1, type); - if (buffer[buffer.size() - 1] != crc) { + uint8_t crc = calculate_crc(buffer, buffer + len, type); + if (buffer[len] != crc) { return false; } - memcpy(data, buffer.data(), len); + memcpy(data, buffer, len); return true; } };