Write down the flash investigation and what made it slow

Four faults in the SPI/DMA/flash models each produced the same symptom -- stored
frequencies zeroed, a typed frequency reverting to 18 MHz -- and each was invisible
from the layer above. AGENTS.md now lists all four with the reasoning that connects
them to what the user saw, so the next person does not rediscover them one at a
time.

Also records the methodology mistakes, because they cost more than the bugs did:

- Attaching gdb between digits clears the frequency input box: the timeout is
  ~2.5 s and an attach takes ~3 s. Three wrong conclusions came from this, so
  instrument the model and read stderr instead of stopping the guest.
- A diagnostic log capped at six entries showed only 0xFF payloads and supported
  precisely the wrong conclusion. Do not cap before the shape of the data is known.
- A failed ninja leaves the old binary in place and the test still runs. Two rounds
  of results were meaningless. Check for FAILED and error: before trusting a run.
- assets/flash.img is written by every session, so a test starting from it can find
  its work already done -- which looks identical to broken persistence. Start from
  assets/pristine/, and power off before restoring, since shutdown flushes the old
  image back over the file.
- Hand-computed struct offsets gave KEY_LOCK=4 and TX_VFO=11, impossible values,
  because the ELF has no DWARF and the structs contain enums. Use an unambiguous
  nm symbol, or find the field by toggling it and diffing.
- One probe printed phase before incrementing it, making a correct address decoder
  look off by one. A working implementation was nearly "fixed" as a result.

README gains the two new tests in the build-verification step and the tools list.
This commit is contained in:
mckero committed 2026-08-28 15:32:45 +01:00
1 parent 798905f154
commit d09bf5f47e
2 files changed
+77 -1

No files matched your search

+8 -1
View File
@@ -72,6 +72,8 @@ keypresses silently stop working. Run the test after touching that code;
docs/screenshots/ LCD captures used in this README
tools/ run, screenshot, inject keys, probe state
keypad_test.py keypad regression test, boots its own instance
test_flash_persist.py flash writes survive a power cycle
test_freq_entry.py a typed frequency takes effect and persists
webui.py web remote control: live LCD plus clickable keypad
dn42_firewall.sh restrict the web UI port to DN42 sources
restore_flash.sh roll the flash image back to its pristine state
@@ -111,10 +113,15 @@ Needs a QEMU 7.2 source tree, `meson`, `ninja`, `libfdt-dev`, `libglib2.0-dev`,
Then check the build actually works, which takes about a minute:
python3 tools/keypad_test.py
python3 tools/test_flash_persist.py
python3 tools/test_freq_entry.py
This matters more than it looks. The keypad can break silently under -O2 without
any compiler warning -- see the `volatile` note in [Status](#status) -- so a clean
build is not evidence that keypresses work.
build is not evidence that keypresses work. The other two cover the flash path,
where four separate faults each ended up zeroing stored frequencies without
producing any error: details in
[AGENTS.md](AGENTS.md#the-flash-bugs-four-faults-one-symptom).
The rest of the tests: