fix: replace Popen readline loop with subprocess.run for Windows pipe reliability; add close_hw before quit in TCL; revert console=True

This commit is contained in:
2026-06-12 17:46:11 +08:00
parent 4da03e97d8
commit c0f7219d30
2 changed files with 24 additions and 25 deletions
+22 -25
View File
@@ -125,7 +125,7 @@ def check_zynq_jtag(
if callback:
callback("progress", "Scanning JTAG chain...")
# ── 3. Run Vivado TCL (stream output to callback) ──────────
# ── 3. Run Vivado TCL ──────────────────────────────────────
tcl = _build_jtag_query_tcl()
python_timeout = config.step_timeouts.get("check_env", 120)
@@ -141,31 +141,27 @@ def check_zynq_jtag(
output_lines: list[str] = []
try:
proc = subprocess.Popen(
build_tool_command(vivado_path, *vivado_args),
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
cmd = build_tool_command(vivado_path, *vivado_args)
# Use run() with communicate() under the hood — reliably
# drains pipes on Windows even when .bat wrappers are involved
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=python_timeout,
)
output = result.stdout + result.stderr
for line in output.splitlines():
stripped = line.strip()
if stripped:
output_lines.append(stripped)
if callback:
callback("progress", stripped)
except subprocess.TimeoutExpired:
return _fail(
f"JTAG scan timed out after {python_timeout}s",
hw_server_url,
)
# Read line by line so user sees real-time progress
deadline = time.monotonic() + python_timeout
while True:
line = proc.stdout.readline() if proc.stdout else ""
if not line:
if proc.poll() is not None:
break
if time.monotonic() > deadline:
proc.kill()
proc.wait()
return _fail(
f"JTAG scan timed out after {python_timeout}s",
hw_server_url,
)
time.sleep(0.1)
continue
line = line.rstrip("\n\r")
output_lines.append(line)
if callback and line.strip():
callback("progress", line)
except OSError as e:
return _fail(f"Failed to run Vivado: {e}", hw_server_url)
finally:
@@ -173,7 +169,6 @@ def check_zynq_jtag(
Path(tcl).unlink(missing_ok=True)
except Exception:
pass
# Clean up Vivado temp files we redirected
for f in ("vivado_jtag.jou", "vivado_jtag.log"):
try:
(Path(tmp) / f).unlink(missing_ok=True)
@@ -267,6 +262,8 @@ foreach dev [get_hw_devices] {
puts "DEVICE:$name IDCODE:$idcode"
}
puts "===JTAG_END==="
close_hw
disconnect_hw_server
quit
"""
import os