tooling(micromate): --event selects what to download, incl. 'largest'
The tool downloaded only the first event, which on UM20147 is a 4,796 B histogram -- so it could not reach the 72,560 B event that is the whole point of the uint32 chunk-offset change. --event takes a key in hex, 'first', 'largest' or 'all'. 'largest' is the one worth running on an unfamiliar unit, since it is what exercises offsets past 64 KB; the output flags any event over 64 KB as carrying into params[1], and prints the chunk count so a 71-chunk walk is visible as such. Selected events are downloaded from inside iter_events(), so the chain cursor sits where THOR's would -- non-selected events are walked past without a download, which the browse walk already attests is fine. Also: connect() returning nothing now prints a hint rather than just a bare timeout. /dev/ttyACM* numbering shifts whenever another CDC-ACM device is plugged in, and this cost a debugging session when the tool was aimed at a TMI-Seismo MCU instead of the Micromate. `ls -l /dev/serial/by-id/` names each device and is stable, so the hint says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
+54
-19
@@ -232,6 +232,18 @@ def _decode(blob: bytes, key: bytes, record: bytes) -> None:
|
|||||||
print(f" saved to {out} for offline analysis")
|
print(f" saved to {out} for offline analysis")
|
||||||
|
|
||||||
|
|
||||||
|
def _select(refs, which: str):
|
||||||
|
"""Pick which events `--download` fetches."""
|
||||||
|
which = which.strip().lower()
|
||||||
|
if which == "first":
|
||||||
|
return refs[:1]
|
||||||
|
if which == "all":
|
||||||
|
return refs
|
||||||
|
if which == "largest":
|
||||||
|
return [max(refs, key=lambda r: r.size)]
|
||||||
|
return [r for r in refs if r.key_hex.lower() == which]
|
||||||
|
|
||||||
|
|
||||||
def step(label: str, fn):
|
def step(label: str, fn):
|
||||||
"""Run one read, report how long it took and what it returned."""
|
"""Run one read, report how long it took and what it returned."""
|
||||||
t0 = time.monotonic()
|
t0 = time.monotonic()
|
||||||
@@ -259,7 +271,12 @@ def main() -> int:
|
|||||||
"and negotiates its own rate.")
|
"and negotiates its own rate.")
|
||||||
ap.add_argument("--timeout", type=float, default=10.0)
|
ap.add_argument("--timeout", type=float, default=10.0)
|
||||||
ap.add_argument("--download", action="store_true",
|
ap.add_argument("--download", action="store_true",
|
||||||
help="also download the first stored event (read-only)")
|
help="also walk the event chain and download (read-only)")
|
||||||
|
ap.add_argument("--event", default="first", metavar="WHICH",
|
||||||
|
help="which event --download fetches: a key in hex "
|
||||||
|
"(e.g. 055d4a83), 'first', 'largest', or 'all'. "
|
||||||
|
"'largest' is the one worth running on an unfamiliar "
|
||||||
|
"unit -- it is what exercises offsets past 64 KB.")
|
||||||
ap.add_argument("--capture", metavar="DIR",
|
ap.add_argument("--capture", metavar="DIR",
|
||||||
help="also write a raw_bw_*/raw_s3_*.bin pair to DIR, so "
|
help="also write a raw_bw_*/raw_s3_*.bin pair to DIR, so "
|
||||||
"this run can become a test fixture. Worth doing on "
|
"this run can become a test fixture. Worth doing on "
|
||||||
@@ -291,6 +308,12 @@ def main() -> int:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
info = step("connect() identity", mm.connect)
|
info = step("connect() identity", mm.connect)
|
||||||
|
if info is None:
|
||||||
|
print("\n Nothing answered. If the port opened but no frame came back,")
|
||||||
|
print(" check it is actually a Micromate and not another CDC-ACM device —")
|
||||||
|
print(" /dev/ttyACM* numbering shifts when anything else is plugged in.")
|
||||||
|
print(" `ls -l /dev/serial/by-id/` names each device and is stable.")
|
||||||
|
return 3
|
||||||
if info:
|
if info:
|
||||||
print(f" serial={info.serial} model={info.model} "
|
print(f" serial={info.serial} model={info.model} "
|
||||||
f"fw={info.firmware_line} monitoring={info.monitoring}")
|
f"fw={info.firmware_line} monitoring={info.monitoring}")
|
||||||
@@ -345,24 +368,36 @@ def main() -> int:
|
|||||||
print(f" would be filed as {ref.filename}")
|
print(f" would be filed as {ref.filename}")
|
||||||
|
|
||||||
if refs:
|
if refs:
|
||||||
# Download via iter_events, which reproduces THOR's interleaved
|
wanted = _select(refs, a.event)
|
||||||
# order -- the one with captures behind it.
|
if not wanted:
|
||||||
print("\n download (first event, THOR's interleaved order):")
|
print(f"\n --event {a.event!r} matched nothing")
|
||||||
for ref in mm.iter_events():
|
else:
|
||||||
t1 = time.monotonic()
|
print(f"\n download ({len(wanted)} of {len(refs)}, "
|
||||||
try:
|
f"THOR's interleaved order):")
|
||||||
result = mm.get_event(ref) # verify=True
|
want_keys = {r.key_hex for r in wanted}
|
||||||
except Exception as e:
|
# iter_events() walks the chain; download only the selected
|
||||||
print(f" {ref.key_hex}: {type(e).__name__}: {e}")
|
# events, at the cursor position THOR would be at.
|
||||||
break
|
for ref in mm.iter_events():
|
||||||
dt = max(time.monotonic() - t1, 1e-6)
|
if ref.key_hex not in want_keys:
|
||||||
n = sum(len(v) for v in getattr(result, "samples", {}).values())
|
continue
|
||||||
err = mm.decode_error(ref, result)
|
n_chunks = -(-ref.size // 1024)
|
||||||
check = ("PVS agrees to %+.4f%%" % (100 * err)
|
note = (" <- past 64 KB, carries into params[1]"
|
||||||
if err is not None else "PVS check n/a (histogram)")
|
if ref.size > 0x10000 else "")
|
||||||
print(f" {ref.key_hex} {ref.record_type:9} {ref.size:6} B "
|
t1 = time.monotonic()
|
||||||
f"in {dt:.1f} s -> {n} samples, {check}")
|
try:
|
||||||
break
|
result = mm.get_event(ref) # verify=True
|
||||||
|
except Exception as e:
|
||||||
|
print(f" {ref.key_hex} {ref.size:7} B "
|
||||||
|
f"FAILED {type(e).__name__}: {e}")
|
||||||
|
continue
|
||||||
|
dt = max(time.monotonic() - t1, 1e-6)
|
||||||
|
n = sum(len(v) for v in getattr(result, "samples", {}).values())
|
||||||
|
err = mm.decode_error(ref, result)
|
||||||
|
check = ("PVS %+.4f%%" % (100 * err) if err is not None
|
||||||
|
else "PVS n/a (histogram)")
|
||||||
|
print(f" {ref.key_hex} {ref.record_type:9} "
|
||||||
|
f"{ref.size:7} B {n_chunks:3} chunks {dt:5.1f} s "
|
||||||
|
f"{n:6} samples {check}{note}")
|
||||||
|
|
||||||
except ProtocolError as e:
|
except ProtocolError as e:
|
||||||
print(f"\n ABORTED {type(e).__name__}: {e}")
|
print(f"\n ABORTED {type(e).__name__}: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user