From e66fcde7e3889cd6ae515c7dec6f7437715f8c64 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:14:58 +0200 Subject: [PATCH] robot tbeam cache error fix Co-authored-by: Copilot --- src/platform/esp32/IramMemcpy.c | 42 +++++++++++++++++++++++++++++ src/platform/esp32/IramMemset.c | 42 +++++++++++++++++++++++++++++ variants/esp32/tbeam/platformio.ini | 7 +++++ 3 files changed, 91 insertions(+) create mode 100644 src/platform/esp32/IramMemcpy.c create mode 100644 src/platform/esp32/IramMemset.c diff --git a/src/platform/esp32/IramMemcpy.c b/src/platform/esp32/IramMemcpy.c new file mode 100644 index 000000000..898f1bdc6 --- /dev/null +++ b/src/platform/esp32/IramMemcpy.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "esp_attr.h" + +#ifdef ESP32_FORCE_IRAM_MEMSET + +/* + * T-Beam/classic ESP32 boot workaround + * ------------------------------------ + * During early flash operations the ESP32 disables cache, but some IRAM flash + * code paths still reach libc memcpy/memset. If those resolve to flash-resident + * implementations, startup can panic with cache-disabled access errors. + * + * We wrap memcpy/memset for the T-Beam environment. Fast path uses the + * normal libc routines when cache is enabled; slow path uses IRAM-safe byte + * loops when cache is disabled. + */ + +extern void *__real_memcpy(void *dst, const void *src, size_t n); + +static inline bool IRAM_ATTR cache_is_enabled(void) +{ + return (*(volatile uint32_t *)0x3FF00040u) & (1u << 3); +} + +extern void *IRAM_ATTR __wrap_memcpy(void *dst, const void *src, size_t n) +{ + if (cache_is_enabled()) { + return __real_memcpy(dst, src, n); + } + + uint8_t *d = (uint8_t *)dst; + const uint8_t *s = (const uint8_t *)src; + while (n--) { + *d++ = *s++; + } + return dst; +} + +#endif diff --git a/src/platform/esp32/IramMemset.c b/src/platform/esp32/IramMemset.c new file mode 100644 index 000000000..66d74d8bc --- /dev/null +++ b/src/platform/esp32/IramMemset.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "esp_attr.h" + +#ifdef ESP32_FORCE_IRAM_MEMSET + +/* + * T-Beam/classic ESP32 boot workaround + * ------------------------------------ + * During early flash operations the ESP32 disables cache, but some IRAM flash + * code paths still reach libc memcpy/memset. If those resolve to flash-resident + * implementations, startup can panic with cache-disabled access errors. + * + * We wrap memcpy/memset for the T-Beam environment. Fast path uses the + * normal libc routines when cache is enabled; slow path uses IRAM-safe byte + * loops when cache is disabled. + */ + +extern void *__real_memset(void *dst, int c, size_t n); + +static inline bool IRAM_ATTR cache_is_enabled(void) +{ + return (*(volatile uint32_t *)0x3FF00040u) & (1u << 3); +} + +extern void *IRAM_ATTR __wrap_memset(void *dst, int c, size_t n) +{ + if (cache_is_enabled()) { + return __real_memset(dst, c, n); + } + + uint8_t *ptr = (uint8_t *)dst; + const uint8_t fill = (uint8_t)c; + while (n--) { + *ptr++ = fill; + } + return dst; +} + +#endif \ No newline at end of file diff --git a/variants/esp32/tbeam/platformio.ini b/variants/esp32/tbeam/platformio.ini index 96e9879ce..4371dcc63 100644 --- a/variants/esp32/tbeam/platformio.ini +++ b/variants/esp32/tbeam/platformio.ini @@ -16,8 +16,15 @@ board_check = true build_flags = ${esp32_base.build_flags} -D TBEAM_V10 -I variants/esp32/tbeam + -D ESP32_FORCE_IRAM_MEMSET + -Wl,--wrap=memset + -Wl,--wrap=memcpy upload_speed = 921600 +custom_sdkconfig = + ${esp32_base.custom_sdkconfig} + CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y + [env:tbeam-displayshield] extends = env:tbeam board_level = extra