[nrf52] Fake a larger flash in testing mode (#20439)

This commit is contained in:
J. Nick Koston
2026-10-09 08:36:42 -10:00
committed by GitHub
parent 52b274c5e8
commit daea315b13
3 changed files with 72 additions and 4 deletions
+37 -1
View File
@@ -12,6 +12,7 @@ from esphome.build_helpers import pch
from esphome.build_helpers.ccache import resolve_ccache_path
import esphome.codegen as cg
from esphome.components.zephyr import (
Section,
add_extra_script,
copy_files as zephyr_copy_files,
zephyr_add_overlay,
@@ -126,11 +127,37 @@ def set_core_data(config: ConfigType) -> ConfigType:
CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK] = KEY_ZEPHYR
if config[KEY_BOOTLOADER] in BOOTLOADER_CONFIG:
zephyr_add_pm_static(BOOTLOADER_CONFIG[config[KEY_BOOTLOADER]])
sections = BOOTLOADER_CONFIG[config[KEY_BOOTLOADER]]
if CORE.testing_mode:
sections = _testing_mode_sections(sections)
zephyr_add_pm_static(sections)
return config
# In testing mode, fake a larger flash to allow linking grouped component
# tests. The nRF52840 has 1 MB and a mcumgr OTA config halves the app slot,
# which an openthread config alone fills; CI images are never flashed.
NRF52840_FLASH_SIZE = 0x100000
TESTING_FLASH_SIZE = 0x400000
def _testing_mode_sections(sections: list[Section]) -> list[Section]:
"""Move a bootloader pinned to the end of the real flash to the end of the
faked one, so the partition manager still sees a single gap for the app."""
return [
Section(
section.name,
section.address + TESTING_FLASH_SIZE - NRF52840_FLASH_SIZE,
section.size,
section.region,
)
if section.end_address == NRF52840_FLASH_SIZE
else section
for section in sections
]
_TOOLCHAINS = (Toolchain.PLATFORMIO, Toolchain.SDK_NRF)
_resolve_toolchain = cv.resolve_toolchain("nRF52", _TOOLCHAINS, Toolchain.SDK_NRF)
@@ -381,6 +408,15 @@ async def to_code(config: ConfigType) -> None:
zephyr_setup_preferences()
zephyr_to_code(config)
if CORE.testing_mode:
zephyr_add_overlay(
f"""
&flash0 {{
reg = <0x0 {TESTING_FLASH_SIZE:#x}>;
}};
"""
)
if dfu_config := config.get(CONF_DFU):
CORE.add_job(_dfu_to_code, dfu_config)
framework_ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
@@ -13,6 +13,7 @@ from esphome.components.zephyr import (
from esphome.components.zephyr.const import (
BOOTLOADER_MCUBOOT,
KEY_BOOTLOADER,
KEY_PM_STATIC,
KEY_SYSBUILD,
)
from esphome.components.zephyr_ble_server import request_ble_l2cap_mtu
@@ -207,10 +208,11 @@ async def to_code(config: ConfigType) -> None:
bootloader = zephyr_data()[KEY_BOOTLOADER]
if bootloader != BOOTLOADER_MCUBOOT:
sections = BOOTLOADER_CONFIG[bootloader]
# Derive partition addresses from the SoftDevice and bootloader sections so
# that the DTS flash map matches what the Partition Manager produces:
# Derive partition addresses from the SoftDevice and bootloader sections
# registered with the Partition Manager (moved in testing mode) so that
# the DTS flash map matches what it produces:
# MCUboot sits immediately after the SoftDevice, then slot0, then slot1.
sections = zephyr_data()[KEY_PM_STATIC]
mcuboot_size = 0x9000
sd_end = next(s.address + s.size for s in sections if "SoftDevice" in s.name)
bl_start = next(s.address for s in sections if "Adafruit" in s.name)
@@ -0,0 +1,30 @@
"""Testing mode fakes a larger flash so grouped component tests link."""
from esphome.components import nrf52
from esphome.components.nrf52.boards import BOOTLOADER_CONFIG
from esphome.components.nrf52.const import BOOTLOADER_ADAFRUIT_NRF52_SD140_V7
from esphome.components.zephyr import Section
def test_testing_mode_sections_move_only_the_bootloader() -> None:
"""The bootloader pinned to the end of flash follows the faked end; the
SoftDevice at the start stays."""
sections = nrf52._testing_mode_sections(
BOOTLOADER_CONFIG[BOOTLOADER_ADAFRUIT_NRF52_SD140_V7]
)
assert [(s.name, s.address, s.size) for s in sections] == [
("SoftDevice", 0x0, 0x27000),
(
"Adafruit_nRF52_Bootloader",
nrf52.TESTING_FLASH_SIZE - 0xC000,
0xC000,
),
]
assert sections[1].end_address == nrf52.TESTING_FLASH_SIZE
def test_testing_mode_sections_leave_unpinned_sections() -> None:
section = Section("other", 0x50000, 0x1000, "flash_primary")
assert nrf52._testing_mode_sections([section]) == [section]