[esp8266] Derive the native image header flash size from the linker script (#19961)

This commit is contained in:
J. Nick Koston
2026-10-01 00:50:40 +02:00
committed by GitHub
parent 568c1ae494
commit 6f5d7475f0
4 changed files with 106 additions and 8 deletions
+55 -1
View File
@@ -21,12 +21,18 @@ from esphome.arduino8266.framework import InstalledPaths, toolchain_tool
from esphome.build_gen import arduino8266
from esphome.build_gen.arduino8266 import (
_defines_flags,
_elf2bin_flash_size,
_flag_defines,
_flash_size_str,
_resolve_build_config,
get_flash_ld_path,
)
from esphome.components.esp8266.boards import BOARDS, ESP8266_BOARD_BUILD
from esphome.components.esp8266.boards import (
BOARDS,
ESP8266_BOARD_BUILD,
KEY_FLASH_SIZE,
board_ld_script,
)
from esphome.components.esp8266.build_surgery import RATETABLE_RULE
from esphome.components.esp8266.const import KEY_BOARD, KEY_ESP8266, KEY_SCANF_FLOAT
import esphome.config_validation as cv
@@ -747,6 +753,54 @@ def test_flash_size_str() -> None:
assert _flash_size_str(512 * 1024) == "512K"
def test_elf2bin_flash_size() -> None:
"""The image-header size follows the ldscript filename like PlatformIO,
falling back to board_upload.maximum_size and then the board table."""
assert _elf2bin_flash_size("esp8285", "eagle.flash.2m.ld") == "2M"
assert _elf2bin_flash_size("esp01", "eagle.flash.512k.ld") == "512K"
assert _elf2bin_flash_size("nodemcuv2", "eagle.flash.4m1m.ld") == "4M"
# The testing-mode prefix still matches (search, not match)
assert _elf2bin_flash_size("esp8285", "testing_eagle.flash.2m.ld") == "2M"
# Custom ldscript name: board_upload.maximum_size wins over the board
CORE.platformio_options["board_upload.maximum_size"] = "2097152"
assert _elf2bin_flash_size("esp8285", "custom.ld") == "2M"
del CORE.platformio_options["board_upload.maximum_size"]
assert _elf2bin_flash_size("esp8285", "custom.ld") == "1M"
@pytest.mark.parametrize("bad", ["2MB", "3145728", "-1"])
def test_elf2bin_flash_size_rejects_bad_maximum_size(bad: str) -> None:
"""A non-numeric or unsupported board_upload.maximum_size fails by name
instead of a ValueError or a late elf2bin choices error."""
CORE.platformio_options["board_upload.maximum_size"] = bad
with pytest.raises(EsphomeError, match="board_upload.maximum_size"):
_elf2bin_flash_size("esp8285", "custom.ld")
def test_elf2bin_flash_size_default_matches_board_table() -> None:
"""Without an ldscript override, every board's own ldscript parses to
the board-table size, so the emitted --flash_size is unchanged."""
for board, entry in BOARDS.items():
assert _elf2bin_flash_size(board, board_ld_script(entry)) == _flash_size_str(
entry[KEY_FLASH_SIZE]
), board
def test_write_project_flash_size_follows_ldscript_override(
tmp_path: Path,
) -> None:
"""An ldscript overriding the board's flash size drives the image header
too (the Athom shape: esp8285 with eagle.flash.2m.ld). A 1M header over
a 2M layout clamps the chip below the OTA scratch area and bricks OTA."""
paths = _make_framework(tmp_path)
(paths.framework / "variants" / "esp8285").mkdir()
CORE.data[KEY_ESP8266][KEY_BOARD] = "esp8285"
CORE.platformio_options["board_build.ldscript"] = "eagle.flash.2m.ld"
content = _write_ninja(paths)
assert "--flash_size 2M" in content
assert "eagle.flash.2m.ld" in content
def test_write_project_testing_mode(tmp_path: Path) -> None:
paths = _make_framework(tmp_path)
CORE.testing_mode = True
+13
View File
@@ -1341,6 +1341,8 @@ async def test_add_platformio_options_native_idf(
"lib_ignore": "libsodium",
"upload_speed": "115200",
"board_build.f_flash": "80000000L",
# Silently dropped on arduino only; warns here
"board_upload.flash_size": "2MB",
}
)
@@ -1351,6 +1353,9 @@ async def test_add_platformio_options_native_idf(
# nothing else lands in platformio_options on the native toolchain.
assert CORE.platformio_options == {"lib_ignore": ["libsodium"]}
assert "esphome->platformio_options->board_build.f_flash is ignored" in caplog.text
assert (
"esphome->platformio_options->board_upload.flash_size is ignored" in caplog.text
)
assert "upload_speed" not in caplog.text
# build_flags has a first-class esphome equivalent, so it is deprecated.
# lib_deps/lib_ignore are kept as valid platformio_options (no warning).
@@ -1464,13 +1469,21 @@ async def test_add_platformio_options_native_arduino(
"board_build.ldscript": ["eagle.flash.2m.ld", "eagle.flash.4m2m.ld"],
"board_build.filesystem": "littlefs",
"upload_speed": "115200",
# The Athom shape: maximum_size is the elf2bin fallback,
# flash_size is dropped silently (PlatformIO never reads it)
"board_upload.maximum_size": "2097152",
"board_upload.flash_size": "2MB",
}
)
assert CORE.platformio_options["board_build.f_cpu"] == "160000000L"
assert CORE.platformio_options["board_build.ldscript"] == "eagle.flash.4m2m.ld"
assert CORE.platformio_options["board_upload.maximum_size"] == "2097152"
assert "board_upload.flash_size" not in CORE.platformio_options
assert "board_build.f_cpu is ignored" not in caplog.text
assert "board_build.ldscript is ignored" not in caplog.text
assert "board_upload.maximum_size is ignored" not in caplog.text
assert "board_upload.flash_size is ignored" not in caplog.text
assert (
"esphome->platformio_options->board_build.filesystem is ignored" in caplog.text
)