upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-19 03:10:04 +0530
committerYour Name <you@example.com>2026-05-19 03:10:04 +0530
commit1232a43f17cd4c1d994b2d652060d4fc9e1053ea (patch)
treeef552a7cd0ca92dcf2ec0d063f00089f315c3ee0
parentd21fc93c4b7d025d99ecc7c15b3998dbdebf076c (diff)
fix: add per-board mutex locks to flash targets
flash-a and flash-b now require lock-a/lock-b to be held before flashing. Prevents cross-session hardware conflicts when multiple LLM agents share the same ESP32 boards. Lock infrastructure matches main repo and price-discovery worktrees: - HARDWARE_LOCK_DIR = physical-router-test-automation/locks - require_lock_a/require_lock_b macros - lock-a/lock-b/unlock-a/unlock-b/force-unlock-a/force-unlock-b/lock-status targets
-rw-r--r--Makefile112
1 files changed, 108 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index c84acdf..1de5c5a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,52 @@ PORT ?= $(PORT_A)
13BAUD ?= 460800 13BAUD ?= 460800
14TARGET ?= esp32s3 14TARGET ?= esp32s3
15 15
16HARDWARE_LOCK_DIR := /home/c03rad0r/physical-router-test-automation/locks
17
18RED := \033[31m
19GREEN := \033[32m
20YELLOW := \033[33m
21BOLD := \033[1m
22RESET := \033[0m
23
24define require_lock_a
25 @if [ ! -f "$(HARDWARE_LOCK_DIR)/board-a.lock" ]; then \
26 echo "$(RED)$(BOLD)Board A not locked — run 'make lock-a PHASE=\"description\"' first$(RESET)"; \
27 echo "$(YELLOW)Another LLM session may be using Board A.$(RESET)"; \
28 exit 1; \
29 fi
30endef
31
32define require_lock_b
33 @if [ ! -f "$(HARDWARE_LOCK_DIR)/board-b.lock" ]; then \
34 echo "$(RED)$(BOLD)Board B not locked — run 'make lock-b PHASE=\"description\"' first$(RESET)"; \
35 echo "$(YELLOW)Another LLM session may be using Board B.$(RESET)"; \
36 exit 1; \
37 fi
38endef
39
40define _acquire_lock
41 @if [ -f "$(HARDWARE_LOCK_DIR)/$(1).lock" ]; then \
42 echo "$(RED)$(BOLD)Cannot acquire lock — $(1) already locked:$(RESET)"; \
43 echo ""; \
44 cat $(HARDWARE_LOCK_DIR)/$(1).lock | sed 's/^/ /'; \
45 echo ""; \
46 echo "$(YELLOW)Use 'make force-unlock-$(1)' to override.$(RESET)"; \
47 exit 1; \
48 fi; \
49 branch=$$(git branch --show-current 2>/dev/null || echo "unknown"); \
50 worktree=$$(pwd); \
51 echo "locked: true" > $(HARDWARE_LOCK_DIR)/$(1).lock; \
52 echo "board: $(1)" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
53 echo "branch: $$branch" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
54 echo "worktree: $$worktree" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
55 echo "session: $$USER@$$HOSTNAME" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
56 echo "timestamp: $$(date -u '+%Y-%m-%dT%H:%M:%SZ')" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
57 echo "phase: $(PHASE)" >> $(HARDWARE_LOCK_DIR)/$(1).lock; \
58 echo "$(GREEN)$(BOLD)$(1) lock acquired$(RESET)"; \
59 cat $(HARDWARE_LOCK_DIR)/$(1).lock
60endef
61
16NODE ?= node 62NODE ?= node
17NPM ?= npm 63NPM ?= npm
18PYTHON ?= python3 64PYTHON ?= python3
@@ -27,6 +73,7 @@ TOLLGATE_IP ?= 10.192.45.1
27.PHONY: tokens wallet-setup wallet-info wallet-balance mint-token send-token 73.PHONY: tokens wallet-setup wallet-info wallet-balance mint-token send-token
28.PHONY: clean erase-nvs reset serial-log bootstrap-config 74.PHONY: clean erase-nvs reset serial-log bootstrap-config
29.PHONY: cvm-pubkey cvm-test-tool cvm-announce 75.PHONY: cvm-pubkey cvm-test-tool cvm-announce
76.PHONY: lock-a lock-b unlock-a unlock-b force-unlock-a force-unlock-b lock-status
30 77
31help: 78help:
32 @echo "TollGate ESP32 — Makefile" 79 @echo "TollGate ESP32 — Makefile"
@@ -131,11 +178,15 @@ flash: build
131 @echo "=== Flashing to $(PORT) ===" 178 @echo "=== Flashing to $(PORT) ==="
132 . $(IDF_PATH)/export.sh && idf.py -p $(PORT) -b $(BAUD) flash 179 . $(IDF_PATH)/export.sh && idf.py -p $(PORT) -b $(BAUD) flash
133 180
134flash-a: PORT=$(PORT_A) 181flash-a: build
135flash-a: flash 182 $(call require_lock_a)
183 @echo "=== Flashing to $(PORT_A) (Board A) ==="
184 . $(IDF_PATH)/export.sh && idf.py -p $(PORT_A) -b $(BAUD) flash
136 185
137flash-b: PORT=$(PORT_B) 186flash-b: build
138flash-b: flash 187 $(call require_lock_b)
188 @echo "=== Flashing to $(PORT_B) (Board B) ==="
189 . $(IDF_PATH)/export.sh && idf.py -p $(PORT_B) -b $(BAUD) flash
139 190
140build: 191build:
141 @echo "=== Building $(TARGET) ===" 192 @echo "=== Building $(TARGET) ==="
@@ -293,3 +344,56 @@ bootstrap-config:
293 @echo "=== Bootstrapping config.json ===" 344 @echo "=== Bootstrapping config.json ==="
294 @echo '{"wifi_networks":[{"ssid":"$(WIFI_SSID)","password":"$(WIFI_PASSWORD)"}],"ap_ssid":"$(AP_SSID)","ap_password":"$(AP_PASSWORD)","mint_url":"$(MINT_URL)","lnurl_url":"$(LNURL_URL)","price_per_step":$(PRICE_PER_STEP),"step_size_ms":$(STEP_SIZE)}' > main/config.json 345 @echo '{"wifi_networks":[{"ssid":"$(WIFI_SSID)","password":"$(WIFI_PASSWORD)"}],"ap_ssid":"$(AP_SSID)","ap_password":"$(AP_PASSWORD)","mint_url":"$(MINT_URL)","lnurl_url":"$(LNURL_URL)","price_per_step":$(PRICE_PER_STEP),"step_size_ms":$(STEP_SIZE)}' > main/config.json
295 @echo "Config written to main/config.json" 346 @echo "Config written to main/config.json"
347
348# ──────────────────────────────────────────────
349# Board Lock Management
350# ──────────────────────────────────────────────
351
352lock-a:
353 @$(call _acquire_lock,board-a)
354
355lock-b:
356 @$(call _acquire_lock,board-b)
357
358unlock-a:
359 @if [ -f "$(HARDWARE_LOCK_DIR)/board-a.lock" ]; then \
360 rm $(HARDWARE_LOCK_DIR)/board-a.lock; \
361 echo "$(GREEN)Board A lock released.$(RESET)"; \
362 else \
363 echo "$(YELLOW)Board A not locked.$(RESET)"; \
364 fi
365
366unlock-b:
367 @if [ -f "$(HARDWARE_LOCK_DIR)/board-b.lock" ]; then \
368 rm $(HARDWARE_LOCK_DIR)/board-b.lock; \
369 echo "$(GREEN)Board B lock released.$(RESET)"; \
370 else \
371 echo "$(YELLOW)Board B not locked.$(RESET)"; \
372 fi
373
374force-unlock-a:
375 @echo "$(RED)$(BOLD)WARNING: Force-releasing Board A lock!$(RESET)"
376 @cat $(HARDWARE_LOCK_DIR)/board-a.lock 2>/dev/null | sed 's/^/ /' || true
377 @rm -f $(HARDWARE_LOCK_DIR)/board-a.lock
378 @echo "$(GREEN)Board A lock force-released.$(RESET)"
379
380force-unlock-b:
381 @echo "$(RED)$(BOLD)WARNING: Force-releasing Board B lock!$(RESET)"
382 @cat $(HARDWARE_LOCK_DIR)/board-b.lock 2>/dev/null | sed 's/^/ /' || true
383 @rm -f $(HARDWARE_LOCK_DIR)/board-b.lock
384 @echo "$(GREEN)Board B lock force-released.$(RESET)"
385
386lock-status:
387 @echo "$(BOLD)Board Lock Status$(RESET)"
388 @if [ -f "$(HARDWARE_LOCK_DIR)/board-a.lock" ]; then \
389 echo "Board a: $(YELLOW)LOCKED$(RESET)"; \
390 cat $(HARDWARE_LOCK_DIR)/board-a.lock | sed 's/^/ /'; \
391 else \
392 echo "Board a: $(GREEN)available$(RESET)"; \
393 fi
394 @if [ -f "$(HARDWARE_LOCK_DIR)/board-b.lock" ]; then \
395 echo "Board b: $(YELLOW)LOCKED$(RESET)"; \
396 cat $(HARDWARE_LOCK_DIR)/board-b.lock | sed 's/^/ /'; \
397 else \
398 echo "Board b: $(GREEN)available$(RESET)"; \
399 fi