Tag Programmer (Rust)
tagprogram-rs is the Rust port of qtprogram. It
does the same job: it programs and tests a batch of tags through a USB base
and records each one. It has the same window, checks, texts and record file.
The difference is underneath. It programs through
probe-rs and needs no
STM32CubeProgrammer, and its UI is a web page drawn by Tauri.
Layout
| Directory | What it is |
|---|---|
core/ |
tagprogram-core: the model (model/: ELF, flash plan, identity record, image, release catalog, record CSV, settings) and the engine (engine/: station, session, view state). No UI toolkit; unit tests run without hardware. |
ui/ |
The page: app.js renders the view state with Preact and the UI kit's components into index.html, laid out by app.css; mock-engine.js stands in for the engine in a plain browser; screenshots.sh captures the user manual's pictures from the two. |
app/ |
The Tauri shell: starts the engine, forwards commands and queries, emits its events, and finds the user guide. build.rs stages the page from ui/ and host/ui-kit under cargo's OUT_DIR. |
design/ |
The engine (threads, loop, station, session, hazards), building and packaging, the UI/engine contract, and qtprogram's specification, the behaviour this port reproduces. Why it was built this way: decision 0035. |
The engine owns every rule and all state; the page holds none. That split is what lets the same kit and pattern serve qtmonitor and qtcalibrate later.
In the host build and the packages
The top-level CMake build builds it with cargo (BUILD_RUST_APPS, on where
cargo is installed; the release workflow turns it on) and installs it beside
the Qt applications: tag_tools/tagprogram.app on macOS, signed with them;
tag_tools/tagprogram.exe on Windows; tag_tools/bin/tagprogram on Linux,
where it needs the system's WebKitGTK 4.1. See CMakeLists.txt.
Nothing else needs installing to build it: libusb is built from source and
linked in, and protoc comes from the protoc-bin-vendored crate. The build
writes nothing into the source tree; app/build.rs stages the page, the
configuration and Tauri's generated files under cargo's OUT_DIR.
The crates it ships are listed, with their licenses, in
LICENSES/host/tagprogram-THIRD-PARTY-NOTICES.txt. Regenerate that file
with LICENSES/tools/generate_rust_notices.py whenever Cargo.lock changes.
Building and running
cd host/applications/tagprogram-rs
cargo build -p tagprogram # the app
./target/debug/tagprogram
cargo test -p tagprogram-core # model and view tests, no hardware
To work on the page without the app or hardware, open ui/index.html in a
browser. The mock engine supplies canned states, and a switcher in the
corner changes between them.
cargo run -p tagprogram-core --example smoke -- <scratch-dir> runs the
engine headless with scratch settings. It answers the first-run question with
automatic attach off, so it lists and identifies the base but never attaches
to the tag.
cargo run -p tagprogram-core --example bench -- <scratch-dir> <release> <label> [--retest]
is qtprogram's --bench-program. It attaches (resetting the tag), programs or
retests one tag, prints each step and the record row, and exits 0 for a
written OK row.
Settings live in the platform config directory (settings.json, qtprogram's
keys). Downloaded releases go in the platform data directory under
firmware/. The record defaults to Documents/Tag Programmer/programmed-tags.csv,
as in qtprogram.
Programming path
- The base is identified with the
F6 99command (Identifying a Base). - A base that answers is driven by probe-rs's own ST-LINK driver. One that does not (older field firmware) is driven by tagprobe's field-safe driver.
tagprobe::programerases as the image's flash plan says, then programs and verifies in one session. It clearsFLASH_SR.PEMPTYon an STM32L432, then starts the image as-g 0x08000000did.- The read-back for Retest uses
tagprobe::read_memory.
The probe driver and part are reported on the Programmer and SWD rows, and probe-rs's progress goes to the log pane.
Status
- Program and Retest have passed on a BitTag (bittag-base-v7, stock driver) with fw-v0.6, through the bench runner: mass erase, program, verify, ALL_PASSED in 13 s (with the final start, stop and erase since removed), and the flash read back matching the image.
- Retest has passed on an IMUTagNandBmp581 (U375, tag-breakout-base-l432-u375-1v8, stock driver): the flash read back matching fw-v0.6, and ALL_PASSED. Programming a U375 through the engine has not been run yet.
- Program has passed on a UIUCTag (STM32L432KB) through a field base with the field-safe driver. The tagcore monitor's debug-register reads failed in a burst (status 0x81) while reconnecting after probe-rs, then recovered; tagcore now logs only the first and a count.
- Retest and Program have passed on the BitTag through a "BitTag Base V5C", the oldest base on the bench, with the field-safe driver.
- A batch of PresTags has been programmed, tag after tag, in one session.
- Built into the host packages, and built and package-tested on all three platforms by the release workflow.