diff --git a/builder/frameworks/base.py b/builder/frameworks/base.py index e7ef82d..c9b3b71 100644 --- a/builder/frameworks/base.py +++ b/builder/frameworks/base.py @@ -16,6 +16,8 @@ family: Family = env["FAMILY_OBJ"] # Parse custom options env.ParseCustomOptions(platform) +# Parse custom flash layout +env.ParseCustomFlashLayout(platform, board) # Add flash layout C defines env.AddFlashLayout(board) # Write custom header options @@ -23,7 +25,7 @@ env.ApplyCustomOptions(platform) # Export board manifest for ltchiptool env.ExportBoardData(board) # Print information about versions and custom options -env.PrintInfo(platform) +env.PrintInfo(platform, board) # TODO remove include path prepending ("!<...>") # Move common core sources (env.AddCoreSources()) and Arduino libs diff --git a/builder/utils/env.py b/builder/utils/env.py index 700ebc1..c9f53a4 100644 --- a/builder/utils/env.py +++ b/builder/utils/env.py @@ -89,7 +89,11 @@ def env_configure( return family -def env_print_info(env: Environment, platform: PlatformBase): +def env_print_info( + env: Environment, + platform: PlatformBase, + board: PlatformBoardConfig, +): TAB = " " * 4 def dump(k, v, indent=""): @@ -114,10 +118,15 @@ def env_print_info(env: Environment, platform: PlatformBase): print("CUSTOM OPTIONS:") for k, v in sorted(platform.custom_opts.items()): dump(k, v) + # Print custom flash layout + if env.get("FLASH_IS_CUSTOM", False): + print("CUSTOM FLASH LAYOUT:") + for k, v in board.get("flash").items(): + print(f" - {k}: {v}") def env_parse_custom_options(env: Environment, platform: PlatformBase): - opts = platform.custom_opts.get("options", None) + opts: dict = platform.custom_opts.get("options", None) if not opts: return headers = { diff --git a/builder/utils/flash.py b/builder/utils/flash.py index b28c0a7..af521e5 100644 --- a/builder/utils/flash.py +++ b/builder/utils/flash.py @@ -2,14 +2,52 @@ import re from os.path import isfile, join +from typing import Dict from ltchiptool.util.fileio import chext +from platformio.platform.base import PlatformBase from platformio.platform.board import PlatformBoardConfig from SCons.Script import DefaultEnvironment, Environment env: Environment = DefaultEnvironment() +def env_parse_custom_flash_layout( + env: Environment, + platform: PlatformBase, + board: PlatformBoardConfig, +): + opts: dict = platform.custom_opts.get("flash", None) + if not opts: + return + flash_layout: dict = board.get("flash") + + # find all default partitions + partitions: Dict[str, int] = {} + flash_size = 0 + for name, layout in flash_layout.items(): + (offset, _, length) = layout.partition("+") + offset = int(offset, 16) + length = int(length, 16) + partitions[name] = offset + flash_size = max(flash_size, offset + length) + + # set custom offsets + for name, offset in opts.items(): + offset = int(offset, 0) + partitions[name] = offset + + # recalculate partition sizes + flash_layout = {} + partitions = sorted(partitions.items(), key=lambda p: p[1]) + for i, (name, offset) in enumerate(partitions): + end = partitions[i + 1][1] if i + 1 < len(partitions) else flash_size + length = end - offset + flash_layout[name] = f"0x{offset:06X}+0x{length:X}" + board.manifest["flash"] = flash_layout + env["FLASH_IS_CUSTOM"] = True + + def env_add_flash_layout(env: Environment, board: PlatformBoardConfig): flash_layout: dict = board.get("flash") if flash_layout: @@ -74,5 +112,6 @@ def env_generate_linker_script(env: Environment, board: PlatformBoardConfig, nam env.Prepend(LIBPATH=["${BUILD_DIR}"]) +env.AddMethod(env_parse_custom_flash_layout, "ParseCustomFlashLayout") env.AddMethod(env_add_flash_layout, "AddFlashLayout") env.AddMethod(env_generate_linker_script, "GenerateLinkerScript")