fix: convert all TCL-embedded paths to forward slashes (cross-platform)

Windows backslashes in TCL strings are interpreted as escape sequences
(\f → form feed, \t → tab). This caused 'dow "Files\fsbl..."' to
fail with garbled paths — TCL couldn't find the file.

Added _tcl_path() helper: replaces \ with / in any path before
embedding in TCL. Forward slashes work on all platforms including
Windows. Applied to all 7 path sites: source, fpga -file, dow.
This commit is contained in:
2026-06-11 18:11:44 +08:00
parent 4ca15c1190
commit 04ad61e694
+17 -8
View File
@@ -37,6 +37,15 @@ ProgressCallback = Callable[[str, str], None] | None
# ── Helpers ─────────────────────────────────────────────────────────
def _tcl_path(path: str | Path) -> str:
"""Convert a filesystem path to TCL-safe format.
TCL interprets backslashes as escape sequences (\\f, \\t, \\n).
Forward slashes work on all platforms including Windows.
"""
return str(path).replace("\\", "/")
def _find_ps7_init_tcl(config: Config) -> str:
"""Find the ps7_init.tcl file for PS initialization.
@@ -187,11 +196,11 @@ def _program_with_xsct(
lines = ["connect"]
if ps7_init_tcl and Path(ps7_init_tcl).exists():
lines.append("targets 1")
lines.append(f'source "{ps7_init_tcl}"')
lines.append(f'source "{_tcl_path(ps7_init_tcl)}"')
lines.append("ps7_init")
if callback:
callback("progress", "PS initialized (clocks, DDR, MIO)")
lines.append(f'fpga -file "{bit_path}"')
lines.append(f'fpga -file {{{_tcl_path(bit_path)}}}')
if ps7_init_tcl and Path(ps7_init_tcl).exists():
lines.append("ps7_post_config")
if callback:
@@ -381,13 +390,13 @@ def _run_elf_via_fsbl(
tcl = "\n".join([
"connect",
"targets 2",
"dow \"%s\"" % fsbl_path,
"dow {%s}" % _tcl_path(fsbl_path),
"puts \"FSBL downloaded\"",
"con",
"after 3000",
"stop",
"puts \"FSBL done, CPU halted\"",
"dow \"%s\"" % elf_path,
"dow {%s}" % _tcl_path(elf_path),
"mwr 0xF800025C 0x00000001",
"con",
"puts \"App running\"",
@@ -461,7 +470,7 @@ def _run_elf_direct(
tcl = "\n".join([
"connect",
"targets 2",
"dow \"%s\"" % elf_path,
"dow {%s}" % _tcl_path(elf_path),
"mwr 0xF800025C 0x00000001",
"con",
"exit",
@@ -620,18 +629,18 @@ def full_bitstream_program(
"rst -processor",
"after 500",
'puts "INFO: Downloading FSBL..."',
'dow "%s"' % fsbl_path,
'dow {%s}' % _tcl_path(fsbl_path),
'puts "INFO: Running FSBL for hardware initialization..."',
"con",
"after 2000",
"stop",
'puts "INFO: Hardware initialization completed."',
'puts "INFO: Downloading Bitstream..."',
'fpga -f "%s"' % bit_path,
'fpga -f {%s}' % _tcl_path(bit_path),
"after 1000",
'targets -set -nocase -filter {name =~ "arm*#0"}',
'puts "INFO: Downloading Application ELF..."',
'dow "%s"' % elf_path,
'dow {%s}' % _tcl_path(elf_path),
'puts "INFO: Executing Application..."',
"con",
'puts "SUCCESS: Zynq target is running the specified application."',