mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 16:51:12 -07:00
BRINGUP describes the present: the 54-test catalog and its seven-test always core, the tier counts, the shipped low-temperature gates, the density floor ($35 = 10), the two local core commits, the ffboot env write, the aa-offset route, the current bench image, and the bench measurements the audit asks for (pooled into the next session). The workstation shell notes and every em dash are gone. forgetest: the takeover waits for the cloud client too (found by its command line); the unauthenticated /boot probe names the endpoint's parameter; the UI prose is American English. Recipes: forgetest fetches its package directory and init script only and drops __pycache__ at unpack; the dev image no longer re-adds forgectrl; the release image's remove list drops the gfui-client the BSP no longer has; the platform identity strips the kernel's local-version hash from the modules directory name, so a re-patched kernel keeps its fingerprints. grblhal restart is stop then start. release.sh --dev packs the dev image. fixture.sh refuses a readable env file. Bench tools: the live-fire drills measure the lid-IR baseline before every run and point at the fire-watch thresholds the engine reads; one thermistor conversion (gfbench.degc) serves every drill; the six dated measurement records leave the tool directory; feeder.c names the two sysfs writes its caller makes. Host tests: forgetest 258 pass; the coverage lint reports no uncovered path across 54 tests. Acceptance: forgectrl.auth covers the /boot probe; update.* cover ffboot and the manifest identity; the runbook and bench-tool changes have no catalog consequence.
105 lines
3.7 KiB
Bash
105 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
# forgefixture: build, flash and watch the bench actuator's firmware.
|
|
#
|
|
# ./fixture.sh env fixture.env from the example, with a fresh API key
|
|
# ./fixture.sh build build (native idf.py if installed, else the IDF container)
|
|
# ./fixture.sh flash [PORT] write the build to the board over USB (esptool)
|
|
# ./fixture.sh monitor [PORT] the board's log (idf.py monitor, or pyserial's miniterm)
|
|
# ./fixture.sh test the host test of the policy (needs a C compiler)
|
|
#
|
|
# The container build needs docker or podman and pulls espressif/idf once
|
|
# (IDF_IMAGE below); flashing never runs in the container: esptool is a
|
|
# pip package (pip install esptool) and talks to the port directly.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
IDF_IMAGE="${IDF_IMAGE:-docker.io/espressif/idf:v5.5.5}"
|
|
CHIP=esp32s3
|
|
BAUD="${BAUD:-460800}"
|
|
|
|
have() { command -v "$1" >/dev/null 2>&1; }
|
|
|
|
runner() {
|
|
if have docker; then echo docker; elif have podman; then echo podman; else
|
|
echo "neither idf.py nor docker/podman found: install ESP-IDF, or a container runtime for $IDF_IMAGE" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# A Windows path for the bind mount when run from Git Bash, which would
|
|
# otherwise rewrite /project into a Windows path.
|
|
host_path() {
|
|
if have cygpath; then cygpath -w "$PWD"; else echo "$PWD"; fi
|
|
}
|
|
|
|
cmd_env() {
|
|
if [ -e fixture.env ]; then
|
|
echo "fixture.env exists; edit it, or remove it first" >&2
|
|
exit 1
|
|
fi
|
|
key=$( (have openssl && openssl rand -hex 16) || python3 -c 'import secrets; print(secrets.token_hex(16))')
|
|
sed -e "s/^API_KEY=.*/API_KEY=$key/" fixture.env.example > fixture.env
|
|
chmod 600 fixture.env 2>/dev/null || true
|
|
echo "fixture.env written with a fresh API key; fill in WIFI_SSID and WIFI_PSK"
|
|
}
|
|
|
|
cmd_build() {
|
|
[ -e fixture.env ] || { echo "no fixture.env: run ./fixture.sh env first" >&2; exit 1; }
|
|
# The file holds the WiFi PSK and the API key: nobody but the owner
|
|
# reads it (an MSYS shell cannot express the mode, so it is not judged).
|
|
if [ "$(uname -o 2>/dev/null)" != "Msys" ] && [ -n "$(find fixture.env -perm /077 2>/dev/null)" ]; then
|
|
echo "fixture.env is group- or world-readable: chmod 600 fixture.env" >&2
|
|
exit 1
|
|
fi
|
|
if have idf.py; then
|
|
idf.py set-target "$CHIP" >/dev/null
|
|
idf.py build
|
|
else
|
|
r=$(runner)
|
|
MSYS_NO_PATHCONV=1 "$r" run --rm -v "$(host_path):/project" -w /project -e HOME=/tmp "$IDF_IMAGE" \
|
|
bash -c "idf.py set-target $CHIP >/dev/null && idf.py build"
|
|
fi
|
|
}
|
|
|
|
port_arg() {
|
|
if [ -n "${1:-}" ]; then echo "$1"; elif [ -n "${PORT:-}" ]; then echo "$PORT"; else
|
|
echo "which port? ./fixture.sh flash PORT (COM5, /dev/ttyUSB0, /dev/cu.usbserial-*)" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
cmd_flash() {
|
|
port=$(port_arg "${1:-}")
|
|
[ -e build/flash_args ] || { echo "no build yet: ./fixture.sh build" >&2; exit 1; }
|
|
if have idf.py; then
|
|
idf.py -p "$port" flash
|
|
else
|
|
have esptool.py || have esptool || { echo "esptool not found: pip install esptool" >&2; exit 1; }
|
|
tool=$(have esptool.py && echo esptool.py || echo esptool)
|
|
(cd build && "$tool" --chip "$CHIP" -p "$port" -b "$BAUD" --before default_reset --after hard_reset \
|
|
write_flash @flash_args)
|
|
fi
|
|
}
|
|
|
|
cmd_monitor() {
|
|
port=$(port_arg "${1:-}")
|
|
if have idf.py; then
|
|
idf.py -p "$port" monitor
|
|
else
|
|
python3 -m serial.tools.miniterm --raw "$port" 115200
|
|
fi
|
|
}
|
|
|
|
cmd_test() {
|
|
sh test/run.sh
|
|
}
|
|
|
|
case "${1:-}" in
|
|
env) cmd_env ;;
|
|
build) cmd_build ;;
|
|
flash) cmd_flash "${2:-}" ;;
|
|
monitor) cmd_monitor "${2:-}" ;;
|
|
test) cmd_test ;;
|
|
*) sed -n '2,12p' "$0"; exit 1 ;;
|
|
esac
|