From 1622a07eb7bde9839c6d8de25a3d64b305a0d365 Mon Sep 17 00:00:00 2001 From: electron-rare <108685187+electron-rare@users.noreply.github.com> Date: Wed, 11 Mar 2026 04:04:40 +0100 Subject: [PATCH] chore(embedded): add memory-budget guardrail and audit doc updates Co-Authored-By: Claude Opus 4.6 --- readme.md | 58 +++++++++++++++++++ tools/check_memory_budget.sh | 109 +++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100755 tools/check_memory_budget.sh diff --git a/readme.md b/readme.md index 11c1733f..ebf6e34f 100644 --- a/readme.md +++ b/readme.md @@ -82,3 +82,61 @@ If you still want to try, don't use strobe, lighting or noise modes or high effe As per the MIT license, I assume no liability for any damage to you or any other person or equipment. +## Firmware memory budget gate (local fork) + +Use the local guardrail script to validate RAM/Flash budget for the active PlatformIO environment: + +```bash +./tools/check_memory_budget.sh --env ClemS-ESP32-to-5-LEDs --max-ram 75 --max-flash 85 --yes +``` + +The script runs `python3 -m platformio run`, parses `RAM:` and `Flash:` lines, and returns non-zero when thresholds are exceeded. + + + + + + + + + + + + + + + + + + + + + + + + + +## Audit & Execution Plan (2026-03-10) + +### Snapshot +- Priority: `P2` +- Tech profile: `node+python+embedded+cpp/cmake` +- Workflows: `yes` +- Tests: `yes` +- Debt markers: `40` +- Source files: `207` + +### Corrections Prioritaires +- [x] Vérifier target PlatformIO et budget mémoire +- [x] Ajouter/fiabiliser les commandes de vérification automatiques. +- [ ] Clore les points bloquants avant optimisation avancée. + +### Optimisation +- [ ] Identifier le hotspot principal et mesurer avant/après. +- [ ] Réduire la complexité des modules les plus touchés. + +### Mémoire chantier +- Control plane: `/Users/electron/.codex/memories/electron_rare_chantier` +- Repo card: `/Users/electron/.codex/memories/electron_rare_chantier/REPOS/WLED_CLS.md` + + diff --git a/tools/check_memory_budget.sh b/tools/check_memory_budget.sh new file mode 100755 index 00000000..50e2e013 --- /dev/null +++ b/tools/check_memory_budget.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat <<'EOF' +Usage: + check_memory_budget.sh [--env ] [--max-ram ] [--max-flash ] [--yes] + +Options: + --env PlatformIO env (default: ClemS-ESP32-to-5-LEDs) + --max-ram RAM threshold in percent (default: 75) + --max-flash Flash threshold in percent (default: 85) + --yes Non-interactive mode + -h, --help + +Examples: + ./tools/check_memory_budget.sh + ./tools/check_memory_budget.sh --env ClemS-ESP32-to-5-LEDs --max-ram 75 --max-flash 85 --yes +EOF +} + +env_name="ClemS-ESP32-to-5-LEDs" +max_ram="75" +max_flash="85" +non_interactive=0 + +while [[ $# -gt 0 ]]; do + case "$1" in + --env) + env_name="${2:-}" + shift 2 + ;; + --max-ram) + max_ram="${2:-}" + shift 2 + ;; + --max-flash) + max_flash="${2:-}" + shift 2 + ;; + --yes|--non-interactive) + non_interactive=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown argument: $1" >&2 + usage + exit 2 + ;; + esac +done + +if [[ "$non_interactive" -eq 0 && -t 0 && -t 1 && "$(command -v gum >/dev/null 2>&1; echo $?)" -eq 0 ]]; then + env_name="$(gum input --value "$env_name" --placeholder "PlatformIO env")" + max_ram="$(gum input --value "$max_ram" --placeholder "RAM threshold %")" + max_flash="$(gum input --value "$max_flash" --placeholder "Flash threshold %")" +fi + +tmp_log="$(mktemp -t wled-cls-mem-budget.XXXXXX.log)" +cleanup() { rm -f "$tmp_log"; } +trap cleanup EXIT + +if [[ -z "${GIT:-}" ]]; then + git_bin="$(command -v git || true)" + [[ -n "$git_bin" ]] && export GIT="$git_bin" +fi + +echo "[RUN] python3 -m platformio run -e $env_name" +python3 -m platformio run -e "$env_name" | tee "$tmp_log" + +ram_line="$(grep -E '^RAM:' "$tmp_log" | tail -n1 || true)" +flash_line="$(grep -E '^Flash:' "$tmp_log" | tail -n1 || true)" + +if [[ -z "$ram_line" || -z "$flash_line" ]]; then + echo "[ERR] RAM/Flash lines not found in PlatformIO output" >&2 + exit 1 +fi + +ram_pct="$(echo "$ram_line" | sed -E 's/.* ([0-9]+([.][0-9]+)?)% .*/\1/')" +flash_pct="$(echo "$flash_line" | sed -E 's/.* ([0-9]+([.][0-9]+)?)% .*/\1/')" +ram_used="$(echo "$ram_line" | sed -E 's/.*[(]used ([0-9]+) bytes from ([0-9]+) bytes[)].*/\1\/\2/')" +flash_used="$(echo "$flash_line" | sed -E 's/.*[(]used ([0-9]+) bytes from ([0-9]+) bytes[)].*/\1\/\2/')" + +echo "[INFO] env=$env_name" +echo "[INFO] RAM : ${ram_pct}% ($ram_used), threshold=${max_ram}%" +echo "[INFO] Flash : ${flash_pct}% ($flash_used), threshold=${max_flash}%" + +ram_over="$(awk "BEGIN {print ($ram_pct > $max_ram) ? 1 : 0}")" +flash_over="$(awk "BEGIN {print ($flash_pct > $max_flash) ? 1 : 0}")" + +status=0 +if [[ "$ram_over" -eq 1 ]]; then + echo "[FAIL] RAM usage above threshold" + status=1 +fi +if [[ "$flash_over" -eq 1 ]]; then + echo "[FAIL] Flash usage above threshold" + status=1 +fi + +if [[ "$status" -eq 0 ]]; then + echo "[PASS] memory budget within thresholds" +fi + +exit "$status"