merge: fast-forward to origin/master
This commit is contained in:
+4
-2
@@ -1022,6 +1022,8 @@ class UartMonitorWindow(ctk.CTkToplevel):
|
||||
self.geometry("680x540")
|
||||
self.minsize(480, 360)
|
||||
self.protocol("WM_DELETE_WINDOW", self._on_close)
|
||||
self.lift() # ensure visible on Windows
|
||||
self.focus()
|
||||
|
||||
self._on_log = on_log
|
||||
|
||||
@@ -1144,7 +1146,8 @@ class UartMonitorWindow(ctk.CTkToplevel):
|
||||
def _bg_open() -> None:
|
||||
try:
|
||||
import serial
|
||||
ser = serial.Serial(self._port, self._baudrate, timeout=1)
|
||||
from serial_monitor import _open_serial
|
||||
ser = _open_serial(self._port, self._baudrate, 1)
|
||||
ser.close()
|
||||
self.after(0, self._on_open_success)
|
||||
except Exception as e:
|
||||
@@ -1270,5 +1273,4 @@ class UartMonitorWindow(ctk.CTkToplevel):
|
||||
if self._monitor:
|
||||
self._monitor.stop()
|
||||
self._monitor = None
|
||||
self.grab_release()
|
||||
self.destroy()
|
||||
|
||||
@@ -125,11 +125,12 @@ def reboot_via_serial(
|
||||
|
||||
try:
|
||||
import serial
|
||||
from serial_monitor import _open_serial
|
||||
|
||||
with serial.Serial(
|
||||
with _open_serial(
|
||||
config.serial_port,
|
||||
config.serial_baudrate,
|
||||
timeout=5,
|
||||
timeout=5.0,
|
||||
) as ser:
|
||||
ser.reset_input_buffer()
|
||||
# Send Ctrl+C to break out of any running process
|
||||
|
||||
+32
-4
@@ -8,6 +8,7 @@ Provides UartMonitor for continuous background monitoring.
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
@@ -17,6 +18,33 @@ import serial
|
||||
import serial.tools.list_ports
|
||||
|
||||
|
||||
def _open_serial(port: str, baudrate: int, timeout: float = 1.0) -> serial.Serial:
|
||||
"""Open a serial port, trying both name formats on Windows.
|
||||
|
||||
pyserial normally adds \\\\.\\COM prefix for COM>=10, but some
|
||||
versions don't. Try raw name first, then explicit NT namespace.
|
||||
"""
|
||||
port = port.strip()
|
||||
last_err = None
|
||||
|
||||
# Try 1: port name as-is
|
||||
try:
|
||||
return serial.Serial(port, baudrate, timeout=timeout)
|
||||
except serial.SerialException as e:
|
||||
last_err = e
|
||||
|
||||
# Try 2: Windows NT namespace prefix
|
||||
if sys.platform == "win32":
|
||||
m = re.match(r"^(COM\d+)$", port, re.IGNORECASE)
|
||||
if m:
|
||||
try:
|
||||
return serial.Serial(r"\\.\%s" % port, baudrate, timeout=timeout)
|
||||
except serial.SerialException as e:
|
||||
last_err = e
|
||||
|
||||
raise last_err or OSError(f"Cannot open serial port: {port}")
|
||||
|
||||
|
||||
@dataclass
|
||||
class BootInfo:
|
||||
"""Parsed information extracted from Zynq boot output."""
|
||||
@@ -169,7 +197,7 @@ def check_uart_available(
|
||||
|
||||
# 3. Try to open and read
|
||||
try:
|
||||
with serial.Serial(port, baudrate, timeout=timeout) as ser:
|
||||
with _open_serial(port, baudrate, timeout) as ser:
|
||||
ser.reset_input_buffer()
|
||||
lines: list[str] = []
|
||||
while ser.in_waiting:
|
||||
@@ -243,7 +271,7 @@ def test_serial_version(
|
||||
import serial
|
||||
|
||||
try:
|
||||
with serial.Serial(port, baudrate, timeout=timeout) as ser:
|
||||
with _open_serial(port, baudrate, timeout) as ser:
|
||||
ser.reset_input_buffer()
|
||||
ser.reset_output_buffer()
|
||||
|
||||
@@ -384,7 +412,7 @@ class UartMonitor:
|
||||
|
||||
# Quick port check before starting thread
|
||||
try:
|
||||
test_ser = serial.Serial(self._port, self._baudrate, timeout=1)
|
||||
test_ser = _open_serial(self._port, self._baudrate, 1)
|
||||
test_ser.close()
|
||||
except serial.SerialException as e:
|
||||
if self.on_error:
|
||||
@@ -410,7 +438,7 @@ class UartMonitor:
|
||||
def _read_loop(self) -> None:
|
||||
"""Main read loop running in background thread."""
|
||||
try:
|
||||
ser = serial.Serial(
|
||||
ser = _open_serial(
|
||||
self._port,
|
||||
self._baudrate,
|
||||
timeout=self._timeout,
|
||||
|
||||
Reference in New Issue
Block a user