Files
uv-k5-v3-emulator/tools/test_serial_capture.py
T
mckero 2667e046e8 Emulator: multiboot slots from the page, flash controller, portable tests
flash controller: store ACR/OPTKEYR instead of swallowing them, which is what stopped the factory bootloader from starting

slots over the firmware's own serial protocol (0x0720 family); uvk5_socket/uvk5_testenv so a fresh checkout skips instead of failing; web UI slot table and Multiboot button; quick start, CONTRIBUTING, and stop tracking firmware images and radio dumps
2026-10-01 14:54:34 +08:00

71 lines
2.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""Firmware serial output must reach the host.
App/main.c sends UART_Version over USART1 right after UART_Init(), and _putchar
routes every printf_ there too. The machine has no USART1 model -- it is one of the
logging catch-all stubs -- so without help those bytes vanish and the firmware
appears to print nothing at all.
Boots a real emulator on a private socket and checks the bytes come out of QEMU's
stderr as SERIAL lines.
Run: python3 tools/test_serial_capture.py
"""
import os
import subprocess
import sys
import time
HERE = os.path.dirname(os.path.abspath(__file__))
SIM = os.path.dirname(HERE)
QEMU = os.path.expanduser("~/qemu-build/qemu-7.2+dfsg/build/qemu-system-arm")
ELF = os.path.expanduser("~/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf")
FLASH = os.path.join(SIM, "assets", "flash.img")
LOG = "/tmp/uvk5-serial-test.log"
QMP = "/tmp/uvk5-serial-test.sock"
def main():
for path, what in ((QEMU, "QEMU binary"), (ELF, "firmware ELF"),
(FLASH, "flash image")):
if not os.path.exists(path):
sys.exit(f"missing {what}: {path}")
if os.path.exists(QMP):
os.unlink(QMP)
with open(LOG, "wb") as fh:
proc = subprocess.Popen(
[QEMU, "-M", f"uv-k5-v3,flash-image={FLASH}", "-nographic",
"-monitor", "none", "-qmp", f"unix:{QMP},server=on,wait=off",
"-kernel", ELF],
stdout=subprocess.DEVNULL, stderr=fh)
try:
time.sleep(14)
finally:
proc.terminate()
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
proc.kill()
if os.path.exists(QMP):
os.unlink(QMP)
# Explicit UTF-8: the firmware's own output is not always ASCII, and the locale
# codec on Windows would mangle it (it cannot decode Chinese at all).
text = open(LOG, encoding="utf-8", errors="replace").read()
lines = [l for l in text.splitlines() if l.startswith("SERIAL")]
print(f"captured {len(lines)} SERIAL line(s)")
for line in lines[:10]:
print(" ", line)
if not lines:
print("\nFAIL no SERIAL output; USART1 DR writes are still being dropped")
print(" (App/main.c:98 sends UART_Version, so something should appear)")
return 1
print("\nPASS firmware serial output reaches the host")
return 0
if __name__ == "__main__":
raise SystemExit(main())