diff --git a/pio-scripts/dynarray.py b/pio-scripts/dynarray.py new file mode 100644 index 000000000..c8c1e6d2c --- /dev/null +++ b/pio-scripts/dynarray.py @@ -0,0 +1,12 @@ +# Add a section to the linker script to store our dynamic arrays +# This is implemented as a pio post-script to ensure that our extra linker +# script fragments are processed last, after the base platform scripts have +# been loaded and all sections defined. +Import("env") + +if env.get("PIOPLATFORM") == "espressif8266": + # Use a shim on this platform so we can share the same output blocks + # names as used by later platforms (ESP32) + env.Append(LINKFLAGS=["-Ttools/esp8266_rodata.ld"]) + +env.Append(LINKFLAGS=["-Ttools/dynarray.ld"]) diff --git a/pio-scripts/validate_modules.py b/pio-scripts/validate_modules.py index d63b609ac..b002af40b 100644 --- a/pio-scripts/validate_modules.py +++ b/pio-scripts/validate_modules.py @@ -41,7 +41,7 @@ def check_map_file_objects(map_file: list[str], dirs: Iterable[str]) -> set[str] def count_usermod_objects(map_file: list[str]) -> int: """ Returns the number of usermod objects in the usermod list """ # Count the number of entries in the usermods table section - return len([x for x in map_file if ".dtors.tbl.usermods.1" in x]) + return len([x for x in map_file if ".dynarray.usermods.1" in x]) def validate_map_file(source, target, env): diff --git a/platformio.ini b/platformio.ini index 60dedd473..29949d33c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -135,6 +135,7 @@ extra_scripts = pre:pio-scripts/set_metadata.py post:pio-scripts/output_bins.py post:pio-scripts/strip-floats.py + post:pio-scripts/dynarray.py pre:pio-scripts/user_config_copy.py pre:pio-scripts/load_usermods.py pre:pio-scripts/build_ui.py diff --git a/tools/dynarray.ld b/tools/dynarray.ld new file mode 100644 index 000000000..2c81217d3 --- /dev/null +++ b/tools/dynarray.ld @@ -0,0 +1,9 @@ +/* Linker script fragment to add dynamic array section to binary */ +SECTIONS +{ + .dynarray : + { + . = ALIGN(4); + KEEP(*(SORT_BY_INIT_PRIORITY(.dynarray.*))) + } > default_rodata_seg +} diff --git a/tools/esp8266_rodata.ld b/tools/esp8266_rodata.ld new file mode 100644 index 000000000..0cb27df6d --- /dev/null +++ b/tools/esp8266_rodata.ld @@ -0,0 +1,2 @@ +/* Linker script fragment to shim ESP8266 section name to newer ESP32 standards */ +REGION_ALIAS("default_rodata_seg", iram1_0_seg) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 1c0b5a7a0..e6a2112cd 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -381,7 +381,7 @@ namespace UsermodManager { }; // Register usermods by building a static list via a linker section -#define REGISTER_USERMOD(x) Usermod* const um_##x __attribute__((__section__(".dtors.tbl.usermods.1"), used)) = &x +#define REGISTER_USERMOD(x) Usermod* const um_##x __attribute__((__section__(".dynarray.usermods.1"), used)) = &x //usermod.cpp void userSetup(); diff --git a/wled00/um_manager.cpp b/wled00/um_manager.cpp index 647757ad6..2cefcdf34 100644 --- a/wled00/um_manager.cpp +++ b/wled00/um_manager.cpp @@ -10,8 +10,8 @@ // We stick them in the '.dtors' segment because it's always included by the linker scripts // even though it never gets called. Who calls exit() in an embedded program anyways? // If someone ever does, though, it'll explode as these aren't function pointers. -static Usermod * const _usermod_table_begin[0] __attribute__((__section__(".dtors.tbl.usermods.0"), unused)) = {}; -static Usermod * const _usermod_table_end[0] __attribute__((__section__(".dtors.tbl.usermods.99"), unused)) = {}; +static Usermod * const _usermod_table_begin[0] __attribute__((__section__(".dynarray.usermods.0"), unused)) = {}; +static Usermod * const _usermod_table_end[0] __attribute__((__section__(".dynarray.usermods.99"), unused)) = {}; static size_t getCount() { return &_usermod_table_end[0] - &_usermod_table_begin[0];