Finish the portability sweep: one firmware resolver, no author paths

The probe scripts, run.sh, trace_run.sh, webui.py and two emulator tests each named the same hardcoded firmware from a source tree that is not in this repository. They now resolve QEMU and the firmware the way tools/uvk5_testenv.py does -- environment, then PATH, then whatever the checkout has -- and skip with a reason when there is nothing.

webui.py's --qemu and --elf lost their author defaults too: a bare qemu-system-arm through PATH, and no firmware until one is uploaded, which the page already reports.
This commit is contained in:
mckero committed 2026-10-01 15:15:31 +08:00
1 parent ae8b48c85a
commit 542515d5ad
21 files changed
+133 -37

No files matched your search

+3 -1
View File
@@ -6,7 +6,9 @@
# probe only read IDR, which cannot tell those two apart.
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
BASE=0x50000400
IDR=$((BASE + 0x10))
+3 -1
View File
@@ -5,7 +5,9 @@
# both twice gives the rate and an estimate of how long the delay will take.
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
GAP="${1:-4}"
SCRIPT=$(mktemp --suffix=.gdb)
trap 'rm -f "$SCRIPT"' EXIT
+3 -1
View File
@@ -5,7 +5,9 @@
# IDR 0x10, ODR 0x14.
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
BASE=0x50000400
SCRIPT=$(mktemp --suffix=.gdb)
trap 'rm -f "$SCRIPT"' EXIT
+3 -1
View File
@@ -6,7 +6,9 @@
# the debounce in app.c accept it?
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
python3 - "$KEY" <<'PY'
+3 -1
View File
@@ -9,7 +9,9 @@
# BSRR: low half sets a pin, high half resets it (py32f071xB.h).
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
BASE=0x50000400
BSRR=$((BASE + 0x18))
+1 -1
View File
@@ -6,7 +6,7 @@
# in the matrix wiring or the debounce.
set -uo pipefail
TOOLS="$HOME/uvk5-port/sim/tools"
TOOLS="$(cd "$(dirname "$0")" && pwd)"
KEY="${1:-MENU}"
python3 - "$KEY" <<'PY'
+3 -1
View File
@@ -6,7 +6,9 @@
# (different PC, or r1 reset for a new call).
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
SAMPLES="${1:-6}"
GAP="${2:-2}"
SCRIPT=$(mktemp --suffix=.gdb)
+3 -1
View File
@@ -6,7 +6,9 @@
# this only observes; the firmware does the driving.
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
STEPS="${2:-400}"
+7 -3
View File
@@ -7,9 +7,13 @@
# Usage: run.sh [firmware.elf]
set -euo pipefail
QEMU="$HOME/qemu-build/qemu-7.2+dfsg/build/qemu-system-arm"
ELF="${1:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
FLASH="$HOME/uvk5-port/sim/assets/flash.img"
QEMU="${QEMU:-$(command -v qemu-system-arm || true)}"
[ -n "$QEMU" ] || { echo "SKIP no qemu-system-arm; set QEMU or put it on PATH" >&2; exit 0; }
ELF="${1:-}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
FLASH="${UVK5_FLASH_IMAGE:-$(cd "$(dirname "$0")/.." && pwd)/assets/flash.img}"
QMP=/tmp/uvk5-qmp.sock
# Never `pkill -f 'M uv-k5-v3'` here: see tools/lib_kill_emulator.sh for why that
+3 -1
View File
@@ -6,7 +6,9 @@
# the firmware looks, versus the rows going low but the debounce rejecting them.
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
SAMPLES="${2:-10}"
+3 -1
View File
@@ -7,7 +7,9 @@
# go low".
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
KEY="${1:-MENU}"
HITS="${2:-12}"
+3 -2
View File
@@ -46,8 +46,9 @@ kill "$decoy" "$decoy2" 2>/dev/null || true
wait 2>/dev/null || true
# And a real emulator must actually be terminated.
QEMU="$HOME/qemu-build/qemu-7.2+dfsg/build/qemu-system-arm"
ELF="$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf"
QEMU="${QEMU:-$(command -v qemu-system-arm || true)}"
. "$HERE/uvk5_elf.sh"
ELF=$(uvk5_find_elf || true)
IMG=$(mktemp /tmp/kill-test-XXXX.img)
gzip -dc "$HERE/../assets/pristine/flash-pristine.img.gz" > "$IMG"
+13 -6
View File
@@ -18,18 +18,25 @@ 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")
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import uvk5_testenv
QEMU = uvk5_testenv.qemu()
ELF = uvk5_testenv.firmware()
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}")
missing = uvk5_testenv.missing([
(QEMU, "QEMU binary", "set QEMU=/path/to/qemu-system-arm, or put it on PATH"),
(ELF, "firmware", "run tools/fetch_firmware.py, or set ELF=..."),
(FLASH, "flash image", "run tools/make_flash.py"),
])
if missing:
print("SKIP: %s" % missing)
return 0
if os.path.exists(QMP):
os.unlink(QMP)
+5 -2
View File
@@ -25,8 +25,11 @@ HERE = os.path.dirname(os.path.abspath(__file__))
SIM = os.path.dirname(HERE)
sys.path.insert(0, 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")
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import uvk5_testenv
QEMU = uvk5_testenv.qemu()
ELF = uvk5_testenv.firmware()
FLASH = os.path.join(SIM, "assets", "flash.img")
QMP = "/tmp/uvk5-webui-e2e.sock"
HTTP_PORT = 8099
+8 -4
View File
@@ -6,9 +6,13 @@
# - does the GPIO input callback run? (TRACE gpio... set_input)
set -uo pipefail
QEMU="$HOME/qemu-build/qemu-7.2+dfsg/build/qemu-system-arm"
ELF="${1:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
FLASH="$HOME/uvk5-port/sim/assets/flash.img"
QEMU="${QEMU:-$(command -v qemu-system-arm || true)}"
[ -n "$QEMU" ] || { echo "SKIP no qemu-system-arm; set QEMU or put it on PATH" >&2; exit 0; }
ELF="${1:-}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
FLASH="${UVK5_FLASH_IMAGE:-$(cd "$(dirname "$0")/.." && pwd)/assets/flash.img}"
LOG=/tmp/uvk5-trace.log
QMP=/tmp/uvk5-qmp.sock
@@ -26,7 +30,7 @@ sleep 1
-kernel "$ELF" -gdb tcp::1234 >"$LOG" 2>&1 &
sleep 12
python3 "$HOME/uvk5-port/sim/tools/key.py" MENU >/dev/null 2>&1 || true
python3 "$(dirname "$0")/key.py" MENU >/dev/null 2>&1 || true
sleep 2
echo "== keypad row drives =="
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Where the firmware is, for the ad-hoc probe scripts.
#
# Every one of them used to name the same hardcoded path -- one developer's CW build --
# so none of them ran on a machine that did not have that file. The order here matches
# tools/uvk5_testenv.py, so the scripts and the tests agree about what is available.
#
# ELF, UVK5_FIRMWARE, UVK5_MULTIBOOT_IMAGE the environment wins
# assets/firmware/*, work/* then whatever the checkout has
#
# Returns non-zero when there is nothing, so a caller can skip with a reason rather
# than run against a path that does not exist.
uvk5_find_elf() {
local var value
for var in ELF UVK5_FIRMWARE UVK5_MULTIBOOT_IMAGE; do
eval "value=\${$var:-}"
if [ -n "$value" ] && [ -e "$value" ]; then
printf '%s' "$value"
return 0
fi
done
local root cand
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
for cand in "$root"/assets/firmware/*.elf "$root"/assets/firmware/*.bin \
"$root"/work/*.elf "$root"/work/*.bin; do
if [ -e "$cand" ]; then
printf '%s' "$cand"
return 0
fi
done
return 1
}
+2 -4
View File
@@ -1,10 +1,8 @@
#!/usr/bin/env python3
"""Where the emulator tests find a QEMU and a firmware, and what to say when they cannot.
The emulator tests used to name one developer's build directory:
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")
The emulator tests used to name one developer's build directory -- a QEMU under their
home, and one firmware build from a source tree outside this repository --
which is fine on the machine they were written on and useless anywhere else -- and a
missing file used to be a hard failure, so a checkout without that build could never
+29 -4
View File
@@ -1164,6 +1164,29 @@ pollFirmware();
</body></html>"""
def _default_qemu():
"""A QEMU to spawn: the environment, then PATH. Never one developer's build dir."""
try:
import uvk5_testenv
return str(uvk5_testenv.qemu() or "qemu-system-arm")
except Exception:
return "qemu-system-arm"
def _default_firmware():
"""Whatever firmware this checkout has, or nothing.
Nothing is the normal case now: a firmware can be uploaded from the page, and the page
says when one is not loaded. tools/uvk5_testenv.py looks in assets/firmware and work.
"""
try:
import uvk5_testenv
firmware = uvk5_testenv.firmware()
return str(firmware) if firmware else None
except Exception:
return None
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument("--qmp", default="/tmp/uvk5-qmp.sock")
@@ -1178,12 +1201,14 @@ def main() -> int:
help="attach to an emulator started elsewhere (run.sh) "
"instead of managing one. Off is then refused, since "
"this server did not start that process.")
ap.add_argument("--qemu", default=os.path.expanduser(
"~/qemu-build/qemu-7.2+dfsg/build/qemu-system-arm"))
# A path or a bare name: Popen resolves a bare name through PATH. The machine is
# built from this checkout, not from one developer's build directory.
ap.add_argument("--qemu", default=_default_qemu())
# Named --elf for history; any .bin or .elf works, and its shape is read out
# of the file rather than assumed. More can be uploaded from the page.
ap.add_argument("--elf", "--firmware", dest="elf", default=os.path.expanduser(
"~/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf"))
# Nothing local by default: upload a firmware from the page, which says so when
# none is loaded. tools/uvk5_testenv.py finds one in assets/firmware or work.
ap.add_argument("--elf", "--firmware", dest="elf", default=_default_firmware())
ap.add_argument("--flash", default=os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"assets", "flash.img"))
+3 -1
View File
@@ -4,7 +4,9 @@
# Usage: where.sh [samples]
set -uo pipefail
ELF="${ELF:-$HOME/uvk5-port/uvk5-sat/build/CW/nr7y.cw.elf}"
# shellcheck source=tools/uvk5_elf.sh
. "$(dirname "$0")/uvk5_elf.sh"
ELF=$(uvk5_find_elf) || { echo "SKIP no firmware found; set ELF or put one in assets/firmware" >&2; exit 0; }
SAMPLES="${1:-1}"
SCRIPT=$(mktemp --suffix=.gdb)
trap 'rm -f "$SCRIPT"' EXIT