docs: Pi install + pm3flash firmware flashing (README, CLAUDE, roadmap)

- README: rewrite Install (from source, submodules, deps, Pi/aarch64); new
  'Flashing firmware (pm3flash)' section — CLI usage, --build, image resolution,
  cross-compile + PLATFORM note, Raspberry Pi bring-up, programmatic API; point
  Firmware Compatibility at it; add a License section (MIT).
- CLAUDE.md: flash.py/_firmware.py/flash_cli.py in the structure; a 'Firmware
  flashing' section with the maintainer gotchas (OLD frame, fullimage-only,
  page-merge, platform != is_rdv4, the pin).
- roadmap: new 2026-07-05-firmware-flasher plan doc + a Firmware-flashing row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-05 22:20:15 -07:00
parent c0ae7b90c8
commit 0ba5256d02
4 changed files with 142 additions and 2 deletions

View File

@@ -30,6 +30,9 @@ pm3py/
hf_iso15.py # ISO 15693 — scan, rdbl, wrbl, thin sniff cmd
hf_mfc.py # MIFARE Classic — rdbl, wrbl, rdsc, chk, nested, cident
lf.py # LF commands + T55xxCommands + LFSearchResult
flash.py # pure-Python firmware flasher (OLD-frame bootloader protocol)
_firmware.py # firmware pin (matches_pin) — the fork build pm3py corresponds to
flash_cli.py # `pm3flash` console-script (detect → build/resolve → flash → verify)
trace/ # firmware trace infrastructure (shared by sniff, sim, reader)
trace.py # parse_tracelog, TRACELOG_HDR_SIZE
decode_iso15.py # ISO 15693 command/response decoders
@@ -137,6 +140,25 @@ Design doc: `docs/PYTHON_SIM_DESIGN.md`. Firmware patch in `firmware/` submodule
Firmware maintenance: atomic single-file commits for easy rebase against upstream PM3. See design doc for CI workflow.
## Firmware flashing
pm3py flashes the fork firmware itself (`pm3.flasher`, `pm3flash` CLI) — no C `pm3-flash`.
Key facts for maintainers:
- **OLD frame, not NG.** The bootloader speaks the legacy 544-byte fixed frame (no
magic/CRC); `core/transport.py` has `send_old`/`reopen`, `core/flash.py` the `Flasher`.
- **fullimage-only by default.** The bootrom region is refused unless `allow_bootrom=True`
a bad OS write is recoverable (proven on hardware); a bad bootrom write bricks to JTAG.
- **Merge segments sharing a flash page** (`build_blocks`): the SAM7 erase-programs whole
pages, so two adjacent PT_LOAD segments landing in one page must be written once with both
segments' data (else 0xFF padding clobbers real bytes — the on-hardware bug we hit).
- **Platform ≠ is_rdv4.** `is_rdv4` is the running firmware's compile-time flag, not the
board, so `--build`/`build_firmware` require an explicit `PLATFORM` (`PM3GENERIC` = Easy,
`PM3RDV4`). Build target: `make -C firmware PLATFORM=... armsrc/all`.
- **The pin.** `pm3py/_firmware.py` `FIRMWARE_PIN` is the fork build pm3py corresponds to
(currently the submodule SHA); bump it when you bump the submodule. `matches()` does a
7-char SHA-prefix test on the device version string. Auto-download of the pinned release
is the open follow-up (see the DT-Gitea migration plan).
## Adding new commands
1. Find the `CMD_*` constant in `include/pm3_cmd.h` and add to `Cmd` enum in `core/protocol.py`