feat: initial Zynq XC7Z100 Flasher GUI project
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
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""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}"],
|
||||
}
|
||||
Reference in New Issue
Block a user