✨ feat(uart): add UART availability check, inter-step delays, and post-download Zynq status verification
- Add check_uart_available() to serial_monitor.py — detects port availability - Add verify_zynq_status() to boot_verifier.py — lightweight post-download check - Add uart_delay / inter_step_delay config fields (defaults: 3s / 2s) - Step 1: Check UART availability, show non-blocking 'UART 不可用' notification - Step 4: Add post-download Zynq status check (ping + serial) after TFTP - _run_steps_worker: Add configurable inter-step delays between all steps - Update step labels (4a→4b→4c→4d) for clarity
This commit is contained in:
+59
-7
@@ -21,8 +21,8 @@ from bitstream_programmer import full_bitstream_program, BitstreamResult
|
||||
from ip_verifier import ping_ip
|
||||
from tftp_manager import tftp_upload_verify, TftpResult
|
||||
from reboot_manager import reboot_zynq, RebootResult
|
||||
from boot_verifier import verify_boot, BootVerificationResult
|
||||
from serial_monitor import detect_serial_ports, parse_boot_output
|
||||
from boot_verifier import verify_boot, verify_zynq_status, BootVerificationResult
|
||||
from serial_monitor import detect_serial_ports, parse_boot_output, check_uart_available
|
||||
from gui.styles import (
|
||||
WINDOW_WIDTH,
|
||||
WINDOW_HEIGHT,
|
||||
@@ -73,6 +73,8 @@ class MainWindow(ctk.CTk):
|
||||
self._step_statuses: dict[int, str] = {}
|
||||
self._is_running = False
|
||||
self._worker_thread: threading.Thread | None = None
|
||||
self._uart_available: bool = False
|
||||
self._uart_message: str = ""
|
||||
|
||||
self._load_config()
|
||||
self._build_ui()
|
||||
@@ -471,7 +473,7 @@ class MainWindow(ctk.CTk):
|
||||
# ── Step Implementations ───────────────────────────────────
|
||||
|
||||
def _run_step_1_check_environment(self) -> bool:
|
||||
"""Step 1: Check environment (Vitis/Vivado tools + Zynq IP)."""
|
||||
"""Step 1: Check environment (Vitis/Vivado tools + Zynq IP + UART)."""
|
||||
self._log_message("Step 1: Checking environment...")
|
||||
|
||||
if not self._config:
|
||||
@@ -507,8 +509,35 @@ class MainWindow(ctk.CTk):
|
||||
self._ip_status.configure(text=f"IP: {ip} ✗", text_color=DANGER_COLOR)
|
||||
return False
|
||||
|
||||
# Check UART availability
|
||||
self._log_message(" Checking UART serial port...")
|
||||
port = self._config.serial_port
|
||||
if port:
|
||||
available, reason = check_uart_available(port, self._config.serial_baudrate)
|
||||
self._uart_available = available
|
||||
self._uart_message = reason
|
||||
if available:
|
||||
self._log_message(f" ✓ UART available: {reason}")
|
||||
else:
|
||||
self._log_message(f" ✗ UART unavailable: {reason}")
|
||||
self._show_uart_notification(reason)
|
||||
else:
|
||||
self._uart_available = False
|
||||
self._uart_message = "No serial port configured"
|
||||
self._log_message(" ✗ No serial port configured")
|
||||
self._show_uart_notification(self._uart_message)
|
||||
|
||||
return True
|
||||
|
||||
def _show_uart_notification(self, reason: str) -> None:
|
||||
"""Show a non-blocking UART unavailable notification in the status panel.
|
||||
|
||||
Args:
|
||||
reason: Why UART is unavailable.
|
||||
"""
|
||||
msg = f"UART 不可用 ({reason}),日志分析及检查将禁用"
|
||||
self.after(0, lambda: self._status.set_status(msg, "warning"))
|
||||
|
||||
def _run_step_2_program_flash(self) -> bool:
|
||||
"""Step 2: Program and verify Flash."""
|
||||
if not self._config:
|
||||
@@ -606,8 +635,21 @@ class MainWindow(ctk.CTk):
|
||||
self._log_message(" Skipping reboot & boot verify (TFTP failed)")
|
||||
return False
|
||||
|
||||
# 4b: Reboot
|
||||
self._log_message("Step 4b: Rebooting Zynq...")
|
||||
# 4a2: Post-download Zynq status check
|
||||
self._log_message("Step 4b: Checking Zynq status after download...")
|
||||
try:
|
||||
zynq_status = verify_zynq_status(
|
||||
self._config,
|
||||
uart_available=self._uart_available,
|
||||
callback=self._zynq_status_callback,
|
||||
)
|
||||
status = "✓" if zynq_status.success else "✗"
|
||||
self._log_message(f" {status} {zynq_status.message}")
|
||||
except Exception as e:
|
||||
self._log_message(f" ✗ Zynq status check error: {e}")
|
||||
|
||||
# 4c: Reboot
|
||||
self._log_message("Step 4c: Rebooting Zynq...")
|
||||
try:
|
||||
reboot_result = reboot_zynq(
|
||||
self._config,
|
||||
@@ -625,8 +667,8 @@ class MainWindow(ctk.CTk):
|
||||
self._log_message(" Skipping boot verify (reboot failed)")
|
||||
return False
|
||||
|
||||
# 4c: Verify boot
|
||||
self._log_message("Step 4c: Verifying boot...")
|
||||
# 4d: Verify boot
|
||||
self._log_message("Step 4d: Verifying boot...")
|
||||
try:
|
||||
boot_result = verify_boot(
|
||||
self._config,
|
||||
@@ -659,6 +701,10 @@ class MainWindow(ctk.CTk):
|
||||
"""Callback for boot verification progress."""
|
||||
self._log_message(f" [{status}] {message}")
|
||||
|
||||
def _zynq_status_callback(self, status: str, message: str) -> None:
|
||||
"""Callback for post-download Zynq status check."""
|
||||
self._log_message(f" [{status}] {message}")
|
||||
|
||||
# ── Run All Steps ──────────────────────────────────────────
|
||||
|
||||
def _update_step_dependencies(self) -> None:
|
||||
@@ -781,6 +827,12 @@ class MainWindow(ctk.CTk):
|
||||
if start_index == 0 and not success:
|
||||
break
|
||||
|
||||
# Inter-step delay (skip after last step)
|
||||
if i < len(step_funcs) - 1:
|
||||
delay = self._config.inter_step_delay if self._config else 2
|
||||
self._log_message(f" ⏳ Waiting {delay}s before next step...")
|
||||
time.sleep(delay)
|
||||
|
||||
self._progress.set_value(1.0)
|
||||
self._is_running = False
|
||||
self._run_btn.configure(state="normal", text="▶ Run All Steps")
|
||||
|
||||
Reference in New Issue
Block a user