fix: two-phase boot wait — don't stop on version when IP still pending

Previously the boot wait loop broke on the first detection of EITHER
IP or version. The Zynq firmware outputs its version string early in
the boot sequence (e.g. firmware header), while the board IP arrives
in a later burst via 'Boot=, IP=192.168.100.13, Ver=...'. The loop
would break on the version-only signal, leaving IP empty.

Changes:
1. Phase 1: log boot signal (version) but keep polling for IP
2. Phase 2: break only when IP address is actually found
3. After timeout: final check of latest_info for late-arriving IP
4. UART buffer fallback: parse all accumulated lines for IP
   (handles lines that arrived between the last poll and exit)
5. 3s pre-scan delay before UDP discover to let network stack settle
   (board's UDP server starts at the very end of boot sequence)
This commit is contained in:
2026-06-11 15:41:21 +08:00
parent 267cae93b6
commit 1619dc194f
+41 -3
View File
@@ -1158,25 +1158,63 @@ class MainWindow(ctk.CTk):
if uart_alive and _uart_src:
self._log_message(f" ⏳ Waiting for UART boot signal (max {boot_delay}s)...")
elapsed = 0.0
boot_seen = False # Phase 1 guard — log once, keep waiting for IP
while elapsed < boot_delay:
info = _uart_src.latest_info if hasattr(_uart_src, 'latest_info') else _uart_src.get_latest_info()
if info and (info.ip_address or info.version):
info = (
_uart_src.latest_info
if hasattr(_uart_src, "latest_info")
else _uart_src.get_latest_info()
)
# Phase 2: IP address found — definitive boot confirmation
if info and info.ip_address:
self._log_message(
f" ✓ Boot detected after {elapsed:.1f}s"
f" (IP={info.ip_address}, Ver={info.version})"
)
discovered_ip = info.ip_address
break
# Phase 1: boot signal (version) seen but no IP yet — keep polling
if info and info.version and not boot_seen:
boot_seen = True
self._log_message(
f" ✓ Boot signal after {elapsed:.1f}s"
f" (Ver={info.version}), waiting for IP..."
)
time.sleep(0.5)
elapsed += 0.5
else:
self._log_message(f" ⏱ UART timeout — no boot signal in {boot_delay}s")
self._log_message(f" ⏱ UART timeout — no IP in {boot_delay}s")
# Final check: IP may have arrived after the last poll
info = (
_uart_src.latest_info
if hasattr(_uart_src, "latest_info")
else _uart_src.get_latest_info()
)
if info and info.ip_address:
self._log_message(f" IP recovered from latest UART info: {info.ip_address}")
discovered_ip = info.ip_address
else:
self._log_message(f" ⏳ UART unavailable — sleeping {boot_delay}s for boot...")
time.sleep(boot_delay)
# Fallback: parse IP from accumulated UART buffer (lines may arrive
# after boot wait loop exited — e.g. "Board IP: 192.168.100.13")
if not discovered_ip and _uart_src:
all_lines = (
_uart_src.all_lines
if hasattr(_uart_src, "all_lines")
else []
)
if all_lines:
parsed = parse_boot_output(all_lines)
if parsed.ip_address:
discovered_ip = parsed.ip_address
self._log_message(f" IP from UART buffer: {discovered_ip}")
# Discover actual IP after reboot (may have changed via DHCP)
if not discovered_ip:
self._log_message(" ⏳ Network stack — waiting 3s...")
time.sleep(3)
self._log_message(" Scanning for Zynq IP (192.168.100.1130)...")
discovered_ip = self._discover_zynq_ip()
if discovered_ip: