mirror of
https://github.com/esphome/esphome.git
synced 2026-09-15 09:08:41 +00:00
libretiny: clean up stale comments and tighten patch_linker script
- hal.h: collapse the four-way USE_LIBRETINY_VARIANT_BK72* guard into USE_BK72XX. - libretiny/__init__.py: drop the stale reference to growing .itcm from 4.5 kB to 8.5 kB; BK72xx no longer gets any .ld patching. - patch_linker.py.script: hoist the duplicated "import subprocess" to the top, pull the fallback IRAM_ATTR symbols out into a module-level frozenset, and split the ELF scan into a helper so _post_link is just the print logic.
This commit is contained in:
@@ -468,16 +468,14 @@ async def component_to_code(config):
|
||||
build_src_flags += " -Os"
|
||||
cg.add_platformio_option("build_src_flags", build_src_flags)
|
||||
# IRAM_ATTR on LibreTiny expands to section(".sram.text") on families
|
||||
# where executable RAM is available (see esphome/core/hal.h). This pre-
|
||||
# link hook rewrites the processed .ld files in the build dir so that
|
||||
# section lands in each family's executable RAM output section:
|
||||
# - BK7231N: grow .itcm from 4.5 kB to 8.5 kB (steal from .tcm) and
|
||||
# inject KEEP(*(.sram.text*)) into .itcm.code.
|
||||
# where the ISR-during-flash race is real (see esphome/core/hal.h). This
|
||||
# pre-link hook routes that section into each family's executable RAM:
|
||||
# - LN882H: inject KEEP(*(.sram.text*)) into .flash_copysection.
|
||||
# - RTL8710B: inject KEEP(*(.sram.text*)) into .image2.ram.text.
|
||||
# - RTL8720C: no-op (stock linker already consumes *(.sram.text*)).
|
||||
# BK7231T/Q/7251 have no executable RAM region; their SDK disables IRQ
|
||||
# + FIQ around flash writes, so IRAM_ATTR is left a no-op on them.
|
||||
# BK72xx (all variants) is no-op: the Beken SDK wraps every flash write
|
||||
# in GLOBAL_INT_DISABLE() so no ISR can fire during a flash stall; the
|
||||
# race IRAM_ATTR guards against cannot occur.
|
||||
cg.add_platformio_option("extra_scripts", ["pre:patch_linker.py"])
|
||||
# dummy version code
|
||||
cg.add_define("USE_ARDUINO_VERSION_CODE", cg.RawExpression("VERSION_CODE(0, 0, 0)"))
|
||||
|
||||
@@ -3,6 +3,7 @@ Import("env") # noqa
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
# ESPHome marks ISR code IRAM_ATTR, which on LibreTiny expands to
|
||||
# section(".sram.text") (see esphome/core/hal.h). Each family's linker script
|
||||
@@ -122,46 +123,50 @@ def _pre_link(target, source, env):
|
||||
_patch_build_dir(_patchers, env.subst("$BUILD_DIR"))
|
||||
|
||||
|
||||
def _post_link(target, source, env):
|
||||
"""Print where IRAM_ATTR ended up so users can confirm at a glance."""
|
||||
nm = env.subst("$NM") or "arm-none-eabi-nm"
|
||||
elf = env.subst("$BUILD_DIR/${PROGNAME}.elf")
|
||||
if not os.path.isfile(elf):
|
||||
return
|
||||
# Well-known ESPHome IRAM_ATTR symbols used as a fallback on RTL8720C, where
|
||||
# we cannot inject the __esphome_sram_text_start/end markers.
|
||||
_FALLBACK_IRAM_SYMBOLS = frozenset({
|
||||
"_ZN7esphome21wake_loop_any_contextEv",
|
||||
"_ZN7esphome17wake_loop_isrsafeEPl",
|
||||
"_ZN7esphome9Component28enable_loop_soon_any_contextEv",
|
||||
})
|
||||
|
||||
|
||||
def _collect_iram_symbols(nm, elf):
|
||||
"""Return (start, end, fallback_addresses) for the IRAM_ATTR payload."""
|
||||
try:
|
||||
import subprocess
|
||||
out = subprocess.check_output([nm, "--defined-only", elf], text=True)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
return
|
||||
return None, None, []
|
||||
start = end = None
|
||||
sample = []
|
||||
fallback = []
|
||||
for line in out.splitlines():
|
||||
parts = line.split(maxsplit=2)
|
||||
if len(parts) != 3:
|
||||
continue
|
||||
addr, _kind, name = parts
|
||||
addr_str, _kind, name = parts
|
||||
if name == "__esphome_sram_text_start":
|
||||
start = int(addr, 16)
|
||||
start = int(addr_str, 16)
|
||||
elif name == "__esphome_sram_text_end":
|
||||
end = int(addr, 16)
|
||||
elif name in (
|
||||
"_ZN7esphome21wake_loop_any_contextEv",
|
||||
"_ZN7esphome17wake_loop_isrsafeEPl",
|
||||
"_ZN7esphome9Component28enable_loop_soon_any_contextEv",
|
||||
):
|
||||
sample.append((int(addr, 16), name))
|
||||
header = "ESPHome: IRAM_ATTR placement summary ({}):".format(_variant)
|
||||
end = int(addr_str, 16)
|
||||
elif name in _FALLBACK_IRAM_SYMBOLS:
|
||||
fallback.append(int(addr_str, 16))
|
||||
return start, end, fallback
|
||||
|
||||
|
||||
def _post_link(target, source, env):
|
||||
"""Print where IRAM_ATTR ended up so users can confirm at a glance."""
|
||||
elf = env.subst("$BUILD_DIR/${PROGNAME}.elf")
|
||||
if not os.path.isfile(elf):
|
||||
return
|
||||
start, end, fallback = _collect_iram_symbols(env.subst("$NM"), elf)
|
||||
print("ESPHome: IRAM_ATTR placement summary ({}):".format(_variant))
|
||||
if start is not None and end is not None:
|
||||
print(header)
|
||||
print(" .sram.text: {} bytes at 0x{:08x} - 0x{:08x}".format(end - start, start, end))
|
||||
elif sample:
|
||||
print(header)
|
||||
sample.sort()
|
||||
lo = sample[0][0]
|
||||
hi = sample[-1][0]
|
||||
elif fallback:
|
||||
lo, hi = min(fallback), max(fallback)
|
||||
print(" IRAM symbols at 0x{:08x} - 0x{:08x} (approx {} bytes)".format(lo, hi, hi - lo))
|
||||
else:
|
||||
print(header)
|
||||
print(" no IRAM_ATTR symbols found in the ELF")
|
||||
|
||||
|
||||
|
||||
+6
-8
@@ -56,10 +56,11 @@
|
||||
#include <freertos/task.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBRETINY_VARIANT_BK7231N) || defined(USE_LIBRETINY_VARIANT_BK7231T) || \
|
||||
defined(USE_LIBRETINY_VARIANT_BK7231Q) || defined(USE_LIBRETINY_VARIANT_BK7251)
|
||||
#ifdef USE_BK72XX
|
||||
// Declared in the Beken FreeRTOS port (portmacro.h) and built in ARM mode so
|
||||
// it is callable from Thumb code via interworking.
|
||||
// it is callable from Thumb code via interworking. The MRS CPSR instruction
|
||||
// is ARM-only and user code here may be built in Thumb, so in_isr_context()
|
||||
// defers to this port helper on BK72xx instead of reading CPSR inline.
|
||||
extern "C" uint32_t platform_is_in_interrupt_context(void);
|
||||
#endif
|
||||
|
||||
@@ -79,11 +80,8 @@ __attribute__((always_inline)) inline bool in_isr_context() {
|
||||
uint32_t ipsr;
|
||||
__asm__ volatile("mrs %0, ipsr" : "=r"(ipsr));
|
||||
return ipsr != 0;
|
||||
#elif defined(USE_LIBRETINY_VARIANT_BK7231N) || defined(USE_LIBRETINY_VARIANT_BK7231T) || \
|
||||
defined(USE_LIBRETINY_VARIANT_BK7231Q) || defined(USE_LIBRETINY_VARIANT_BK7251)
|
||||
// BK72xx is ARM968E-S (ARM9). The MRS CPSR instruction is ARM-only, and
|
||||
// user code here may be built in Thumb mode. Defer to the FreeRTOS port
|
||||
// helper declared above (compiled in ARM mode by the SDK).
|
||||
#elif defined(USE_BK72XX)
|
||||
// BK72xx is ARM968E-S (ARM9); see extern declaration above.
|
||||
return platform_is_in_interrupt_context() != 0;
|
||||
#elif defined(USE_LIBRETINY)
|
||||
// Cortex-M (AmebaZ, AmebaZ2, LN882H). IPSR is the active exception number;
|
||||
|
||||
Reference in New Issue
Block a user