Add cross-platform GUI application for programming Zynq devices with step-by-step workflow: - CustomTkinter GUI with dark/light theme support - 4-step workflow: Check Env → Flash → Bootloader → Main Program - YAML configuration with relative path resolution - Serial monitoring and boot log parsing - TFTP upload with CRC32 verification - SSH/serial reboot management - Vivado/Impact tool auto-detection Project structure: - app.py: Entry point - src/: Core modules (config, flash, bitstream, tftp, serial, gui) - config/: Default configuration template - .flasher_env/: Python virtual environment
108 lines
2.8 KiB
Python
108 lines
2.8 KiB
Python
"""IP connectivity verification for Zynq Flasher GUI.
|
|
|
|
Pings the Zynq device IP to verify network connectivity.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import platform
|
|
import subprocess
|
|
|
|
|
|
def ping_ip(
|
|
ip_address: str,
|
|
count: int = 3,
|
|
timeout: int = 5,
|
|
) -> bool:
|
|
"""Ping an IP address to verify connectivity.
|
|
|
|
Uses platform-appropriate ping command:
|
|
- Linux/macOS: ping -c <count> -W <timeout>
|
|
- Windows: ping -n <count> -w <timeout>
|
|
|
|
Args:
|
|
ip_address: IP address to ping (e.g., '192.168.100.11').
|
|
count: Number of ping packets to send.
|
|
timeout: Timeout in seconds (Linux) or milliseconds (Windows).
|
|
|
|
Returns:
|
|
True if all ping packets were received, False otherwise.
|
|
"""
|
|
system = platform.system().lower()
|
|
|
|
if system == "windows":
|
|
cmd = ["ping", "-n", str(count), "-w", str(timeout * 1000), ip_address]
|
|
else:
|
|
cmd = ["ping", "-c", str(count), "-W", str(timeout), ip_address]
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
cmd,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=timeout * count + 10,
|
|
)
|
|
return result.returncode == 0
|
|
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
|
return False
|
|
|
|
|
|
def ping_ip_verbose(
|
|
ip_address: str,
|
|
count: int = 3,
|
|
timeout: int = 5,
|
|
) -> dict:
|
|
"""Ping an IP address and return detailed results.
|
|
|
|
Args:
|
|
ip_address: IP address to ping.
|
|
count: Number of ping packets.
|
|
timeout: Timeout per packet.
|
|
|
|
Returns:
|
|
Dictionary with 'success' (bool), 'output' (str), and 'errors' (list).
|
|
"""
|
|
system = platform.system().lower()
|
|
|
|
if system == "windows":
|
|
cmd = ["ping", "-n", str(count), "-w", str(timeout * 1000), ip_address]
|
|
else:
|
|
cmd = ["ping", "-c", str(count), "-W", str(timeout), ip_address]
|
|
|
|
output = ""
|
|
errors: list[str] = []
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
cmd,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=timeout * count + 10,
|
|
)
|
|
output = result.stdout.strip()
|
|
if result.stderr:
|
|
errors.append(result.stderr.strip())
|
|
return {
|
|
"success": result.returncode == 0,
|
|
"output": output,
|
|
"errors": errors,
|
|
}
|
|
except subprocess.TimeoutExpired as e:
|
|
return {
|
|
"success": False,
|
|
"output": e.stdout if e.stdout else "",
|
|
"errors": ["Ping timed out"],
|
|
}
|
|
except FileNotFoundError as e:
|
|
return {
|
|
"success": False,
|
|
"output": "",
|
|
"errors": [f"ping command not found: {e}"],
|
|
}
|
|
except OSError as e:
|
|
return {
|
|
"success": False,
|
|
"output": "",
|
|
"errors": [f"OS error: {e}"],
|
|
}
|