Root cause: When UART window is open, self._uart_monitor is None
(the window creates its own UartMonitor). Step 4 boot wait loop
only checked self._uart_monitor.latest_info → always saw empty data
→ fell through to IP scanning even though UART had detected the IP.
Fix:
- UartMonitorWindow.get_latest_info() exposes parsed BootInfo
- Step 4 checks both: self._uart_monitor first, then UART window
- Null guard on info before accessing .ip_address
After Step 4 reboot, the Zynq may obtain a different IP via DHCP.
IP discovery strategy:
1. UART available → parse IP from boot output (fast, zero network traffic)
2. UART unavailable → scan 192.168.100.11–30 via UDP ver() probe
(port = last_octet - 3, 0.5s timeout each, ~10s max for 20 IPs)
If IP changed → auto-update config.zynq_ip + UI field
Tool discovery:
- On Windows, scan .bat files in addition to .exe
(Xilinx Windows tools use .bat wrappers, not .exe)
- Prefer .exe over .bat when both exist (same version dir)
Environment setup:
- _find_settings_script(): walk up from bin/ to find settings64.sh/.bat
- build_tool_command(): wrap Linux tool invocation with 'source settings64.sh'
Windows .bat wrappers handle env internally, no extra wrapping needed
- reboot_manager.py now uses build_tool_command() for proper env
Example output (Linux):
build_tool_command('/data/xilinx/Vitis/2023.2/bin/xsct', 'script.tcl')
→ ['bash', '-c', 'source .../settings64.sh && .../xsct script.tcl']
_version discovery:
- _scan_xilinx_root() collects ALL versions under Vitis/*/bin/ and Vivado/*/bin/
- _parse_version_tuple() semantic version comparison (2023.2 > 2018.3)
- Defaults to newest version, Vitis preferred over Vivado for same version
- _find_executable() search order: PATH → legacy vitis_path → scan xilinx_root → common paths
_version reporting:
- _get_tool_version(): tries -version flag first, falls back to path parsing
- _version_from_path(): extracts version from install path (e.g., .../Vitis/2023.2/bin/xsct → 2023.2)
- Step 1 logs each tool with version: ✓ xsct: /path [v2023.2]
- If multiple versions found, lists all: xsct versions found: 2023.2 (Vitis), 2018.3 (Vivado)
Cross-platform:
- Handles Windows path separators via Path()
- Expanded common Windows install paths
rst -system inherently resumes ARM execution on Zynq.
The subsequent 'con' command fails with 'Already running'
because the core is already executing after system reset.
Fix: wrap 'con' in 'catch {}' — if core is already running
the error is silently caught; if stopped, con resumes it.
xsct exits 0 (success) in both cases.
Config:
- Add boot_wait_delay (default 10s) for post-reboot wait time
Layout:
- Restore row weights for proportional scaling when maximized
- CTkScrollableFrame handles overflow when window is small
Step 3:
- Log xsct/vivado tool output (last 20 lines per result)
for detailed diagnostics
Step 4:
- UART boot wait: monitor for IP/version via UART after reboot
- If UART unavailable, fall back to config.boot_wait_delay
- Reduces unnecessary wait time when boot is detected early
Serial:
- Real-time port validation on selection change (CTkComboBox command)
- Persistent UART unavailable warning until valid port selected
- Auto-restart UART monitor on port switch
- Graceful cross-platform handling
- Implement _tftp_get() for downloading files from Zynq via TFTP
- Add TftpSubStepFrame widget for Step 4 progress display
- Refactor Step 4 into 5 sub-steps: Upload, Download Verify, CRC Check, Reboot, Boot Verify
- Fix SubStepFrame.reset() bug that caused collapse after execution
- Fix layout overlap: Step 4 sub-step and progress bar now use separate rows
- Improve ProgressIndicator appearance with better styling and spacing
- Fix UART monitor to start regardless of _uart_available flag
- Add CRC32 verification between uploaded and downloaded files