mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
Add external-flash overlay app platform
This commit is contained in:
1 parent
3f958f637d
commit
f35408317e
35 files changed
+3255
-295
No files matched your search
Executable
+126
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build overlay-app blobs (.app), the counterpart of compile-firmware.sh.
|
||||
#
|
||||
# Usage:
|
||||
# ./compile-app.sh # build every app
|
||||
# ./compile-app.sh All # build every app
|
||||
# ./compile-app.sh breakout # build one app
|
||||
# ./compile-app.sh fm foxhunt # build several apps
|
||||
#
|
||||
# Each app is compiled in the uvk1-uvk5v3 Docker image, linked at the pinned
|
||||
# overlay VMA, packed into build/Apps/<Name>.app (named after the app's human
|
||||
# label, spaces stripped), and reported against the 4 KiB overlay budget. Apps
|
||||
# are auto-discovered from App/apps/<name>/build.sh.
|
||||
# ---------------------------------------------------------------------------
|
||||
set -euo pipefail
|
||||
|
||||
IMAGE=uvk1-uvk5v3
|
||||
APPS_DIR=App/apps
|
||||
OUT_DIR=build/Apps
|
||||
OVERLAY_MAX=4096
|
||||
APP_VMA=${APP_VMA:-0x20000280} # pinned overlay VMA (Core/py32f071xb.ld)
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# --- discover apps (any App/apps/<name>/build.sh) ---
|
||||
ALL_APPS=()
|
||||
for d in "$APPS_DIR"/*/; do
|
||||
[ -f "${d}build.sh" ] && ALL_APPS+=("$(basename "$d")")
|
||||
done
|
||||
if [ "${#ALL_APPS[@]}" -eq 0 ]; then
|
||||
echo "❌ No apps found under $APPS_DIR/*/build.sh"; exit 1
|
||||
fi
|
||||
|
||||
# --- select targets ---
|
||||
if [ "$#" -eq 0 ] || [ "${1,,}" = "all" ]; then
|
||||
TARGETS=("${ALL_APPS[@]}")
|
||||
else
|
||||
TARGETS=()
|
||||
for want in "$@"; do
|
||||
ok=0
|
||||
for a in "${ALL_APPS[@]}"; do [ "$a" = "$want" ] && ok=1; done
|
||||
if [ "$ok" -eq 0 ]; then
|
||||
echo "❌ Unknown app '$want'. Available: ${ALL_APPS[*]} (or All)"; exit 1
|
||||
fi
|
||||
TARGETS+=("$want")
|
||||
done
|
||||
fi
|
||||
|
||||
command -v docker >/dev/null 2>&1 || { echo "❌ docker not found"; exit 1; }
|
||||
if [[ "$(docker images -q "$IMAGE")" == "" ]]; then
|
||||
echo "🐳 Building Docker image..."; docker build -q -t "$IMAGE" . >/dev/null
|
||||
fi
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
# Give the container a pseudo-TTY when we are interactive, so build.sh's
|
||||
# single-line [k/3] progress refreshes in place (same trick as the firmware
|
||||
# build gives Ninja). Batch/redirected runs stay plain and line-oriented.
|
||||
TTY_ARGS=(); [[ -t 1 ]] && TTY_ARGS=(-t)
|
||||
|
||||
echo
|
||||
echo "🚀 Building overlay apps"
|
||||
printf ' VMA %s · budget %d B / %d.00 KiB · out %s/\n\n' \
|
||||
"$APP_VMA" "$OVERLAY_MAX" "$((OVERLAY_MAX / 1024))" "$OUT_DIR"
|
||||
|
||||
files=(); sizes=(); vmas=(); states=()
|
||||
fail=0
|
||||
|
||||
read_u32le() { od -An -tx1 -j"$2" -N4 "$1" | awk '{printf "0x%s%s%s%s",$4,$3,$2,$1}'; }
|
||||
|
||||
for app in "${TARGETS[@]}"; do
|
||||
if docker run --rm "${TTY_ARGS[@]}" -u "$(id -u):$(id -g)" \
|
||||
-v "$PWD":/work -w "/work/$APPS_DIR/$app" \
|
||||
-e PATH="/opt/toolchain/bin:/usr/bin:/bin" -e APP_VMA="$APP_VMA" \
|
||||
"$IMAGE" bash ./build.sh; then
|
||||
appfile=$(ls -1 "$APPS_DIR/$app"/*.app 2>/dev/null | head -1)
|
||||
if [ -n "$appfile" ] && [ -f "$appfile" ]; then
|
||||
cp -f "$appfile" "$OUT_DIR/"
|
||||
base=$(basename "$appfile")
|
||||
code=$(( $(wc -c < "$appfile") - 64 ))
|
||||
vma=$(read_u32le "$appfile" 52)
|
||||
state="✅ OK"; [ "$code" -gt "$OVERLAY_MAX" ] && { state="🚨 OVERFLOW"; fail=1; }
|
||||
else
|
||||
base="$app.app"; code=-1; vma="--"; state="❌ NO BLOB"; fail=1
|
||||
fi
|
||||
else
|
||||
base="$app.app"; code=-1; vma="--"; state="❌ BUILD FAIL"; fail=1
|
||||
fi
|
||||
files+=("$base"); sizes+=("$code"); vmas+=("$vma"); states+=("$state")
|
||||
done
|
||||
|
||||
# --- memory report (styled like the firmware Flash/RAM tables) ---
|
||||
echo
|
||||
printf '📦 Overlay apps (budget: %d B / %d.00 KiB)\n' "$OVERLAY_MAX" "$((OVERLAY_MAX / 1024))"
|
||||
printf '%-16s | %9s | %9s | %9s | %9s | %7s | %s\n' \
|
||||
"File" "Code (B)" "Code(KiB)" "Free (B)" "Free(KiB)" "Usage" "Status"
|
||||
printf '%-16s-+-%9s-+-%9s-+-%9s-+-%9s-+-%7s-+-%s\n' \
|
||||
"----------------" "---------" "---------" "---------" "---------" "-------" "----------"
|
||||
for i in "${!files[@]}"; do
|
||||
c=${sizes[$i]}
|
||||
if [ "$c" -ge 0 ]; then
|
||||
free=$(( OVERLAY_MAX - c ))
|
||||
bp=$(( (c * 10000 + OVERLAY_MAX / 2) / OVERLAY_MAX ))
|
||||
ck100=$(( (c * 100 + 512) / 1024 )); fk100=$(( (free * 100 + 512) / 1024 ))
|
||||
printf -v pct '%d.%02d%%' "$((bp/100))" "$((bp%100))"
|
||||
printf -v ckib '%d.%02d' "$((ck100/100))" "$((ck100%100))"
|
||||
printf -v fkib '%d.%02d' "$((fk100/100))" "$((fk100%100))"
|
||||
printf '%-16s | %9d | %9s | %9d | %9s | %7s | %s\n' \
|
||||
"${files[$i]}" "$c" "$ckib" "$free" "$fkib" "$pct" "${states[$i]}"
|
||||
else
|
||||
printf '%-16s | %9s | %9s | %9s | %9s | %7s | %s\n' \
|
||||
"${files[$i]}" "-" "-" "-" "-" "-" "${states[$i]}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
if [ "$fail" -eq 0 ]; then
|
||||
if [ "${#files[@]}" -eq 1 ]; then
|
||||
echo "🎉 App ${files[0]} built successfully -> $OUT_DIR/"
|
||||
else
|
||||
echo "🎉 All ${#files[@]} apps built successfully -> $OUT_DIR/"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Some apps failed or overflowed — see the table above."
|
||||
fi
|
||||
exit $fail
|
||||
Reference in new issue
Block a user