Files
uv-k5-v3-emulator/tools/uvk5_banner.py
mckero fc432d2055 Report what the device says it is running, not the file we handed it
The page only knew its own input. A build called f4hwn.fusion.bin reports EGZUMER+F4HWN v6.0.0.CN, and with the multi-system release a committed external slot makes the factory bootloader reflash the internal flash from that slot on every power-on -- so the uploaded image never runs and the page keeps naming it. The firmware prints its own banner on USART1; tools/uvk5_banner.py reads it back, /api/firmware returns running: {banner, matches_uploaded, note}, and the page shows what the device reports, flagging it only when the running version is not in the uploaded image at all.

That reader also exposed a regression of my own: _start_stderr_pump had been rewritten to read the pipe in 64 KB chunks, which kept QEMU from blocking but delivered nothing to the log until 64 KB had accumulated -- and the banner is forty bytes, so it never appeared. It reads lines again, still starting before anything waits on QEMU, and test_uvk5_supervisor passes either way.
2026-10-01 16:22:44 +08:00

51 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""What the device says it is running, and whether that is what was uploaded.
The page knew only what it had *asked* to boot: the image it was given, or the one
uploaded through it. That is not the same question. With the multi-system release, an
external slot plus a valid state marker makes the factory bootloader reflash the
internal flash from that slot on every power-on -- so the uploaded image is overwritten
before it ever runs, the page keeps saying "f4hwn.fusion.bin", and the radio is running
something else entirely.
The firmware answers the question itself: it prints a banner on USART1 in its first
seconds ("UV-K5 Firmware, EGZUMER+F4HWN v6.0.0.CN"), which the machine tags SERIAL and
the page already collects. Reading that back is the difference between what we asked for
and what is running.
The second half matters too: a banner *should* often differ from a file name -- a file
called f4hwn.fusion.bin can legitimately report v6.0.0.CN -- so a difference is only
suspicious when the running version is not in the uploaded image at all. That check is
`image_mentions`, and it is what makes the hint honest rather than a false alarm.
"""
import re
BANNER = re.compile(r"UV-K5 Firmware,\s*(.+?)\s*$")
def latest(lines):
"""The most recent firmware banner in an iterable of log lines, or None."""
found = None
for line in lines:
match = BANNER.search(str(line))
if match:
found = match.group(1).strip()
return found
def image_mentions(path, banner) -> bool:
"""Does this firmware file contain the string the device reported?
A version string lives in the image, so an image whose banner this is will contain
it. If it does not, the device is running something else -- which is the case that
needs explaining (a slot restored by the bootloader, most often).
"""
if not path or not banner:
return True # nothing to check against; do not accuse anything
try:
with open(path, "rb") as fh:
blob = fh.read()
except OSError:
return True # unreadable is not evidence of a mismatch
return banner.encode("ascii", "ignore") in blob