[core] Support adding custom board JSON, pass it to ltchiptool

This commit is contained in:
Kuba Szczodrzyński
2023-03-25 20:10:15 +01:00
parent 4c1ab20ba4
commit 0e84e08a18
9 changed files with 55 additions and 24 deletions

View File

@@ -535,7 +535,7 @@ image_app_rblh = "${BUILD_DIR}/image_${MCULC}_app.${FLASH_RBL_OFFSET}.rblh"
image_ota_rbl = "${BUILD_DIR}/image_${MCULC}_app.ota.rbl"
env.Replace(
# linker command (encryption + packaging)
LINK="${LTCHIPTOOL} link2bin ${VARIANT} '' ''",
LINK="${LTCHIPTOOL} link2bin ${BOARD_JSON} '' ''",
# UF2OTA input list
UF2OTA=[
# app binary image (enc+crc) for flasher

View File

@@ -296,7 +296,7 @@ image_ota1 = "${BUILD_DIR}/image_ota1.${FLASH_OTA1_OFFSET}.bin"
image_ota2 = "${BUILD_DIR}/image_ota2.${FLASH_OTA2_OFFSET}.bin"
env.Replace(
# linker command (dual .bin outputs)
LINK="${LTCHIPTOOL} link2bin ${VARIANT} xip1 xip2",
LINK="${LTCHIPTOOL} link2bin ${BOARD_JSON} xip1 xip2",
# UF2OTA input list
UF2OTA=[
# same OTA images for flasher and device

View File

@@ -14,10 +14,16 @@ board: PlatformBoardConfig = env.BoardConfig()
platform: PlatformBase = env.PioPlatform()
family: Family = env["FAMILY_OBJ"]
# Parse custom options
env.ParseCustomOptions(platform)
# Add flash layout C defines
env.AddFlashLayout(board)
# Write custom header options
env.ApplyCustomOptions(platform)
# Export board manifest for ltchiptool
env.ExportBoardData(board)
# Print information about versions and custom options
env.PrintInfo(platform)
# Apply custom header options
env.ApplyCustomOptions(platform)
# TODO remove include path prepending ("!<...>")
# Move common core sources (env.AddCoreSources()) and Arduino libs

View File

@@ -49,10 +49,6 @@ env.Replace(
# Environment variables, include paths, etc.
env.ConfigureEnvironment(platform, board)
# Flash layout defines
env.AddFlashLayout(board)
# Parse custom options
env.ParseCustomOptions(platform)
# Family builders details:
# - call env.AddLibrary("lib name", "base dir", [sources]) to add lib sources
@@ -72,7 +68,7 @@ env.ParseCustomOptions(platform)
# Framework builder (base.py/arduino.py) is executed in BuildProgram()
# Force including the base framework in case no other is specified
if not env.get("PIOFRAMEWORK"):
if "nobuild" not in COMMAND_LINE_TARGETS and not env.get("PIOFRAMEWORK"):
env.SConscript("frameworks/base.py")
#

View File

@@ -96,7 +96,7 @@ def env_print_info(env: Environment, platform: PlatformBase):
k = k.replace("#", ".")
if isinstance(v, dict):
print(f"{indent} - {k}:")
for k, v in v.items():
for k, v in sorted(v.items()):
dump(k, v, indent + TAB)
elif isinstance(v, list):
print(f"{indent} - {k}:")
@@ -112,7 +112,7 @@ def env_print_info(env: Environment, platform: PlatformBase):
# Print custom platformio.ini options
if platform.custom_opts:
print("CUSTOM OPTIONS:")
for k, v in platform.custom_opts.items():
for k, v in sorted(platform.custom_opts.items()):
dump(k, v)

View File

@@ -17,10 +17,12 @@ def env_add_flash_layout(env: Environment, board):
for name, layout in flash_layout.items():
name = name.upper()
(offset, _, length) = layout.partition("+")
defines[f"FLASH_{name}_OFFSET"] = offset
defines[f"FLASH_{name}_LENGTH"] = length
offset = int(offset, 16)
length = int(length, 16)
defines[f"FLASH_{name}_OFFSET"] = f"0x{offset:06X}"
defines[f"FLASH_{name}_LENGTH"] = f"0x{length:06X}"
fal_items += f"FAL_PART_TABLE_ITEM({name.lower()},{name})"
flash_size = max(flash_size, int(offset, 16) + int(length, 16))
flash_size = max(flash_size, offset + length)
defines["FLASH_LENGTH"] = f"0x{flash_size:06X}"
# for "root" partition
defines["FLASH_ROOT_OFFSET"] = "0x000000"

View File

@@ -1,9 +1,11 @@
# Copyright (c) Kuba Szczodrzyński 2022-06-02.
import json
from datetime import datetime
from os.path import basename, join, normpath
from platformio.platform.base import PlatformBase
from platformio.platform.board import PlatformBoardConfig
from SCons.Script import Builder, DefaultEnvironment, Environment
env: Environment = DefaultEnvironment()
@@ -43,13 +45,12 @@ def env_uf2ota(env: Environment, *args, **kwargs):
cmd = [
"@${LTCHIPTOOL} uf2 write",
*output_opts,
"--family ${FAMILY_SHORT_NAME}",
"--board ${VARIANT}",
"--board ${BOARD_JSON}",
f"--lt-version {lt_version}",
f'--fw "{project_name}:{project_version}"',
f"--date {int(now.timestamp())}",
"--legacy",
*env["UF2OTA"],
*(f'"{arg}"' for arg in env["UF2OTA"]),
]
for output in outputs:
@@ -72,6 +73,13 @@ def env_flash_write(env: Environment):
return []
def env_export_board_data(env: Environment, board: PlatformBoardConfig):
output = join("${BUILD_DIR}", "board.json")
with open(env.subst(output), "w") as f:
json.dump(board.manifest, f, indent="\t")
env["BOARD_JSON"] = output
env.Append(
BUILDERS=dict(
BuildUF2OTA=Builder(
@@ -80,3 +88,4 @@ env.Append(
)
)
env.AddMethod(env_flash_write, "GetLtchiptoolWriteFlags")
env.AddMethod(env_export_board_data, "ExportBoardData")

View File

@@ -30,6 +30,12 @@ Explicit is better than implicit.
- write OpenOCD flashers, using uf2ota library + FAL for partitions (in ltchiptool repository)
### Development
- write Contributor's Guide
- export LT cores in an Arduino IDE-compatible format (automatically - GitHub Actions)
- consider using precompiled SDK blobs for improved build speed (especially on e.g. Raspberry Pi)
### Serial
- configuration of RX/TX pins

View File

@@ -2,11 +2,12 @@
import importlib
import json
import os
import platform
import sys
from os import system
from os.path import dirname
from typing import Dict
from typing import Dict, List
import click
from platformio.debug.config.base import DebugConfigBase
@@ -114,7 +115,10 @@ class LibretuyaPlatform(PlatformBase):
def print(self, *args, **kwargs):
if not self.verbose:
return
print(*args, **kwargs)
print(f"platform.py({os.getpid()}):", *args, **kwargs)
def custom(self, key: str) -> object:
return self.custom_opts.get(key, None)
def get_package_spec(self, name, version=None):
# make PlatformIO detach existing package versions instead of overwriting
@@ -124,12 +128,13 @@ class LibretuyaPlatform(PlatformBase):
spec._name_is_custom = False
return spec
def configure_default_packages(self, options, targets):
def configure_default_packages(self, options: dict, targets: List[str]):
from ltchiptool.util.dict import RecursiveDict
self.verbose = (
"-v" in sys.argv or "--verbose" in sys.argv or "PIOVERBOSE=1" in sys.argv
)
self.print(f"configure_default_packages(targets={targets})")
pioframework = options.get("pioframework") or ["base"]
if not pioframework:
@@ -272,10 +277,8 @@ class LibretuyaPlatform(PlatformBase):
return super().configure_default_packages(options, targets)
def custom(self, key: str) -> object:
return self.custom_opts.get(key, None)
def get_boards(self, id_=None):
self.print(f"get_boards(id_={id_})")
result = PlatformBase.get_boards(self, id_)
if not result:
return result
@@ -289,6 +292,14 @@ class LibretuyaPlatform(PlatformBase):
def update_board(self, board: PlatformBoardConfig):
if "_base" in board:
board._manifest = ltchiptool.Board.get_data(board._manifest)
board._manifest.pop("_base")
if self.custom("board"):
from ltchiptool.util.dict import merge_dicts
with open(self.custom("board"), "r") as f:
custom_board = json.load(f)
board._manifest = merge_dicts(board._manifest, custom_board)
family = board.get("build.family")
family = ltchiptool.Family.get(short_name=family)
@@ -310,7 +321,8 @@ class LibretuyaPlatform(PlatformBase):
if "custom" not in debug["tools"]:
debug["tools"]["custom"] = {}
init = debug.get("gdb_init", [])
init += ["set mem inaccessible-by-default off"]
if "set mem inaccessible-by-default off" not in init:
init += ["set mem inaccessible-by-default off"]
for link in protocols:
if link == "openocd":