fbt: initial blackmagic support (#1362)
* fbt: added separate script for Windows env setup; moved flash targets from firmware.scons to SConstruct; added Blackmagic support with automatic probe port resolution; added apps.c rebuild on any manifest.fam changes; fixed simultaneous flash & debug ops * fbt: added networked BlackmagicResolver mode; added `get_blackmagic` target for IDE integration * fbt: cleanup * fbt: docs update; fixed blackmagic lookup on certain usb hubs * fbt: removed explicit python serial port import * fbt: cleanup * fbt: raising exception on multiple serial blackmagic probes
This commit is contained in:
parent
793501d62d
commit
6b6ea44802
109
SConstruct
109
SConstruct
@ -28,15 +28,41 @@ SConscript("site_scons/cc.scons", exports={"ENV": coreenv})
|
|||||||
# Store root dir in environment for certain tools
|
# Store root dir in environment for certain tools
|
||||||
coreenv["ROOT_DIR"] = Dir(".")
|
coreenv["ROOT_DIR"] = Dir(".")
|
||||||
|
|
||||||
|
|
||||||
# Create a separate "dist" environment and add construction envs to it
|
# Create a separate "dist" environment and add construction envs to it
|
||||||
distenv = coreenv.Clone(
|
distenv = coreenv.Clone(
|
||||||
tools=["fbt_dist", "openocd"],
|
tools=["fbt_dist", "openocd", "blackmagic"],
|
||||||
GDBOPTS="-ex 'target extended-remote | ${OPENOCD} -c \"gdb_port pipe\" ${OPENOCD_OPTS}' "
|
OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"],
|
||||||
'-ex "set confirm off" ',
|
GDBOPTS_BASE=[
|
||||||
|
"-ex",
|
||||||
|
"target extended-remote ${GDBREMOTE}",
|
||||||
|
"-ex",
|
||||||
|
"set confirm off",
|
||||||
|
],
|
||||||
|
GDBOPTS_BLACKMAGIC=[
|
||||||
|
"-ex",
|
||||||
|
"monitor swdp_scan",
|
||||||
|
"-ex",
|
||||||
|
"monitor debug_bmp enable",
|
||||||
|
"-ex",
|
||||||
|
"attach 1",
|
||||||
|
"-ex",
|
||||||
|
"set mem inaccessible-by-default off",
|
||||||
|
],
|
||||||
|
GDBPYOPTS=[
|
||||||
|
"-ex",
|
||||||
|
"source debug/FreeRTOS/FreeRTOS.py",
|
||||||
|
"-ex",
|
||||||
|
"source debug/PyCortexMDebug/PyCortexMDebug.py",
|
||||||
|
"-ex",
|
||||||
|
"svd_load ${SVD_FILE}",
|
||||||
|
"-ex",
|
||||||
|
"compare-sections",
|
||||||
|
],
|
||||||
ENV=os.environ,
|
ENV=os.environ,
|
||||||
)
|
)
|
||||||
|
|
||||||
firmware_out = distenv.AddFwProject(
|
firmware_env = distenv.AddFwProject(
|
||||||
base_env=coreenv,
|
base_env=coreenv,
|
||||||
fw_type="firmware",
|
fw_type="firmware",
|
||||||
fw_env_key="FW_ENV",
|
fw_env_key="FW_ENV",
|
||||||
@ -44,7 +70,7 @@ firmware_out = distenv.AddFwProject(
|
|||||||
|
|
||||||
# If enabled, initialize updater-related targets
|
# If enabled, initialize updater-related targets
|
||||||
if GetOption("fullenv"):
|
if GetOption("fullenv"):
|
||||||
updater_out = distenv.AddFwProject(
|
updater_env = distenv.AddFwProject(
|
||||||
base_env=coreenv,
|
base_env=coreenv,
|
||||||
fw_type="updater",
|
fw_type="updater",
|
||||||
fw_env_key="UPD_ENV",
|
fw_env_key="UPD_ENV",
|
||||||
@ -72,19 +98,32 @@ if GetOption("fullenv"):
|
|||||||
|
|
||||||
selfupdate_dist = distenv.DistCommand(
|
selfupdate_dist = distenv.DistCommand(
|
||||||
"updater_package",
|
"updater_package",
|
||||||
(distenv["DIST_DEPENDS"], firmware_out["FW_RESOURCES"]),
|
(distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
|
||||||
DIST_EXTRA=dist_arguments,
|
DIST_EXTRA=dist_arguments,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Updater debug
|
# Updater debug
|
||||||
distenv.AddDebugTarget("updater_debug", updater_out, False)
|
distenv.PhonyTarget(
|
||||||
|
"updater_debug",
|
||||||
|
"${GDBPYCOM}",
|
||||||
|
source=updater_env["FW_ELF"],
|
||||||
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||||
|
)
|
||||||
|
|
||||||
|
distenv.PhonyTarget(
|
||||||
|
"updater_blackmagic",
|
||||||
|
"${GDBPYCOM}",
|
||||||
|
source=updater_env["FW_ELF"],
|
||||||
|
GDBOPTS=distenv.subst("$GDBOPTS_BLACKMAGIC"),
|
||||||
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||||
|
)
|
||||||
|
|
||||||
# Installation over USB & CLI
|
# Installation over USB & CLI
|
||||||
usb_update_package = distenv.UsbInstall(
|
usb_update_package = distenv.UsbInstall(
|
||||||
"#build/usbinstall.flag",
|
"#build/usbinstall.flag",
|
||||||
(
|
(
|
||||||
distenv["DIST_DEPENDS"],
|
distenv["DIST_DEPENDS"],
|
||||||
firmware_out["FW_RESOURCES"],
|
firmware_env["FW_RESOURCES"],
|
||||||
selfupdate_dist,
|
selfupdate_dist,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -104,15 +143,47 @@ copro_dist = distenv.CoproBuilder(
|
|||||||
)
|
)
|
||||||
distenv.Alias("copro_dist", copro_dist)
|
distenv.Alias("copro_dist", copro_dist)
|
||||||
|
|
||||||
|
firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env)
|
||||||
|
distenv.Alias("flash", firmware_flash)
|
||||||
|
|
||||||
|
firmware_bm_flash = distenv.PhonyTarget(
|
||||||
|
"flash_blackmagic",
|
||||||
|
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
|
||||||
|
source=firmware_env["FW_ELF"],
|
||||||
|
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
||||||
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||||
|
GDBFLASH=[
|
||||||
|
"-ex",
|
||||||
|
"load",
|
||||||
|
"-ex",
|
||||||
|
"quit",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
# Debugging firmware
|
# Debugging firmware
|
||||||
distenv.AddDebugTarget("debug", firmware_out)
|
firmware_debug = distenv.PhonyTarget(
|
||||||
|
"debug",
|
||||||
|
"${GDBPYCOM}",
|
||||||
|
source=firmware_env["FW_ELF"],
|
||||||
|
GDBOPTS="${GDBOPTS_BASE}",
|
||||||
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||||
|
)
|
||||||
|
distenv.Depends(firmware_debug, firmware_flash)
|
||||||
|
|
||||||
|
distenv.PhonyTarget(
|
||||||
|
"blackmagic",
|
||||||
|
"${GDBPYCOM}",
|
||||||
|
source=firmware_env["FW_ELF"],
|
||||||
|
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
|
||||||
|
GDBREMOTE="${BLACKMAGIC_ADDR}",
|
||||||
|
)
|
||||||
|
|
||||||
# Debug alien elf
|
# Debug alien elf
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"debug_other",
|
"debug_other",
|
||||||
"$GDBPYCOM",
|
"${GDBPYCOM}",
|
||||||
GDBPYOPTS=
|
GDBPYOPTS='-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
|
||||||
# '-ex "source ${ROOT_DIR.abspath}/debug/FreeRTOS/FreeRTOS.py" '
|
GDBREMOTE="${OPENOCD_GDB_PIPE}",
|
||||||
'-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" ',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Just start OpenOCD
|
# Just start OpenOCD
|
||||||
@ -125,11 +196,19 @@ distenv.PhonyTarget(
|
|||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"lint",
|
"lint",
|
||||||
"${PYTHON3} scripts/lint.py check ${LINT_SOURCES}",
|
"${PYTHON3} scripts/lint.py check ${LINT_SOURCES}",
|
||||||
LINT_SOURCES=firmware_out["LINT_SOURCES"],
|
LINT_SOURCES=firmware_env["LINT_SOURCES"],
|
||||||
)
|
)
|
||||||
|
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget(
|
||||||
"format",
|
"format",
|
||||||
"${PYTHON3} scripts/lint.py format ${LINT_SOURCES}",
|
"${PYTHON3} scripts/lint.py format ${LINT_SOURCES}",
|
||||||
LINT_SOURCES=firmware_out["LINT_SOURCES"],
|
LINT_SOURCES=firmware_env["LINT_SOURCES"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Find blackmagic probe
|
||||||
|
|
||||||
|
distenv.PhonyTarget(
|
||||||
|
"get_blackmagic",
|
||||||
|
"@echo $( ${BLACKMAGIC_ADDR} $)",
|
||||||
)
|
)
|
||||||
|
@ -34,7 +34,9 @@ FBT keeps track of internal dependencies, so you only need to build the highest-
|
|||||||
- `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded
|
- `debug` - build and flash firmware, then attach with gdb with firmware's .elf loaded
|
||||||
- `debug_updater` - attach gdb with updater's .elf loaded. _Requires `--with-updater` option_
|
- `debug_updater` - attach gdb with updater's .elf loaded. _Requires `--with-updater` option_
|
||||||
- `debug_other` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb.
|
- `debug_other` - attach gdb without loading any .elf. Allows to manually add external elf files with `add-symbol-file` in gdb.
|
||||||
|
- `blackmagic` - debug firmware with Blackmagic probe (WiFi dev board)
|
||||||
- `openocd` - just start OpenOCD
|
- `openocd` - just start OpenOCD
|
||||||
|
- `get_blackmagic` - output blackmagic address in gdb remote format. Useful for IDE integration
|
||||||
|
|
||||||
### Firmware targets
|
### Firmware targets
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ FBT keeps track of internal dependencies, so you only need to build the highest-
|
|||||||
- Check out `--extra-ext-apps` for force adding extra apps to external build
|
- Check out `--extra-ext-apps` for force adding extra apps to external build
|
||||||
- `firmware_snake_game_list`, etc - generate source + assembler listing for app's .elf
|
- `firmware_snake_game_list`, etc - generate source + assembler listing for app's .elf
|
||||||
- `flash`, `firmware_flash` - flash current version to attached device with OpenOCD over ST-Link
|
- `flash`, `firmware_flash` - flash current version to attached device with OpenOCD over ST-Link
|
||||||
|
- `flash_blackmagic` - flash current version to attached device with Blackmagic probe
|
||||||
- `firmware_cdb` - generate compilation database
|
- `firmware_cdb` - generate compilation database
|
||||||
- `firmware_all`, `updater_all` - build basic set of binaries
|
- `firmware_all`, `updater_all` - build basic set of binaries
|
||||||
- `firmware_list`, `updater_list` - generate source + assembler listing
|
- `firmware_list`, `updater_list` - generate source + assembler listing
|
||||||
|
1
fbt
1
fbt
@ -6,7 +6,6 @@ SCRIPTDIR="$( dirname -- "$0"; )";
|
|||||||
SCONS_EP=${SCRIPTDIR}/lib/scons/scripts/scons.py
|
SCONS_EP=${SCRIPTDIR}/lib/scons/scripts/scons.py
|
||||||
|
|
||||||
if [[ -d .git ]]; then
|
if [[ -d .git ]]; then
|
||||||
echo Updating git submodules
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
else # Not in a git repo
|
else # Not in a git repo
|
||||||
echo Not in a git repo, please clone with git clone --recursive
|
echo Not in a git repo, please clone with git clone --recursive
|
||||||
|
1
fbt.cmd
1
fbt.cmd
@ -3,7 +3,6 @@
|
|||||||
set SCONS_EP=%~dp0\lib\scons\scripts\scons.py
|
set SCONS_EP=%~dp0\lib\scons\scripts\scons.py
|
||||||
|
|
||||||
if exist ".git" (
|
if exist ".git" (
|
||||||
echo Updating git submodules
|
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -41,10 +41,24 @@ COPRO_STACK_BIN_DIR = posixpath.join(
|
|||||||
# Supported toolchain versions
|
# Supported toolchain versions
|
||||||
FBT_TOOLCHAIN_VERSIONS = (" 10.3.",)
|
FBT_TOOLCHAIN_VERSIONS = (" 10.3.",)
|
||||||
|
|
||||||
OPENOCD_OPTS = '-f interface/stlink.cfg -c "transport select hla_swd" -f debug/stm32wbx.cfg -c "stm32wbx.cpu configure -rtos auto" -c "init"'
|
OPENOCD_OPTS = [
|
||||||
|
"-f",
|
||||||
|
"interface/stlink.cfg",
|
||||||
|
"-c",
|
||||||
|
"transport select hla_swd",
|
||||||
|
"-f",
|
||||||
|
"debug/stm32wbx.cfg",
|
||||||
|
"-c",
|
||||||
|
"stm32wbx.cpu configure -rtos auto",
|
||||||
|
"-c",
|
||||||
|
"init",
|
||||||
|
]
|
||||||
|
|
||||||
SVD_FILE = "debug/STM32WB55_CM4.svd"
|
SVD_FILE = "debug/STM32WB55_CM4.svd"
|
||||||
|
|
||||||
|
# Look for blackmagic probe on serial ports
|
||||||
|
BLACKMAGIC = "auto"
|
||||||
|
|
||||||
FIRMWARE_APPS = {
|
FIRMWARE_APPS = {
|
||||||
"default": [
|
"default": [
|
||||||
"crypto_start",
|
"crypto_start",
|
||||||
|
@ -6,7 +6,7 @@ from fbt.util import link_dir
|
|||||||
|
|
||||||
# Building initial C environment for libs
|
# Building initial C environment for libs
|
||||||
env = ENV.Clone(
|
env = ENV.Clone(
|
||||||
tools=["compilation_db", "fwbin", "openocd", "fbt_apps"],
|
tools=["compilation_db", "fwbin", "fbt_apps"],
|
||||||
COMPILATIONDB_USE_ABSPATH=True,
|
COMPILATIONDB_USE_ABSPATH=True,
|
||||||
BUILD_DIR=fw_build_meta["build_dir"],
|
BUILD_DIR=fw_build_meta["build_dir"],
|
||||||
IS_BASE_FIRMWARE=fw_build_meta["type"] == "firmware",
|
IS_BASE_FIRMWARE=fw_build_meta["type"] == "firmware",
|
||||||
@ -139,6 +139,8 @@ apps_c = fwenv.ApplicationsC(
|
|||||||
"applications/applications.c",
|
"applications/applications.c",
|
||||||
Value(fwenv["APPS"]),
|
Value(fwenv["APPS"]),
|
||||||
)
|
)
|
||||||
|
# Adding dependency on manifest files so apps.c is rebuilt when any manifest is changed
|
||||||
|
fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", "applications"))
|
||||||
|
|
||||||
sources = [apps_c]
|
sources = [apps_c]
|
||||||
# Gather sources only from app folders from current configuration
|
# Gather sources only from app folders from current configuration
|
||||||
@ -235,7 +237,7 @@ AddPostAction(fwelf, Action("@$SIZECOM"))
|
|||||||
AddPostAction(fwelf, Action(link_latest_dir, None))
|
AddPostAction(fwelf, Action(link_latest_dir, None))
|
||||||
|
|
||||||
link_dir_command = fwenv["LINK_DIR_CMD"] = fwenv.PhonyTarget(
|
link_dir_command = fwenv["LINK_DIR_CMD"] = fwenv.PhonyTarget(
|
||||||
"${FIRMWARE_BUILD_CFG}" + "_latest",
|
fwenv.subst("${FIRMWARE_BUILD_CFG}_latest"),
|
||||||
Action(lambda target, source, env: link_elf_dir_as_latest(env, source[0]), None),
|
Action(lambda target, source, env: link_elf_dir_as_latest(env, source[0]), None),
|
||||||
source=fwelf,
|
source=fwelf,
|
||||||
)
|
)
|
||||||
@ -249,18 +251,6 @@ Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_dfu", fwdfu)
|
|||||||
fwdump = fwenv.ObjDump("${FIRMWARE_BUILD_CFG}")
|
fwdump = fwenv.ObjDump("${FIRMWARE_BUILD_CFG}")
|
||||||
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_list", fwdump)
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_list", fwdump)
|
||||||
|
|
||||||
# Additional FW-related pseudotargets
|
|
||||||
flash = fwenv["FW_FLASH"] = fwenv.OpenOCDFlash(
|
|
||||||
"#build/oocd-${FIRMWARE_BUILD_CFG}-flash.flag",
|
|
||||||
"${FIRMWARE_BUILD_CFG}",
|
|
||||||
OPENOCD_COMMAND='-c "program ${SOURCE.posix} reset exit ${IMAGE_BASE_ADDRESS}"',
|
|
||||||
)
|
|
||||||
if fwenv["FORCE"]:
|
|
||||||
fwenv.AlwaysBuild(flash)
|
|
||||||
fwenv.Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_flash", flash)
|
|
||||||
if fwenv["IS_BASE_FIRMWARE"]:
|
|
||||||
fwenv.Alias("flash", flash)
|
|
||||||
|
|
||||||
|
|
||||||
# Compile DB generation
|
# Compile DB generation
|
||||||
fwcdb = fwenv["FW_CDB"] = fwenv.CompilationDatabase("compile_commands.json")
|
fwcdb = fwenv["FW_CDB"] = fwenv.CompilationDatabase("compile_commands.json")
|
||||||
|
@ -162,6 +162,12 @@ vars.Add(
|
|||||||
default="",
|
default="",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
vars.Add(
|
||||||
|
"BLACKMAGIC",
|
||||||
|
help="Blackmagic probe location",
|
||||||
|
default="auto",
|
||||||
|
)
|
||||||
|
|
||||||
vars.Add(
|
vars.Add(
|
||||||
"UPDATE_SPLASH",
|
"UPDATE_SPLASH",
|
||||||
help="Directory name with slideshow frames to render after installing update package",
|
help="Directory name with slideshow frames to render after installing update package",
|
||||||
|
@ -78,5 +78,6 @@ coreenv["TEMPFILEARGESCFUNC"] = util.tempfile_arg_esc_func
|
|||||||
util.wrap_tempfile(coreenv, "LINKCOM")
|
util.wrap_tempfile(coreenv, "LINKCOM")
|
||||||
util.wrap_tempfile(coreenv, "ARCOM")
|
util.wrap_tempfile(coreenv, "ARCOM")
|
||||||
|
|
||||||
|
coreenv["SINGLEQUOTEFUNC"] = util.single_quote
|
||||||
|
|
||||||
Return("coreenv")
|
Return("coreenv")
|
||||||
|
@ -42,3 +42,7 @@ def random_alnum(length):
|
|||||||
return "".join(
|
return "".join(
|
||||||
random.choice(string.ascii_letters + string.digits) for _ in range(length)
|
random.choice(string.ascii_letters + string.digits) for _ in range(length)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def single_quote(arg_list):
|
||||||
|
return " ".join(f"'{arg}'" if " " in arg else str(arg) for arg in arg_list)
|
||||||
|
74
site_scons/site_tools/blackmagic.py
Normal file
74
site_scons/site_tools/blackmagic.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
from SCons.Errors import StopError
|
||||||
|
|
||||||
|
|
||||||
|
class BlackmagicResolver:
|
||||||
|
BLACKMAGIC_HOSTNAME = "blackmagic.local"
|
||||||
|
|
||||||
|
def __init__(self, env):
|
||||||
|
self.env = env
|
||||||
|
|
||||||
|
# On Win:
|
||||||
|
# 'location': '1-5:x.0', 'name': 'COM4',
|
||||||
|
# 'location': '1-5:x.2', 'name': 'COM13',
|
||||||
|
# On Linux:
|
||||||
|
# 'location': '1-1.2:1.0', 'name': 'ttyACM0',
|
||||||
|
# 'location': '1-1.2:1.2', 'name': 'ttyACM1',
|
||||||
|
# On MacOS:
|
||||||
|
# 'location': '0-1.3', 'name': 'cu.usbmodemblackmagic1',
|
||||||
|
# 'location': '0-1.3', 'name': 'cu.usbmodemblackmagic3',
|
||||||
|
def _find_probe(self):
|
||||||
|
import serial.tools.list_ports as list_ports
|
||||||
|
|
||||||
|
ports = list(list_ports.grep("blackmagic"))
|
||||||
|
if len(ports) == 0:
|
||||||
|
# Blackmagic probe serial port not found, will be handled later
|
||||||
|
pass
|
||||||
|
elif len(ports) > 2:
|
||||||
|
raise StopError("More than one Blackmagic probe found")
|
||||||
|
else:
|
||||||
|
# If you're getting any issues with auto lookup, uncomment this
|
||||||
|
# print("\n".join([f"{p.device} {vars(p)}" for p in ports]))
|
||||||
|
return sorted(ports, key=lambda p: f"{p.location}_{p.name}")[0]
|
||||||
|
|
||||||
|
# Look up blackmagic probe hostname with dns
|
||||||
|
def _resolve_hostname(self):
|
||||||
|
import socket
|
||||||
|
|
||||||
|
try:
|
||||||
|
return socket.gethostbyname(self.BLACKMAGIC_HOSTNAME)
|
||||||
|
except socket.gaierror:
|
||||||
|
print("Failed to resolve Blackmagic hostname")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
if not (probe := self._find_probe()):
|
||||||
|
return None
|
||||||
|
# print(f"Found Blackmagic probe on {probe.device}")
|
||||||
|
if self.env.subst("$PLATFORM") == "win32":
|
||||||
|
return f"\\\\.\\{probe.device}"
|
||||||
|
return probe.device
|
||||||
|
|
||||||
|
def get_networked(self):
|
||||||
|
if not (probe := self._resolve_hostname()):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return f"tcp:{probe}:2345"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
# print("distenv blackmagic", self.env.subst("$BLACKMAGIC"))
|
||||||
|
if (blackmagic := self.env.subst("$BLACKMAGIC")) != "auto":
|
||||||
|
return blackmagic
|
||||||
|
|
||||||
|
# print("Looking for Blackmagic...")
|
||||||
|
if probe := self.get_serial() or self.get_networked():
|
||||||
|
return probe
|
||||||
|
|
||||||
|
raise Exception("Please specify BLACKMAGIC=...")
|
||||||
|
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
env.SetDefault(BLACKMAGIC_ADDR=BlackmagicResolver(env))
|
||||||
|
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return True
|
@ -54,20 +54,20 @@ def AddFwProject(env, base_env, fw_type, fw_env_key):
|
|||||||
return project_env
|
return project_env
|
||||||
|
|
||||||
|
|
||||||
def AddDebugTarget(env, alias, targetenv, force_flash=True):
|
def AddOpenOCDFlashTarget(env, targetenv, **kw):
|
||||||
debug_target = env.PhonyTarget(
|
openocd_target = env.OpenOCDFlash(
|
||||||
alias,
|
"#build/oocd-${BUILD_CFG}-flash.flag",
|
||||||
"$GDBPYCOM",
|
targetenv["FW_BIN"],
|
||||||
source=targetenv["FW_ELF"],
|
OPENOCD_COMMAND=[
|
||||||
GDBPYOPTS='-ex "source debug/FreeRTOS/FreeRTOS.py" '
|
"-c",
|
||||||
'-ex "source debug/PyCortexMDebug/PyCortexMDebug.py" '
|
"program ${SOURCE.posix} reset exit ${BASE_ADDRESS}",
|
||||||
'-ex "svd_load ${SVD_FILE}" '
|
],
|
||||||
'-ex "compare-sections"',
|
BUILD_CFG=targetenv.subst("$FIRMWARE_BUILD_CFG"),
|
||||||
|
BASE_ADDRESS=targetenv.subst("$IMAGE_BASE_ADDRESS"),
|
||||||
|
**kw,
|
||||||
)
|
)
|
||||||
if force_flash:
|
env.Alias(targetenv.subst("${FIRMWARE_BUILD_CFG}_flash"), openocd_target)
|
||||||
env.Depends(debug_target, targetenv["FW_FLASH"])
|
return openocd_target
|
||||||
|
|
||||||
return debug_target
|
|
||||||
|
|
||||||
|
|
||||||
def DistCommand(env, name, source, **kw):
|
def DistCommand(env, name, source, **kw):
|
||||||
@ -85,8 +85,9 @@ def DistCommand(env, name, source, **kw):
|
|||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
env.AddMethod(AddFwProject)
|
env.AddMethod(AddFwProject)
|
||||||
env.AddMethod(AddDebugTarget)
|
|
||||||
env.AddMethod(DistCommand)
|
env.AddMethod(DistCommand)
|
||||||
|
env.AddMethod(AddOpenOCDFlashTarget)
|
||||||
|
|
||||||
env.SetDefault(
|
env.SetDefault(
|
||||||
COPRO_MCU_FAMILY="STM32WB5x",
|
COPRO_MCU_FAMILY="STM32WB5x",
|
||||||
)
|
)
|
||||||
|
@ -34,9 +34,9 @@ def PhonyTarget(env, name, action, source=None, **kw):
|
|||||||
source = []
|
source = []
|
||||||
phony_name = "phony_" + name
|
phony_name = "phony_" + name
|
||||||
env.Pseudo(phony_name)
|
env.Pseudo(phony_name)
|
||||||
return env.AlwaysBuild(
|
command = env.Command(phony_name, source, action, **kw)
|
||||||
env.Alias(name, env.Command(phony_name, source, action, **kw))
|
env.AlwaysBuild(env.Alias(name, command))
|
||||||
)
|
return command
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
Loading…
Reference in New Issue
Block a user