2020-08-25 21:02:02 -04:00
|
|
|
#!/usr/bin/env python
|
2020-09-11 19:33:56 -04:00
|
|
|
import argparse
|
|
|
|
|
import hashlib
|
2022-03-03 11:42:05 -05:00
|
|
|
import subprocess
|
2020-09-11 19:33:56 -04:00
|
|
|
import shutil
|
2020-12-03 16:56:01 -05:00
|
|
|
import shlex
|
2022-04-20 20:06:11 -04:00
|
|
|
import glob
|
2020-09-11 19:33:56 -04:00
|
|
|
import time
|
2022-03-31 21:04:25 -04:00
|
|
|
import math
|
2020-09-11 19:33:56 -04:00
|
|
|
import sys
|
|
|
|
|
import re
|
|
|
|
|
import os
|
2020-08-25 21:02:02 -04:00
|
|
|
|
2022-03-03 11:42:05 -05:00
|
|
|
try:
|
|
|
|
|
sys.path.append(os.path.join(os.environ["IDF_PATH"], "components", "partition_table"))
|
2022-03-31 21:04:25 -04:00
|
|
|
import serial, parttool, gen_esp32part
|
2022-03-03 11:42:05 -05:00
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
2022-08-24 16:29:11 -04:00
|
|
|
TARGETS = ["odroid-go"] # We just need to specify the default, the others are discovered below
|
2022-04-20 20:06:11 -04:00
|
|
|
for t in glob.glob("components/retro-go/targets/*.h"):
|
|
|
|
|
TARGETS.append(os.path.basename(t)[0:-2])
|
|
|
|
|
|
|
|
|
|
DEFAULT_TARGET = os.getenv("RG_TOOL_TARGET", TARGETS[0])
|
2021-09-24 16:50:27 -04:00
|
|
|
DEFAULT_BAUD = os.getenv("RG_TOOL_BAUD", "1152000")
|
|
|
|
|
DEFAULT_PORT = os.getenv("RG_TOOL_PORT", "COM3")
|
2022-03-16 18:16:54 -04:00
|
|
|
PROJECT_NAME = os.getenv("PROJECT_NAME", "Retro-Go") # os.path.basename(os.getcwd()).title()
|
2022-03-14 00:19:22 -04:00
|
|
|
PROJECT_ICON = os.getenv("PROJECT_ICON", "icon.raw")
|
2022-03-31 21:04:25 -04:00
|
|
|
PROJECT_APPS = {}
|
2022-01-31 07:53:00 -05:00
|
|
|
try:
|
2022-03-14 00:19:22 -04:00
|
|
|
PROJECT_VER = os.getenv("PROJECT_VER") or subprocess.check_output(
|
|
|
|
|
"git describe --tags --abbrev=5 --dirty --always", shell=True
|
|
|
|
|
).decode().rstrip()
|
2022-01-31 07:53:00 -05:00
|
|
|
except:
|
2022-03-14 00:19:22 -04:00
|
|
|
PROJECT_VER = "unknown"
|
2020-08-25 21:02:02 -04:00
|
|
|
|
2022-03-31 21:04:25 -04:00
|
|
|
if os.path.exists("rg_config.py"):
|
|
|
|
|
with open("rg_config.py", "rb") as f:
|
|
|
|
|
exec(f.read())
|
|
|
|
|
# else: something like
|
|
|
|
|
# for file in glob(*/CMakeLists.txt):
|
|
|
|
|
# PROJECT_APPS[basename(dirname(file))] = [0, 0, 0, 0]
|
2022-03-14 00:19:22 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
if not os.getenv("IDF_PATH"):
|
|
|
|
|
exit("IDF_PATH is not defined. Are you running inside esp-idf environment?")
|
2020-09-11 19:33:56 -04:00
|
|
|
|
2022-01-31 07:53:00 -05:00
|
|
|
|
2020-09-11 19:33:56 -04:00
|
|
|
class Symbol:
|
|
|
|
|
def __init__(self, address, name, source="??:?", inlined=None):
|
|
|
|
|
self.address = int(str(address), 0)
|
|
|
|
|
self.name = name
|
|
|
|
|
self.source = os.path.normpath(source)
|
|
|
|
|
self.inlined = inlined
|
|
|
|
|
self.hash = hashlib.sha1(bytes(self.source + self.name, "UTF-8")).hexdigest()
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
text = "0x%x: %s at %s" % (self.address, self.name, self.source)
|
|
|
|
|
if self.inlined:
|
|
|
|
|
text += "\ninlined by %s" % str(self.inlined)
|
|
|
|
|
return text.replace("\n", "\n ")
|
|
|
|
|
|
2020-09-11 21:35:57 -04:00
|
|
|
|
|
|
|
|
class CallBranch:
|
|
|
|
|
def __init__(self, name, parent=None):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.parent = parent
|
|
|
|
|
self.run_time = 0;
|
|
|
|
|
self.children = dict()
|
|
|
|
|
|
|
|
|
|
def add_frame(self, caller, callee, num_calls, run_time):
|
|
|
|
|
if callee.hash not in self.children:
|
|
|
|
|
self.children[callee.hash] = [caller, callee, num_calls, run_time]
|
|
|
|
|
else:
|
|
|
|
|
self.children[callee.hash][2] += num_calls
|
|
|
|
|
self.children[callee.hash][3] += run_time
|
|
|
|
|
self.run_time += run_time
|
|
|
|
|
|
|
|
|
|
|
2022-01-31 07:53:00 -05:00
|
|
|
def debug_print(text):
|
|
|
|
|
print("\033[0;33m%s\033[0m" % text)
|
|
|
|
|
|
|
|
|
|
|
2020-09-11 19:33:56 -04:00
|
|
|
def find_symbol(elf_file, addr):
|
|
|
|
|
try:
|
|
|
|
|
if addr not in symbols_cache:
|
|
|
|
|
symbols_cache[addr] = Symbol(0, "??")
|
2022-01-31 07:53:00 -05:00
|
|
|
out = subprocess.check_output(["xtensa-esp32-elf-addr2line", "-ifCe", elf_file, addr], shell=True)
|
|
|
|
|
lines = out.decode().rstrip().splitlines()
|
2020-09-11 19:33:56 -04:00
|
|
|
if len(lines) > 2:
|
|
|
|
|
symbols_cache[addr] = Symbol(addr, lines[0], lines[1], Symbol(0, lines[2], lines[3]))
|
|
|
|
|
elif len(lines) == 2:
|
|
|
|
|
symbols_cache[addr] = Symbol(addr, lines[0], lines[1])
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
return symbols_cache[addr]
|
2022-03-14 00:19:22 -04:00
|
|
|
symbols_cache = dict()
|
2020-09-11 19:33:56 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def analyze_profile(frames):
|
2020-09-11 21:35:57 -04:00
|
|
|
flatten = True # False is currently not working correctly
|
2020-09-11 19:33:56 -04:00
|
|
|
tree = dict()
|
|
|
|
|
|
|
|
|
|
for caller, callee, num_calls, run_time in frames:
|
2020-09-11 21:35:57 -04:00
|
|
|
branch = '*' if flatten else caller.name + "@" + os.path.basename(caller.source)
|
2020-09-11 19:33:56 -04:00
|
|
|
if branch not in tree:
|
2020-09-11 21:35:57 -04:00
|
|
|
tree[branch] = CallBranch(branch, caller)
|
|
|
|
|
tree[branch].add_frame(caller, callee, num_calls, run_time)
|
|
|
|
|
|
|
|
|
|
tree_sorted = sorted(tree.values(), key=lambda x: x.run_time, reverse=True)
|
|
|
|
|
|
|
|
|
|
for branch in tree_sorted:
|
|
|
|
|
if branch.run_time < 100_000:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
debug_print("%-68s %dms" % (branch.name, branch.run_time / 1000))
|
|
|
|
|
children = sorted(branch.children.values(), key=lambda x: x[3], reverse=True)
|
|
|
|
|
|
|
|
|
|
for caller, callee, num_calls, run_time in children:
|
|
|
|
|
if run_time < 10_000:
|
|
|
|
|
continue
|
|
|
|
|
debug_print(" %-32s %-20s %-10d %dms"
|
|
|
|
|
% (callee.name, os.path.basename(callee.source), num_calls, run_time / 1000))
|
|
|
|
|
|
|
|
|
|
debug_print("")
|
2020-09-11 19:33:56 -04:00
|
|
|
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
def build_firmware(apps, device_type):
|
|
|
|
|
print("Building firmware with: %s\n" % " ".join(apps))
|
2020-08-27 16:40:45 -04:00
|
|
|
args = [
|
|
|
|
|
sys.executable,
|
|
|
|
|
"tools/mkfw.py",
|
2021-12-17 13:25:35 -05:00
|
|
|
("%s_%s_%s.fw" % (PROJECT_NAME, PROJECT_VER, device_type)).lower(),
|
2020-08-27 16:40:45 -04:00
|
|
|
("%s %s" % (PROJECT_NAME, PROJECT_VER)),
|
2022-03-14 00:19:22 -04:00
|
|
|
PROJECT_ICON
|
2020-08-27 16:40:45 -04:00
|
|
|
]
|
2021-09-13 20:38:10 -04:00
|
|
|
|
|
|
|
|
if device_type in ["mrgc-g32", "esplay"]:
|
|
|
|
|
args.append("--esplay")
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
for app in apps:
|
|
|
|
|
part = PROJECT_APPS[app]
|
|
|
|
|
args += [str(part[0]), str(part[1]), str(part[2]), app, os.path.join(app, "build", app + ".bin")]
|
2020-08-25 21:02:02 -04:00
|
|
|
|
2022-03-31 21:04:25 -04:00
|
|
|
print("Running: %s" % ' '.join(shlex.quote(arg) for arg in args[1:]))
|
2022-03-14 00:19:22 -04:00
|
|
|
subprocess.run(args, check=True)
|
2020-08-25 21:02:02 -04:00
|
|
|
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
def build_image(apps, device_type):
|
|
|
|
|
print("Building image with: %s\n" % " ".join(apps))
|
2022-03-31 21:04:25 -04:00
|
|
|
image_file = ("%s_%s_%s.img" % (PROJECT_NAME, PROJECT_VER, device_type)).lower()
|
|
|
|
|
image_data = bytearray(b"\xFF" * 0x10000)
|
|
|
|
|
table_ota = 0
|
|
|
|
|
table_csv = [
|
|
|
|
|
"nvs, data, nvs, 36864, 16384",
|
|
|
|
|
"otadata, data, ota, 53248, 8192",
|
|
|
|
|
"phy_init, data, phy, 61440, 4096",
|
|
|
|
|
]
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
for app in apps:
|
|
|
|
|
part = PROJECT_APPS[app]
|
|
|
|
|
with open(os.path.join(app, "build", app + ".bin"), "rb") as f:
|
2022-03-31 21:04:25 -04:00
|
|
|
data = f.read()
|
|
|
|
|
part_size = max(part[2], math.ceil(len(data) / 0x10000) * 0x10000)
|
2022-04-20 20:06:11 -04:00
|
|
|
table_csv.append("%s, app, ota_%d, %d, %d" % (app, table_ota, len(image_data), part_size))
|
2022-03-31 21:04:25 -04:00
|
|
|
table_ota += 1
|
|
|
|
|
image_data += data + b"\xFF" * (part_size - len(data))
|
|
|
|
|
|
|
|
|
|
try:
|
2022-04-20 20:06:11 -04:00
|
|
|
cwd = os.path.join(os.getcwd(), list(apps)[0])
|
2022-03-31 21:04:25 -04:00
|
|
|
subprocess.run("idf.py bootloader", stdout=subprocess.DEVNULL, shell=True, check=True, cwd=cwd)
|
|
|
|
|
with open(os.path.join(cwd, "build", "bootloader", "bootloader.bin"), "rb") as f:
|
|
|
|
|
bootloader_bin = f.read()
|
|
|
|
|
image_data[0x1000:0x1000+len(bootloader_bin)] = bootloader_bin
|
|
|
|
|
except:
|
|
|
|
|
exit("Error building bootloader")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
table_bin = gen_esp32part.PartitionTable.from_csv("\n".join(table_csv)).to_binary()
|
|
|
|
|
image_data[0x8000:0x8000+len(table_bin)] = table_bin
|
|
|
|
|
except:
|
|
|
|
|
exit("Error generating partition table")
|
|
|
|
|
|
|
|
|
|
with open(image_file, "wb") as f:
|
|
|
|
|
f.write(image_data)
|
|
|
|
|
|
|
|
|
|
print("Saved image '%s' (%d bytes)\n" % (image_file, len(image_data)))
|
|
|
|
|
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
def clean_app(app):
|
|
|
|
|
print("Cleaning up app '%s'..." % app)
|
2021-06-19 11:33:11 -04:00
|
|
|
try:
|
2022-04-20 20:06:11 -04:00
|
|
|
os.unlink(os.path.join(app, "sdkconfig"))
|
|
|
|
|
os.unlink(os.path.join(app, "sdkconfig.old"))
|
2021-09-13 20:38:10 -04:00
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
try:
|
2022-04-20 20:06:11 -04:00
|
|
|
shutil.rmtree(os.path.join(app, "build"))
|
2021-06-19 11:33:11 -04:00
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
print("Done.\n")
|
2020-08-25 21:02:02 -04:00
|
|
|
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
def build_app(app, device_type, with_profiling=False, with_netplay=False):
|
2020-09-11 19:33:56 -04:00
|
|
|
# To do: clean up if any of the flags changed since last build
|
2022-04-20 20:06:11 -04:00
|
|
|
print("Building app '%s'" % app)
|
2022-07-19 16:26:07 -04:00
|
|
|
os.putenv("RG_ENABLE_PROFILING", "1" if with_profiling else "0")
|
|
|
|
|
os.putenv("RG_ENABLE_NETPLAY", "1" if with_netplay else "0")
|
|
|
|
|
os.putenv("RG_BUILD_TARGET", re.sub(r'[^A-Z0-9]', '_', device_type.upper()))
|
2022-07-18 14:16:59 -04:00
|
|
|
os.putenv("RG_BUILD_TIME", str(int(time.time())))
|
|
|
|
|
os.putenv("PROJECT_VER", PROJECT_VER)
|
2022-04-20 20:06:11 -04:00
|
|
|
subprocess.run("idf.py app", shell=True, check=True, cwd=os.path.join(os.getcwd(), app))
|
2020-09-12 01:44:55 -04:00
|
|
|
|
2021-11-24 15:46:54 -05:00
|
|
|
try:
|
|
|
|
|
print("\nPatching esp_image_header_t to skip sha256 on boot... ", end="")
|
2022-04-20 20:06:11 -04:00
|
|
|
with open(os.path.join(app, "build", app + ".bin"), "r+b") as fp:
|
2021-11-24 15:46:54 -05:00
|
|
|
fp.seek(23)
|
|
|
|
|
fp.write(b"\0")
|
|
|
|
|
print("done!\n")
|
|
|
|
|
except: # don't really care if that fails
|
|
|
|
|
print("failed!\n")
|
|
|
|
|
pass
|
2020-08-25 21:02:02 -04:00
|
|
|
|
|
|
|
|
|
2022-04-20 20:06:11 -04:00
|
|
|
def monitor_app(app, port, baudrate=115200):
|
|
|
|
|
print("Starting monitor for app '%s'" % app)
|
2020-09-11 19:33:56 -04:00
|
|
|
mon = serial.Serial(port, baudrate=baudrate, timeout=0)
|
2022-04-20 20:06:11 -04:00
|
|
|
elf = os.path.join(app, "build", app + ".elf")
|
2020-09-11 19:33:56 -04:00
|
|
|
|
|
|
|
|
mon.setDTR(False)
|
|
|
|
|
mon.setRTS(False)
|
|
|
|
|
|
|
|
|
|
# To do: detect ctrl+r ctrl+c etc
|
|
|
|
|
|
|
|
|
|
profile_frames = list()
|
|
|
|
|
|
|
|
|
|
line_bytes = b''
|
|
|
|
|
while 1:
|
2020-09-13 16:01:33 -04:00
|
|
|
if mon.in_waiting == 0:
|
2020-09-11 19:33:56 -04:00
|
|
|
sys.stdout.flush()
|
|
|
|
|
time.sleep(0.010)
|
2020-09-13 16:01:33 -04:00
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
byte = mon.read()
|
|
|
|
|
|
|
|
|
|
if byte != b"\n":
|
|
|
|
|
sys.stdout.buffer.write(byte) # byte.decode()
|
|
|
|
|
line_bytes += byte
|
|
|
|
|
else:
|
|
|
|
|
line = line_bytes.decode(errors="ignore").rstrip()
|
|
|
|
|
line_bytes = b''
|
|
|
|
|
|
|
|
|
|
# check for debug data meant to be analyzed, not displayed
|
|
|
|
|
m = re.match(r"^RGD:([A-Z0-9]+):([A-Z0-9]+)\s*(.*)$", line)
|
|
|
|
|
if m:
|
|
|
|
|
rg_debug_ns = m.group(1)
|
|
|
|
|
rg_debug_cmd = m.group(2)
|
|
|
|
|
rg_debug_arg = m.group(3)
|
|
|
|
|
|
|
|
|
|
sys.stdout.buffer.write(b"\r") # Clear the line
|
|
|
|
|
|
|
|
|
|
if rg_debug_ns == "PROF":
|
|
|
|
|
if rg_debug_cmd == "BEGIN":
|
|
|
|
|
profile_frames.clear()
|
|
|
|
|
if rg_debug_cmd == "END":
|
|
|
|
|
analyze_profile(profile_frames)
|
|
|
|
|
if rg_debug_cmd == "DATA":
|
|
|
|
|
m = re.match(r"([x0-9a-f]+)\s([x0-9a-f]+)\s(\d+)\s(\d+)", rg_debug_arg)
|
|
|
|
|
if m:
|
|
|
|
|
profile_frames.append([
|
|
|
|
|
find_symbol(elf, m.group(1)),
|
|
|
|
|
find_symbol(elf, m.group(2)),
|
|
|
|
|
int(m.group(3)),
|
|
|
|
|
int(m.group(4)),
|
|
|
|
|
])
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
sys.stdout.buffer.write(b"\n")
|
|
|
|
|
|
|
|
|
|
# check for symbol addresses
|
|
|
|
|
for addr in re.findall(r"0x4[0-9a-fA-F]{7}", line):
|
|
|
|
|
symbol = find_symbol(elf, addr)
|
|
|
|
|
if symbol and "??:" not in symbol.source:
|
|
|
|
|
debug_print(symbol)
|
2020-08-25 21:02:02 -04:00
|
|
|
|
|
|
|
|
|
2020-08-27 16:40:45 -04:00
|
|
|
parser = argparse.ArgumentParser(description="Retro-Go build tool")
|
|
|
|
|
parser.add_argument(
|
2020-09-11 19:41:51 -04:00
|
|
|
# To do: Learn to use subcommands instead...
|
2022-03-19 21:17:44 -04:00
|
|
|
"command", choices=["build-fw", "build-img", "release", "build", "clean", "flash", "monitor", "run", "profile"],
|
2020-08-27 16:40:45 -04:00
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
2021-06-19 11:33:11 -04:00
|
|
|
"apps", nargs="*", default="all", choices=["all"] + list(PROJECT_APPS.keys())
|
2020-08-27 16:40:45 -04:00
|
|
|
)
|
2020-09-11 19:33:56 -04:00
|
|
|
parser.add_argument(
|
2022-04-20 20:06:11 -04:00
|
|
|
"--target", default=DEFAULT_TARGET, choices=set(TARGETS), help="Device to target"
|
2020-09-11 19:33:56 -04:00
|
|
|
)
|
2020-09-09 16:43:17 -04:00
|
|
|
parser.add_argument(
|
2021-06-19 11:33:11 -04:00
|
|
|
"--with-netplay", action="store_const", const=True, help="Build with netplay enabled"
|
2020-09-09 16:43:17 -04:00
|
|
|
)
|
2020-08-27 16:40:45 -04:00
|
|
|
parser.add_argument(
|
2021-09-24 12:26:08 -04:00
|
|
|
"--port", default=DEFAULT_PORT, help="Serial port to use for flash and monitor"
|
|
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--baud", default=DEFAULT_BAUD, help="Serial baudrate to use for flashing"
|
2020-08-27 16:40:45 -04:00
|
|
|
)
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
2020-09-09 16:43:17 -04:00
|
|
|
|
2020-08-27 16:40:45 -04:00
|
|
|
command = args.command
|
2022-06-18 14:03:15 -04:00
|
|
|
apps = [app for app in PROJECT_APPS.keys() if app in args.apps or "all" in args.apps]
|
2020-08-27 16:40:45 -04:00
|
|
|
|
2022-06-18 14:03:15 -04:00
|
|
|
if command in ["build-fw", "build-img", "release"]:
|
|
|
|
|
if "launcher" not in apps:
|
|
|
|
|
print("\nWARNING: The launcher is mandatory for those apps and will be included!\n")
|
|
|
|
|
apps.insert(0, "launcher")
|
2020-09-09 16:43:17 -04:00
|
|
|
|
2021-12-06 18:39:18 -05:00
|
|
|
if command in ["clean", "release"]:
|
2021-09-13 20:38:10 -04:00
|
|
|
print("=== Step: Cleaning ===\n")
|
|
|
|
|
for app in apps:
|
|
|
|
|
clean_app(app)
|
2021-06-19 11:33:11 -04:00
|
|
|
|
2022-03-19 21:17:44 -04:00
|
|
|
if command in ["build", "build-fw", "build-img", "release", "run", "profile"]:
|
2021-09-13 20:38:10 -04:00
|
|
|
print("=== Step: Building ===\n")
|
|
|
|
|
for app in apps:
|
2022-03-19 21:17:44 -04:00
|
|
|
build_app(app, args.target, command == "profile", args.with_netplay)
|
2020-08-25 21:02:02 -04:00
|
|
|
|
2021-12-06 18:39:18 -05:00
|
|
|
if command in ["build-fw", "release"]:
|
2021-09-13 20:38:10 -04:00
|
|
|
print("=== Step: Packing ===\n")
|
2022-03-19 21:17:44 -04:00
|
|
|
build_firmware(apps, args.target)
|
|
|
|
|
|
2022-03-31 21:04:25 -04:00
|
|
|
if command in ["build-img", "release"]:
|
|
|
|
|
print("=== Step: Packing ===\n")
|
|
|
|
|
build_image(apps, args.target)
|
2020-08-25 21:02:02 -04:00
|
|
|
|
2022-03-19 21:17:44 -04:00
|
|
|
if command in ["flash", "run", "profile"]:
|
2021-09-13 20:38:10 -04:00
|
|
|
print("=== Step: Flashing ===\n")
|
2022-03-14 00:31:13 -04:00
|
|
|
if "parttool" not in globals():
|
|
|
|
|
exit("Failed to load the parttool module from your esp-idf framework.")
|
2022-03-03 11:42:05 -05:00
|
|
|
try:
|
|
|
|
|
pt = parttool.ParttoolTarget(args.port, args.baud)
|
|
|
|
|
except:
|
|
|
|
|
exit("Failed to read device's partition table!")
|
|
|
|
|
try:
|
|
|
|
|
for app in apps:
|
|
|
|
|
print("Flashing app '%s'" % app)
|
|
|
|
|
pt.write_partition(parttool.PartitionName(app), os.path.join(app, "build", app + ".bin"))
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print("Error: {}".format(e))
|
|
|
|
|
if "does not exist" in str(e):
|
|
|
|
|
print("This indicates that the partition table on your device is incorrect.")
|
|
|
|
|
print("Make sure you've installed a recent retro-go-*.fw!")
|
|
|
|
|
exit("Task failed.")
|
2020-09-09 16:43:17 -04:00
|
|
|
|
2022-03-19 21:17:44 -04:00
|
|
|
if command in ["monitor", "run", "profile"]:
|
2021-09-13 20:38:10 -04:00
|
|
|
print("=== Step: Monitoring ===\n")
|
2022-03-14 00:31:13 -04:00
|
|
|
if "serial" not in globals():
|
|
|
|
|
exit("Failed to load the serial module. You can try running 'pip install pyserial'.")
|
2021-06-19 11:33:11 -04:00
|
|
|
if len(apps) == 1:
|
|
|
|
|
monitor_app(apps[0], args.port)
|
2021-02-06 15:56:11 -05:00
|
|
|
else:
|
|
|
|
|
monitor_app("dummy", args.port)
|
2020-08-25 21:02:02 -04:00
|
|
|
|
|
|
|
|
print("All done!")
|