Run 4 (2026-07-13): remote.push() consumed ~6 MB of PSRAM over 66 s and the UI thread aborted on Frame::new_white's per-draw vec![0xFF; 26928]. Run 5 confirmed the UI now survives, but the push still exhausts both pools (a ~7 KB inflateInit fails inside the pack build) and the heap telemetry never fired — hence the telemetry rework. - display/editor: Editor::draw_into() renders into a caller-owned Frame; main.rs keeps two boot-time frames (shown/back) and mem::swaps on success, so steady-state repaints never allocate. - git_sync: odb cache capped at 1 MB via raw libgit2-sys opts (git2 0.20 doesn't wrap the total cap); log_push_heap at pre-push, post-push and push-failure with largest-PSRAM-block and per-pool min-evers; pack_progress logging is now time-gated (2 s) — the count gate (+256 objects) never fired because AddingObjects reports total=0 and a small push inserts only dozens of objects. - editor: empty/whitespace snippets file parses as 0 snippets instead of a JSON error at boot. - build.rs: refuse a git-feature build with unset TW_* publish vars — a bare `cargo build --features git` baked empty creds and produced a firmware whose :sync could never work.
149 lines
5.9 KiB
TOML
149 lines
5.9 KiB
TOML
[package]
|
|
name = "firmware"
|
|
version = "0.6.0"
|
|
authors = ["Julien Calixte <juliencalixte@gmail.com>"]
|
|
edition = "2024"
|
|
resolver = "2"
|
|
rust-version = "1.85"
|
|
# Declare every binary explicitly so a spike program under src/bin/ doesn't get
|
|
# an auto-discovered target with the default test harness (which trips up
|
|
# rust-analyzer — see README "harness = false" note).
|
|
autobins = false
|
|
|
|
# Shared library surface (currently just resilient Wi-Fi bring-up in
|
|
# `firmware::net`), reused by the editor bin and the spike bins so the connect
|
|
# retry logic lives in exactly one place rather than being copied per binary.
|
|
[lib]
|
|
name = "firmware"
|
|
path = "src/lib.rs"
|
|
|
|
[[bin]]
|
|
name = "firmware"
|
|
path = "src/main.rs"
|
|
harness = false # do not use the built-in cargo test harness -> resolve rust-analyzer errors
|
|
|
|
# Spike 6 — Wi-Fi + TLS. Standalone bench program, kept separate from the
|
|
# editor firmware. Flash with `just flash-wifi`.
|
|
[[bin]]
|
|
name = "wifi_tls"
|
|
path = "src/bin/wifi_tls.rs"
|
|
harness = false
|
|
|
|
# Spike 3 — SD card (FAT) over the shared SPI2 bus. Standalone bench program.
|
|
# Flash with `just flash-sd`.
|
|
[[bin]]
|
|
name = "sd_fat"
|
|
path = "src/bin/sd_fat.rs"
|
|
harness = false
|
|
|
|
# SD/FAT primitive-op micro-benchmark — attributes the ~700 ms/loose-object write
|
|
# floor (see docs/tradeoff-curves/sync-commit-staging.md). Pure SD, no git feature.
|
|
# Flash with `just flash-bench`.
|
|
[[bin]]
|
|
name = "sd_bench"
|
|
path = "src/bin/sd_bench.rs"
|
|
harness = false
|
|
|
|
# git-level micro-benchmark — localizes the ~700 ms/object libgit2 overhead (see
|
|
# docs/tradeoff-curves/sync-commit-staging.md). Needs the `git` feature.
|
|
[[bin]]
|
|
name = "git_bench"
|
|
path = "src/bin/git_bench.rs"
|
|
harness = false
|
|
required-features = ["git"]
|
|
|
|
# Spike 9 — boot splash. Standalone bench program that paints the Typoena
|
|
# wordmark-in-a-circle on the EPD. No git, no SD, no Wi-Fi. Flash with
|
|
# `just flash-splash`.
|
|
[[bin]]
|
|
name = "splash"
|
|
path = "src/bin/splash.rs"
|
|
harness = false
|
|
|
|
# Spike 7 Path 2 — libgit2 link/run smoke via the git2 safe API. Gated behind
|
|
# the `git` feature so the editor build never pulls libgit2-sys/pkg-config.
|
|
# Build: cargo build --release --bin git_smoke --features git (env in justfile).
|
|
[[bin]]
|
|
name = "git_smoke"
|
|
path = "src/bin/git_smoke.rs"
|
|
harness = false
|
|
required-features = ["git"]
|
|
|
|
# Spike 7 Path 2 finish — on-device init/commit/push over mbedTLS HTTPS. Wi-Fi +
|
|
# SNTP + flash-FAT + libgit2 in one bench binary. Gated behind `git` like
|
|
# git_smoke. Build/flash with `just flash-git-push` (needs the git TW_* vars in
|
|
# .env; flashes partitions.csv so the `storage` FAT partition exists).
|
|
[[bin]]
|
|
name = "git_push"
|
|
path = "src/bin/git_push.rs"
|
|
harness = false
|
|
required-features = ["git"]
|
|
|
|
# Milestone #2A — persistent-clone publish cycle (clone + open + fast-forward
|
|
# push), the product's real git flow. Same `git` gate + TW_* env + partition
|
|
# table as git_push. Build/flash with `just flash-git-sync`.
|
|
[[bin]]
|
|
name = "git_sync"
|
|
path = "src/bin/git_sync.rs"
|
|
harness = false
|
|
required-features = ["git"]
|
|
|
|
[profile.release]
|
|
opt-level = "s"
|
|
|
|
[profile.dev]
|
|
debug = true # Symbols are nice, and they don't increase the size on Flash
|
|
opt-level = "z"
|
|
[patch.crates-io]
|
|
esp-idf-sys = { git = "https://github.com/esp-rs/esp-idf-sys.git" }
|
|
esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal.git" }
|
|
esp-idf-svc = { git = "https://github.com/esp-rs/esp-idf-svc.git" }
|
|
|
|
[features]
|
|
# A Cargo feature, OFF by default — so a bare `cargo build` (and `just
|
|
# build-light`) is a LIGHT editor build. The justfile's nominal `build`/`flash`
|
|
# opt in via `--features git`. Enabling it (a) pulls the git2 safe API and (b)
|
|
# turns on the `#[cfg(feature = "git")]` publish path in main.rs (see
|
|
# `publish()`), so git code is only ever compiled with `--features git`. libgit2
|
|
# itself is built by the esp-idf component (firmware/components/libgit2/) with
|
|
# mbedTLS — but ONLY when the justfile also sets LIBGIT2_SRC (the full recipes
|
|
# do; `build-light` doesn't, so the component is an empty no-op). git2/libgit2-sys
|
|
# run in system mode (LIBGIT2_NO_VENDOR=1) purely for the Rust bindings, with
|
|
# default features off to avoid dragging in openssl-sys/libssh2-sys.
|
|
git = ["dep:git2", "dep:libgit2-sys"]
|
|
|
|
[dependencies]
|
|
anyhow = "1"
|
|
log = "0.4"
|
|
# Pure HID decode (Key type + edge-detecting Decoder), split out so it is
|
|
# host-testable off the xtensa target. See ../keymap and MEMORY_AUDIT.md.
|
|
keymap = { path = "../keymap" }
|
|
# Editor core (buffer, motions, edits, layout/render) and the panel framebuffer,
|
|
# extracted from src/editor.rs and src/epd.rs so `cargo test` can exercise them
|
|
# off-device. The firmware links them; the host tests live in each crate.
|
|
editor = { path = "../editor" }
|
|
display = { path = "../display" }
|
|
git2 = { version = "0.20", default-features = false, optional = true }
|
|
# Already in the tree under git2 (same system-mode build); named directly for
|
|
# the raw `git_libgit2_opts` calls git2 doesn't wrap — the odb-cache cap
|
|
# (GIT_OPT_SET_CACHE_MAX_SIZE) and cache telemetry (GIT_OPT_GET_CACHED_MEMORY)
|
|
# that git_sync sets against the run-4 push OOM (2026-07-13).
|
|
libgit2-sys = { version = "0.18", default-features = false, optional = true }
|
|
esp-idf-svc = { version = "0.52.1", features = ["critical-section", "embassy-time-driver", "embassy-sync"] }
|
|
# Remove `generic-queue-8` if you plan to use `embassy-time` WITH `embassy-executor`
|
|
embassy-time = { version = "0.5", features = ["generic-queue-8"] }
|
|
embedded-graphics = "0.8"
|
|
# Traits shared with esp-idf-svc (Spike 6 uses `embedded_svc::http::Method`).
|
|
# Already in the tree via esp-idf-svc; pinned here so the spike names it directly.
|
|
embedded-svc = "0.29"
|
|
|
|
[build-dependencies]
|
|
embuild = "0.33"
|
|
|
|
# TEMPORARY — Spike 7 Path 2 Gate A probe. Builds libgit2 as an esp-idf
|
|
# component (see firmware/components/libgit2/). Compiled against on-disk source
|
|
# via LIBGIT2_SRC. Revert if the probe fails; promote (vendor the source) if it
|
|
# passes.
|
|
[[package.metadata.esp-idf-sys.extra_components]]
|
|
component_dirs = ["components/libgit2"]
|