[store_yaml] Use memcpy_P on ESP8266, std::memcpy elsewhere

Byte-by-byte `progmem_read_byte` for a 512-byte chunk does 512 aligned
32-bit flash reads + shifts on ESP8266. Switching to `memcpy_P` lets the
SDK do bulk aligned-flash copies. Other platforms get a plain
`std::memcpy` since their `PROGMEM` is a no-op and the blob lives in
normal address space.

`memcpy_P` is only available on ESP8266 (via `<pgmspace.h>`), so the
implementation is platform-gated; both paths boil down to a one-call
copy.
This commit is contained in:
J. Nick Koston
2026-05-15 22:36:15 -07:00
parent cd2c1014f3
commit a9ec101631
+13 -4
View File
@@ -3,6 +3,10 @@
#ifdef USE_STORE_YAML
#include "esphome/core/log.h"
#include <cstring>
#ifdef USE_ESP8266
#include <pgmspace.h>
#endif
namespace esphome::store_yaml {
@@ -23,10 +27,15 @@ void StoreYamlComponent::dump_config() {
}
void StoreYamlComponent::read_chunk(size_t pos, uint8_t *dst, size_t len) const {
const uint8_t *src = this->data_ + pos;
for (size_t i = 0; i < len; i++) {
dst[i] = progmem_read_byte(&src[i]);
}
#ifdef USE_ESP8266
// ESP8266 needs `memcpy_P` for aligned bulk flash reads; the byte-by-byte
// `progmem_read_byte` loop would otherwise emit ~4x as many flash accesses.
memcpy_P(dst, this->data_ + pos, len);
#else
// PROGMEM is a no-op everywhere else and the data lives in normal address
// space, so a plain `std::memcpy` is correct and the fast path.
std::memcpy(dst, this->data_ + pos, len);
#endif
}
} // namespace esphome::store_yaml