fix: use xsct (not Vivado) for JTAG check + normalize COM>=10 ports on Windows
**JTAG check**: Switch from Vivado to xsct - xsct is already proven to work (JTAG reboot succeeds) - Much lighter than Vivado (no GUI infrastructure / open_hw_manager) - Uses -eval inline TCL: connect; targets; disconnect; quit - Removes dead tempfile/Path/os imports **Windows COM port**: Add normalize_port() to serial_monitor.py - COM ports >= 10 require NT namespace prefix (\.\COM11) - Without it: PermissionError(13, '拒绝访问。') - Applied at all 7 call sites: serial_monitor (5), reboot_manager, widgets
This commit is contained in:
+27
-6
@@ -7,8 +7,10 @@ Provides UartMonitor for continuous background monitoring.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import platform
|
||||
import re
|
||||
import threading
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable
|
||||
|
||||
@@ -16,6 +18,26 @@ import serial
|
||||
import serial.tools.list_ports
|
||||
|
||||
|
||||
def normalize_port(port: str) -> str:
|
||||
"""Normalize a serial port name for the current platform.
|
||||
|
||||
On Windows, COM ports numbered >= 10 require the NT namespace
|
||||
prefix (\\\\.\\COM11). Without it, CreateFile fails with
|
||||
'Access denied' or 'file not found'.
|
||||
|
||||
Args:
|
||||
port: Raw port name from config or detection.
|
||||
|
||||
Returns:
|
||||
Normalized port name suitable for serial.Serial().
|
||||
"""
|
||||
if platform.system() == "Windows":
|
||||
match = re.match(r"^COM(\d+)$", port, re.IGNORECASE)
|
||||
if match and int(match.group(1)) >= 10:
|
||||
return rf"\\.\{port}"
|
||||
return port
|
||||
|
||||
|
||||
@dataclass
|
||||
class BootInfo:
|
||||
"""Parsed information extracted from Zynq boot output."""
|
||||
@@ -168,7 +190,7 @@ def check_uart_available(
|
||||
|
||||
# 3. Try to open and read
|
||||
try:
|
||||
with serial.Serial(port, baudrate, timeout=timeout) as ser:
|
||||
with serial.Serial(normalize_port(port), baudrate, timeout=timeout) as ser:
|
||||
ser.reset_input_buffer()
|
||||
lines: list[str] = []
|
||||
while ser.in_waiting:
|
||||
@@ -206,7 +228,7 @@ def read_serial_stream(
|
||||
serial.SerialException: If the port cannot be opened.
|
||||
"""
|
||||
lines: list[str] = []
|
||||
with serial.Serial(port, baudrate, timeout=timeout) as ser:
|
||||
with serial.Serial(normalize_port(port), baudrate, timeout=timeout) as ser:
|
||||
# Clear any pending data
|
||||
ser.reset_input_buffer()
|
||||
while ser.in_waiting:
|
||||
@@ -242,8 +264,7 @@ def test_serial_version(
|
||||
import serial
|
||||
|
||||
try:
|
||||
with serial.Serial(port, baudrate, timeout=timeout) as ser:
|
||||
# Clear buffers
|
||||
with serial.Serial(normalize_port(port), baudrate, timeout=timeout) as ser:
|
||||
ser.reset_input_buffer()
|
||||
ser.reset_output_buffer()
|
||||
|
||||
@@ -384,7 +405,7 @@ class UartMonitor:
|
||||
|
||||
# Quick port check before starting thread
|
||||
try:
|
||||
test_ser = serial.Serial(self._port, self._baudrate, timeout=1)
|
||||
test_ser = serial.Serial(normalize_port(self._port), self._baudrate, timeout=1)
|
||||
test_ser.close()
|
||||
except serial.SerialException as e:
|
||||
if self.on_error:
|
||||
@@ -411,7 +432,7 @@ class UartMonitor:
|
||||
"""Main read loop running in background thread."""
|
||||
try:
|
||||
ser = serial.Serial(
|
||||
self._port,
|
||||
normalize_port(self._port),
|
||||
self._baudrate,
|
||||
timeout=self._timeout,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user