more on esp_deploy
This commit is contained in:
parent
ddc0ab185f
commit
6ce2de5088
|
|
@ -3,6 +3,7 @@
|
||||||
ESP32 Unified Deployment Tool (esp32_deploy)
|
ESP32 Unified Deployment Tool (esp32_deploy)
|
||||||
Combines firmware flashing and device configuration with full control.
|
Combines firmware flashing and device configuration with full control.
|
||||||
Updates:
|
Updates:
|
||||||
|
- FIXED: Indentation errors in class methods
|
||||||
- FIXED: Overlap error caused by swapping ota_data_initial.bin with main app
|
- FIXED: Overlap error caused by swapping ota_data_initial.bin with main app
|
||||||
- '--target auto' support for mixed-device flashing
|
- '--target auto' support for mixed-device flashing
|
||||||
- 'target all' support (Build 12 configurations)
|
- '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)
|
suffix = generate_config_suffix(target_to_use, self.args.csi_enable, self.args.ampdu)
|
||||||
firmware_dir = self.project_dir / "firmware"
|
firmware_dir = self.project_dir / "firmware"
|
||||||
|
|
||||||
# Find unique binary
|
# Find unique binary for this specific target config
|
||||||
unique_app = None
|
unique_app = None
|
||||||
if firmware_dir.exists():
|
if firmware_dir.exists():
|
||||||
for f in os.listdir(firmware_dir):
|
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
|
unique_app = f
|
||||||
break
|
break
|
||||||
|
|
||||||
if not unique_app:
|
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
|
return False
|
||||||
|
|
||||||
unique_boot = f"bootloader_{suffix}.bin"
|
unique_boot = f"bootloader_{suffix}.bin"
|
||||||
|
|
@ -164,21 +165,25 @@ class UnifiedDeployWorker:
|
||||||
raw_args = [x for x in content.split(' ') if x]
|
raw_args = [x for x in content.split(' ') if x]
|
||||||
final_args = []
|
final_args = []
|
||||||
|
|
||||||
# 4. Construct Flash Command (Swap paths safely)
|
# 4. Construct Flash Command (Safe Swapping)
|
||||||
for arg in raw_args:
|
for arg in raw_args:
|
||||||
if arg.endswith('bootloader.bin'):
|
if arg.endswith('bootloader.bin'):
|
||||||
final_args.append(str(firmware_dir / unique_boot))
|
final_args.append(str(firmware_dir / unique_boot))
|
||||||
elif arg.endswith('partition-table.bin'):
|
elif arg.endswith('partition-table.bin'):
|
||||||
final_args.append(str(firmware_dir / unique_part))
|
final_args.append(str(firmware_dir / unique_part))
|
||||||
elif arg.endswith('ota_data_initial.bin'):
|
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():
|
if (firmware_dir / unique_ota).exists():
|
||||||
final_args.append(str(firmware_dir / unique_ota))
|
final_args.append(str(firmware_dir / unique_ota))
|
||||||
else:
|
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)
|
final_args.append(arg)
|
||||||
elif arg.endswith('.bin'):
|
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))
|
final_args.append(str(firmware_dir / unique_app))
|
||||||
else:
|
else:
|
||||||
final_args.append(arg)
|
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}")
|
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()
|
project_dir = Path(args.dir).resolve()
|
||||||
|
|
||||||
|
# --- Target 'ALL' Mode ---
|
||||||
if args.target == 'all':
|
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']
|
targets = ['esp32', 'esp32s3', 'esp32c5']
|
||||||
booleans = [False, True]
|
booleans = [False, True]
|
||||||
results = []
|
results = []
|
||||||
total_steps = len(targets) * 4
|
|
||||||
|
total_steps = len(targets) * len(booleans) * len(booleans)
|
||||||
current_step = 0
|
current_step = 0
|
||||||
|
|
||||||
for target in targets:
|
for target in targets:
|
||||||
for csi in booleans:
|
for csi in booleans:
|
||||||
for ampdu in booleans:
|
for ampdu in booleans:
|
||||||
current_step += 1
|
current_step += 1
|
||||||
success, msg, dur = await build_task(project_dir, target, csi, ampdu, current_step, total_steps)
|
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})
|
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}")
|
print(f"\n{Colors.BLUE}Batch Summary:{Colors.RESET}")
|
||||||
for r in results:
|
for r in results:
|
||||||
status = f"{Colors.GREEN}PASS{Colors.RESET}" if r['ok'] else f"{Colors.RED}FAIL{Colors.RESET}"
|
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)")
|
print(f" {r['cfg']} : {status} ({r['dur']:.1f}s)")
|
||||||
return
|
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':
|
if not args.config_only and args.target != 'auto':
|
||||||
target = args.target if args.target else 'esp32s3'
|
target = args.target if args.target else 'esp32s3'
|
||||||
csi = args.csi_enable
|
csi = args.csi_enable
|
||||||
ampdu = args.ampdu
|
ampdu = args.ampdu
|
||||||
|
|
||||||
if args.interactive:
|
if args.interactive:
|
||||||
print(f"\n{Colors.YELLOW}--- Build Configuration ---{Colors.RESET}")
|
print(f"\n{Colors.YELLOW}--- Build Configuration ---{Colors.RESET}")
|
||||||
target = ask_user("Target Chip", default=target, choices=['esp32', 'esp32s3', 'esp32c5'])
|
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.csi_enable = csi
|
||||||
args.target = target
|
args.target = target
|
||||||
args.ampdu = ampdu
|
args.ampdu = ampdu
|
||||||
|
|
||||||
success, msg, _ = await build_task(project_dir, target, csi, ampdu, 1, 1)
|
success, msg, _ = await build_task(project_dir, target, csi, ampdu, 1, 1)
|
||||||
if not success:
|
if not success:
|
||||||
print(f"{Colors.RED}{msg}{Colors.RESET}")
|
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:
|
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}")
|
print(f"{Colors.YELLOW}Target 'auto' selected. Skipping build step (assuming artifacts in firmware/).{Colors.RESET}")
|
||||||
|
|
||||||
|
# --- Device Detection & Flash ---
|
||||||
if args.devices:
|
if args.devices:
|
||||||
devs = [type('obj', (object,), {'device': d.strip()}) for d in args.devices.split(',')]
|
devs = [type('obj', (object,), {'device': d.strip()}) for d in args.devices.split(',')]
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue