more on esp_deploy

This commit is contained in:
Bob 2025-12-11 11:20:53 -08:00
parent ddc0ab185f
commit 6ce2de5088
1 changed files with 39 additions and 10 deletions

View File

@ -3,6 +3,7 @@
ESP32 Unified Deployment Tool (esp32_deploy)
Combines firmware flashing and device configuration with full control.
Updates:
- FIXED: Indentation errors in class methods
- FIXED: Overlap error caused by swapping ota_data_initial.bin with main app
- '--target auto' support for mixed-device flashing
- 'target all' support (Build 12 configurations)
@ -134,16 +135,16 @@ class UnifiedDeployWorker:
suffix = generate_config_suffix(target_to_use, self.args.csi_enable, self.args.ampdu)
firmware_dir = self.project_dir / "firmware"
# Find unique binary
# Find unique binary for this specific target config
unique_app = None
if firmware_dir.exists():
for f in os.listdir(firmware_dir):
if f.endswith(f"_{suffix}.bin") and not f.startswith("bootloader") and not f.startswith("partition"):
if f.endswith(f"_{suffix}.bin") and not f.startswith("bootloader") and not f.startswith("partition") and not f.startswith("ota_data") and not f.startswith("phy_init"):
unique_app = f
break
if not unique_app:
self.log.error(f"Binary for config '{suffix}' not found in firmware/.")
self.log.error(f"Binary for config '{suffix}' not found in firmware/. Run --target all first?")
return False
unique_boot = f"bootloader_{suffix}.bin"
@ -164,21 +165,25 @@ class UnifiedDeployWorker:
raw_args = [x for x in content.split(' ') if x]
final_args = []
# 4. Construct Flash Command (Swap paths safely)
# 4. Construct Flash Command (Safe Swapping)
for arg in raw_args:
if arg.endswith('bootloader.bin'):
final_args.append(str(firmware_dir / unique_boot))
elif arg.endswith('partition-table.bin'):
final_args.append(str(firmware_dir / unique_part))
elif arg.endswith('ota_data_initial.bin'):
# Fix: Handle OTA data specifically so it doesn't get swapped with app
# Only use unique if it exists, otherwise assume standard path relative to build (risky if build gone)
if (firmware_dir / unique_ota).exists():
final_args.append(str(firmware_dir / unique_ota))
else:
# Fallback to standard if unique doesn't exist (though it should)
# Skip if missing to avoid error
self.log.warning(f"OTA binary {unique_ota} missing. Skipping arg to prevent crash.")
continue
elif arg.endswith('phy_init_data.bin'):
# System binary: Do NOT replace with App.
final_args.append(arg)
elif arg.endswith('.bin'):
# This catch-all must exclude partition/bootloader/ota
# This catch-all is for the MAIN APP only.
final_args.append(str(firmware_dir / unique_app))
else:
final_args.append(arg)
@ -431,29 +436,51 @@ async def run_deployment(args):
print(f"\n{Colors.BLUE}{'='*60}{Colors.RESET}\n ESP32 Unified Deployment Tool\n{Colors.BLUE}{'='*60}{Colors.RESET}")
project_dir = Path(args.dir).resolve()
# --- Target 'ALL' Mode ---
if args.target == 'all':
print(f"{Colors.YELLOW}Starting Batch Build Verification (12 Combinations){Colors.RESET}\n")
print(f"{Colors.YELLOW}Starting Batch Build Verification (12 Combinations){Colors.RESET}")
# SAFETY: Wipe firmware dir to ensure no stale binaries exist
firmware_dir = project_dir / "firmware"
if firmware_dir.exists():
try:
shutil.rmtree(firmware_dir)
print(f"{Colors.YELLOW} [Clean] Removed old firmware/ directory.{Colors.RESET}")
except Exception as e:
print(f"{Colors.RED} [Error] Could not clean firmware dir: {e}{Colors.RESET}")
return
# Re-create it fresh
firmware_dir.mkdir(exist_ok=True)
print("") # Spacer
targets = ['esp32', 'esp32s3', 'esp32c5']
booleans = [False, True]
results = []
total_steps = len(targets) * 4
total_steps = len(targets) * len(booleans) * len(booleans)
current_step = 0
for target in targets:
for csi in booleans:
for ampdu in booleans:
current_step += 1
success, msg, dur = await build_task(project_dir, target, csi, ampdu, current_step, total_steps)
results.append({"cfg": f"{target.ljust(9)} CSI:{'ON ' if csi else 'OFF'} AMPDU:{'ON ' if ampdu else 'OFF'}", "ok": success, "dur": dur})
print(f"\n{Colors.BLUE}Batch Summary:{Colors.RESET}")
for r in results:
status = f"{Colors.GREEN}PASS{Colors.RESET}" if r['ok'] else f"{Colors.RED}FAIL{Colors.RESET}"
print(f" {r['cfg']} : {status} ({r['dur']:.1f}s)")
return
# --- Single Build Configuration ---
# Skip build if we are in AUTO mode (we assume binaries exist in firmware/)
if not args.config_only and args.target != 'auto':
target = args.target if args.target else 'esp32s3'
csi = args.csi_enable
ampdu = args.ampdu
if args.interactive:
print(f"\n{Colors.YELLOW}--- Build Configuration ---{Colors.RESET}")
target = ask_user("Target Chip", default=target, choices=['esp32', 'esp32s3', 'esp32c5'])
@ -462,6 +489,7 @@ async def run_deployment(args):
args.csi_enable = csi
args.target = target
args.ampdu = ampdu
success, msg, _ = await build_task(project_dir, target, csi, ampdu, 1, 1)
if not success:
print(f"{Colors.RED}{msg}{Colors.RESET}")
@ -469,6 +497,7 @@ async def run_deployment(args):
elif args.target == 'auto' and not args.config_only:
print(f"{Colors.YELLOW}Target 'auto' selected. Skipping build step (assuming artifacts in firmware/).{Colors.RESET}")
# --- Device Detection & Flash ---
if args.devices:
devs = [type('obj', (object,), {'device': d.strip()}) for d in args.devices.split(',')]
else: