From 00cc9e44b61b2ae8b275dbdc35479e0149f2389f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 15 Jan 2026 10:38:24 -1000 Subject: [PATCH] [analyze_memory] Fix ELF section mapping for RTL87xx and LN882X platforms (#13213) --- esphome/analyze_memory/const.py | 40 ++++++++++++++++++++++++++--- script/determine-jobs.py | 17 +++++++++--- tests/script/test_determine_jobs.py | 22 ++++++++++++++++ 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/esphome/analyze_memory/const.py b/esphome/analyze_memory/const.py index 9933bd77fd..aadc6a231c 100644 --- a/esphome/analyze_memory/const.py +++ b/esphome/analyze_memory/const.py @@ -9,10 +9,44 @@ ESPHOME_COMPONENT_PATTERN = re.compile(r"esphome::([a-zA-Z0-9_]+)::") # Maps standard section names to their various platform-specific variants # Note: Order matters! More specific patterns (.bss) must come before general ones (.dram) # because ESP-IDF uses names like ".dram0.bss" which would match ".dram" otherwise +# +# Platform-specific sections: +# - ESP8266/ESP32: .iram*, .dram* +# - LibreTiny RTL87xx: .xip.code_* (flash), .ram.code_* (RAM) +# - LibreTiny BK7231: .itcm.code (fast RAM), .vectors (interrupt vectors) +# - LibreTiny LN882X: .flash_text, .flash_copy* (flash code) SECTION_MAPPING = { - ".text": frozenset([".text", ".iram"]), - ".rodata": frozenset([".rodata"]), - ".bss": frozenset([".bss"]), # Must be before .data to catch ".dram0.bss" + ".text": frozenset( + [ + ".text", + ".iram", + # LibreTiny RTL87xx XIP (eXecute In Place) flash code + ".xip.code", + # LibreTiny RTL87xx RAM code + ".ram.code_text", + # LibreTiny BK7231 fast RAM code and vectors + ".itcm.code", + ".vectors", + # LibreTiny LN882X flash code + ".flash_text", + ".flash_copy", + ] + ), + ".rodata": frozenset( + [ + ".rodata", + # LibreTiny RTL87xx read-only data in RAM + ".ram.code_rodata", + ] + ), + # .bss patterns - must be before .data to catch ".dram0.bss" + ".bss": frozenset( + [ + ".bss", + # LibreTiny LN882X BSS + ".bss_ram", + ] + ), ".data": frozenset([".data", ".dram"]), } diff --git a/script/determine-jobs.py b/script/determine-jobs.py index a61c9bf08d..7ecbfb225e 100755 --- a/script/determine-jobs.py +++ b/script/determine-jobs.py @@ -90,6 +90,8 @@ class Platform(StrEnum): ESP32_S2_IDF = "esp32-s2-idf" ESP32_S3_IDF = "esp32-s3-idf" BK72XX_ARD = "bk72xx-ard" # LibreTiny BK7231N + RTL87XX_ARD = "rtl87xx-ard" # LibreTiny RTL8720x + LN882X_ARD = "ln882x-ard" # LibreTiny LN882x RP2040_ARD = "rp2040-ard" # Raspberry Pi Pico @@ -122,8 +124,8 @@ PLATFORM_SPECIFIC_COMPONENTS = frozenset( # fastest build times, most sensitive to code size changes # 3. ESP32 IDF - Primary ESP32 platform, most representative of modern ESPHome # 4-6. Other ESP32 variants - Less commonly used but still supported -# 7. BK72XX - LibreTiny platform (good for detecting LibreTiny-specific changes) -# 8. RP2040 - Raspberry Pi Pico platform +# 7-9. LibreTiny platforms (BK72XX, RTL87XX, LN882X) - good for detecting LibreTiny-specific changes +# 10. RP2040 - Raspberry Pi Pico platform MEMORY_IMPACT_PLATFORM_PREFERENCE = [ Platform.ESP32_C6_IDF, # ESP32-C6 IDF (newest, supports Thread/Zigbee) Platform.ESP8266_ARD, # ESP8266 Arduino (most memory constrained, fastest builds) @@ -132,6 +134,8 @@ MEMORY_IMPACT_PLATFORM_PREFERENCE = [ Platform.ESP32_S2_IDF, # ESP32-S2 IDF Platform.ESP32_S3_IDF, # ESP32-S3 IDF Platform.BK72XX_ARD, # LibreTiny BK7231N + Platform.RTL87XX_ARD, # LibreTiny RTL8720x + Platform.LN882X_ARD, # LibreTiny LN882x Platform.RP2040_ARD, # Raspberry Pi Pico ] @@ -411,6 +415,8 @@ def _detect_platform_hint_from_filename(filename: str) -> Platform | None: - wifi_component_esp8266.cpp, *_esp8266.h -> ESP8266_ARD - *_esp32*.cpp -> ESP32 IDF (generic) - *_libretiny.cpp, *_bk72*.* -> BK72XX (LibreTiny) + - *_rtl87*.* -> RTL87XX (LibreTiny Realtek) + - *_ln882*.* -> LN882X (LibreTiny Lightning) - *_pico.cpp, *_rp2040.* -> RP2040_ARD Args: @@ -444,7 +450,12 @@ def _detect_platform_hint_from_filename(filename: str) -> Platform | None: if "esp32" in filename_lower: return Platform.ESP32_IDF - # LibreTiny (via 'libretiny' pattern or BK72xx-specific files) + # LibreTiny platforms (check specific variants before generic libretiny) + # Check specific variants first to handle paths like libretiny/wifi_rtl87xx.cpp + if "rtl87" in filename_lower: + return Platform.RTL87XX_ARD + if "ln882" in filename_lower: + return Platform.LN882X_ARD if "libretiny" in filename_lower or "bk72" in filename_lower: return Platform.BK72XX_ARD diff --git a/tests/script/test_determine_jobs.py b/tests/script/test_determine_jobs.py index bd20cb3e21..52025513a8 100644 --- a/tests/script/test_determine_jobs.py +++ b/tests/script/test_determine_jobs.py @@ -1472,6 +1472,24 @@ def test_detect_memory_impact_config_runs_at_component_limit(tmp_path: Path) -> determine_jobs.Platform.BK72XX_ARD, ), ("esphome/components/ble/ble_bk72xx.cpp", determine_jobs.Platform.BK72XX_ARD), + # RTL87xx (LibreTiny Realtek) detection + ( + "tests/components/logger/test.rtl87xx-ard.yaml", + determine_jobs.Platform.RTL87XX_ARD, + ), + ( + "esphome/components/libretiny/wifi_rtl87xx.cpp", + determine_jobs.Platform.RTL87XX_ARD, + ), + # LN882x (LibreTiny Lightning) detection + ( + "tests/components/logger/test.ln882x-ard.yaml", + determine_jobs.Platform.LN882X_ARD, + ), + ( + "esphome/components/libretiny/wifi_ln882x.cpp", + determine_jobs.Platform.LN882X_ARD, + ), # RP2040 / Raspberry Pi Pico detection ("esphome/components/gpio/gpio_rp2040.cpp", determine_jobs.Platform.RP2040_ARD), ("esphome/components/wifi/wifi_rp2040.cpp", determine_jobs.Platform.RP2040_ARD), @@ -1501,6 +1519,10 @@ def test_detect_memory_impact_config_runs_at_component_limit(tmp_path: Path) -> "esp32_in_name", "libretiny", "bk72xx", + "rtl87xx_test_yaml", + "rtl87xx_wifi", + "ln882x_test_yaml", + "ln882x_wifi", "rp2040_gpio", "rp2040_wifi", "pico_i2c",