One cut, no dual path. Closes ALIGNMENT defect 3 ("Arduino-CLI build
machinery is actively hostile") and vision bullet 4.
platformio.ini carries 16 [env:], one per variant, each passing
-DMEMLNAUT_MODE_TYPE; selftest passes -DNISPS_SELFTEST=1 instead. The env list
IS the registry now — the .ino comment-registry and the NISPS_ST_* token-paste
table are deleted rather than migrated. L12 noted that table was already
silently missing the currently-shipped SLPWorkshop variant, which is the whole
argument against having a second list.
Also deleted: the Python/sed machinery that rewrote the COMMITTED .ino on every
build, the sketch symlink forest, the global TFT_eSPI User_Setup.h mutation
(now -D flags — TFT_eSPI's own documented PlatformIO recipe), the UF2
boot-mount detection stack (upload_protocol=picotool talks to the bootloader
directly), and build-firmware-arch.sh entirely. Scripts 683 -> 435 lines.
memllib is vendored at lib/memllib/ from upstream e291192; no submodules
remain. VENDORED.md records provenance and the re-sync procedure.
S9: a firmware-build CI job compiles three representative envs against a cached
toolchain and reports per-variant flash/RAM. Firmware is in an automated gate
for the FIRST time. The old ci.yml comment justified excluding it as "low
verification value" — an assessment that did not survive contact, since the
SelfTest variant sat broken for an unknown period calling a DisplayDriver
method that did not exist at the pinned memllib commit, and nothing noticed
because nothing built it.
Verified: all 16 envs build from an empty cache, each within ~520 bytes of the
arduino-cli binary it replaces, flash and RAM. Measured as .text+.rodata /
.data+.bss+vector+uninitialized — NOT PlatformIO's console line, which
double-counts .data on this board. This does not prove the hardware boots; no
flash+smoke test was possible and that stays an operator chokepoint.
slpworkshop 248232/145028 pafsynth 256880/149716 selftest 216228/17960
(all 16 in the CI log format; none exceeds 2% of a 16 MB flash)
Two traps recorded so nobody rediscovers them: vendoring memllib's subdirs
without a src/ wrapper makes PlatformIO's library builder silently compile
NOTHING while still linking; and project build_flags land BEFORE the
framework's own -std=gnu++17 -Os, so build_unflags is required.
CORRECTION carried in this commit: the firmware sizes in c19d846's message and
the first version of the memllib recon doc were wrong — SLPWorkshop 145348,
PAFSynth 145300, SelfTest 141840. They came from building variants in sequence
through a SHARED incremental arduino-cli build directory, which reused stale
objects and under-reported by ~75 KB. Clean-cache rebuilds of the identical
commit give 216736/18492 for SelfTest. The real cost of the memllib upstream
bump is +216 bytes flash, not +316. Never measure firmware size through a
reused build dir.
HISTORY NOTE: this commit and the docs commit before it were rebuilt (force-push,
2026-07-21) so that each contains only what its message describes. The first
versions had the firmware deletions stranded in the docs commit by a shared-index
race between concurrent agents; content is byte-identical to the originals.
Gates: run-all-tests.sh ALL GREEN (nisps/ untouched by this change beyond
include paths); 16/16 pio envs build.
110 lines
2.9 KiB
Bash
Executable file
110 lines
2.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=./firmware-common.sh
|
|
source "$SCRIPT_DIR/firmware-common.sh"
|
|
|
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
cat <<'EOF'
|
|
Usage:
|
|
scripts/build-firmware.sh [variant]
|
|
scripts/build-firmware.sh --all
|
|
scripts/build-firmware.sh --variant VARIANT [extra `pio run` args...]
|
|
scripts/build-firmware.sh [variant] -- [extra `pio run` args...]
|
|
|
|
Builds the MEMLNaut firmware via PlatformIO (firmware/MEMLNaut-NISPS/platformio.ini).
|
|
If no variant is provided and the script is run in a TTY, it prompts from the
|
|
[env:...] sections in platformio.ini. --all builds every variant in one
|
|
PlatformIO invocation.
|
|
|
|
Requires `pio` (PlatformIO Core) on PATH — see
|
|
scripts/setup-firmware-toolchain.sh, or run under:
|
|
nix-shell -p platformio-core --run 'scripts/build-firmware.sh ...'
|
|
EOF
|
|
exit 0
|
|
fi
|
|
|
|
ensure_pio
|
|
|
|
variant_arg="${MEMLNAUT_FIRMWARE_VARIANT:-}"
|
|
build_all=0
|
|
run_extra=()
|
|
|
|
load_firmware_variants
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--all)
|
|
build_all=1
|
|
shift
|
|
;;
|
|
--variant)
|
|
if [[ $# -lt 2 ]]; then
|
|
echo "error: --variant requires a value" >&2
|
|
exit 1
|
|
fi
|
|
variant_arg="$2"
|
|
shift 2
|
|
;;
|
|
--variant=*)
|
|
variant_arg="${1#*=}"
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
run_extra+=("$@")
|
|
break
|
|
;;
|
|
-*)
|
|
# Looks like a passthrough flag for `pio run` (e.g. -v), not a variant.
|
|
run_extra+=("$1")
|
|
shift
|
|
;;
|
|
*)
|
|
# A bare word is an attempted variant name, not passthrough — resolve it
|
|
# now so a typo fails loudly instead of turning into a confusing
|
|
# "Got unexpected extra argument" error from `pio run` later.
|
|
if [[ -n "$variant_arg" ]]; then
|
|
echo "error: unexpected extra argument: $1 (variant already set to $variant_arg)" >&2
|
|
exit 1
|
|
fi
|
|
variant_arg="$(resolve_firmware_variant "$1")" || {
|
|
echo "error: unknown firmware variant: $1" >&2
|
|
echo "available variants (from $PLATFORMIO_INI):" >&2
|
|
for v in "${FIRMWARE_VARIANTS[@]}"; do
|
|
echo " - $v" >&2
|
|
done
|
|
exit 1
|
|
}
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$build_all" -eq 1 ]]; then
|
|
echo "Building ALL firmware variants: ${FIRMWARE_VARIANTS[*]}"
|
|
env_args=()
|
|
for v in "${FIRMWARE_VARIANTS[@]}"; do
|
|
env_args+=(-e "$v")
|
|
done
|
|
run_pio run "${env_args[@]}" "${run_extra[@]}"
|
|
echo
|
|
echo "UF2s ready under:"
|
|
for v in "${FIRMWARE_VARIANTS[@]}"; do
|
|
echo " $FIRMWARE_PROJECT_DIR/.pio/build/$v/firmware.uf2"
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
selected="$(choose_firmware_variant "$variant_arg")"
|
|
|
|
echo "Building firmware:"
|
|
echo " project: $FIRMWARE_PROJECT_DIR"
|
|
echo " variant: $selected"
|
|
|
|
run_pio run -e "$selected" "${run_extra[@]}"
|
|
|
|
echo
|
|
echo "UF2 ready at:"
|
|
echo " $FIRMWARE_PROJECT_DIR/.pio/build/$selected/firmware.uf2"
|