forked from platformio/platformio-core
Improved a serial port finder for Black Magic Probe // Resolve #4023
This commit is contained in:
@ -33,6 +33,7 @@ PlatformIO Core 6
|
||||
* Documented `Stringification <https://docs.platformio.org/en/latest/projectconf/section_env_build.html#stringification>`__ – converting a macro argument into a string constant (`issue #4310 <https://github.com/platformio/platformio-core/issues/4310>`_)
|
||||
* Added ``env.StringifyMacro(value)`` helper function for the `Advanced Scripting <https://docs.platformio.org/en/latest/scripting/index.html>`__
|
||||
* Allowed to ``Import("projenv")`` in a library extra script (`issue #4305 <https://github.com/platformio/platformio-core/issues/4305>`_)
|
||||
* Improved a serial port finder for `Black Magic Probe <https://docs.platformio.org/en/latest/plus/debug-tools/blackmagic.html>`__ (`issue #4023 <https://github.com/platformio/platformio-core/issues/4023>`_)
|
||||
* Improved a serial port finder for a board with predefined HWIDs
|
||||
* Fixed an issue when the `build_unflags <https://docs.platformio.org/en/latest/projectconf/section_env_build.html#build-unflags>`__ operation ignores a flag value (`issue #4309 <https://github.com/platformio/platformio-core/issues/4309>`_)
|
||||
* Fixed an issue when the `build_unflags <https://docs.platformio.org/en/latest/projectconf/section_env_build.html#build-unflags>`__ option was not applied to the ``ASPPFLAGS`` scope
|
||||
|
@ -18,7 +18,7 @@ import os
|
||||
from platformio import fs, proc, util
|
||||
from platformio.compat import string_types
|
||||
from platformio.debug.exception import DebugInvalidOptionsError
|
||||
from platformio.debug.helpers import reveal_debug_port
|
||||
from platformio.device.finder import find_debug_port
|
||||
from platformio.project.config import ProjectConfig
|
||||
from platformio.project.helpers import load_build_metadata
|
||||
from platformio.project.options import ProjectOptions
|
||||
@ -119,12 +119,22 @@ class DebugConfigBase: # pylint: disable=too-many-instance-attributes
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return reveal_debug_port(
|
||||
initial_port = (
|
||||
self.env_options.get("debug_port", self.tool_settings.get("port"))
|
||||
or self._port,
|
||||
or self._port
|
||||
)
|
||||
port = find_debug_port(
|
||||
initial_port,
|
||||
self.tool_name,
|
||||
self.tool_settings,
|
||||
)
|
||||
if port:
|
||||
return port
|
||||
if not self.tool_settings.get("require_debug_port"):
|
||||
return None
|
||||
raise DebugInvalidOptionsError(
|
||||
"Please specify `debug_port` for the working environment"
|
||||
)
|
||||
|
||||
@port.setter
|
||||
def port(self, value):
|
||||
|
@ -16,14 +16,12 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from fnmatch import fnmatch
|
||||
from hashlib import sha1
|
||||
from io import BytesIO
|
||||
|
||||
from platformio.cli import PlatformioCLI
|
||||
from platformio.compat import IS_WINDOWS, is_bytes
|
||||
from platformio.compat import is_bytes
|
||||
from platformio.debug.exception import DebugInvalidOptionsError
|
||||
from platformio.device.list.util import list_serial_ports
|
||||
from platformio.run.cli import cli as cmd_run
|
||||
from platformio.run.cli import print_processing_header
|
||||
from platformio.test.helpers import list_test_names
|
||||
@ -161,44 +159,3 @@ def is_prog_obsolete(prog_path):
|
||||
with open(prog_hash_path, mode="w", encoding="utf8") as fp:
|
||||
fp.write(new_digest)
|
||||
return True
|
||||
|
||||
|
||||
def reveal_debug_port(env_debug_port, tool_name, tool_settings):
|
||||
def _get_pattern():
|
||||
if not env_debug_port:
|
||||
return None
|
||||
if set(["*", "?", "[", "]"]) & set(env_debug_port):
|
||||
return env_debug_port
|
||||
return None
|
||||
|
||||
def _is_match_pattern(port):
|
||||
pattern = _get_pattern()
|
||||
if not pattern:
|
||||
return True
|
||||
return fnmatch(port, pattern)
|
||||
|
||||
def _look_for_serial_port(hwids):
|
||||
for item in list_serial_ports(filter_hwid=True):
|
||||
if not _is_match_pattern(item["port"]):
|
||||
continue
|
||||
port = item["port"]
|
||||
if tool_name.startswith("blackmagic"):
|
||||
if IS_WINDOWS and port.startswith("COM") and len(port) > 4:
|
||||
port = "\\\\.\\%s" % port
|
||||
if "GDB" in item["description"]:
|
||||
return port
|
||||
for hwid in hwids:
|
||||
hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
|
||||
if hwid_str in item["hwid"]:
|
||||
return port
|
||||
return None
|
||||
|
||||
if env_debug_port and not _get_pattern():
|
||||
return env_debug_port
|
||||
if not tool_settings.get("require_debug_port"):
|
||||
return None
|
||||
|
||||
debug_port = _look_for_serial_port(tool_settings.get("hwids", []))
|
||||
if not debug_port:
|
||||
raise DebugInvalidOptionsError("Please specify `debug_port` for environment")
|
||||
return debug_port
|
||||
|
@ -18,13 +18,16 @@ from fnmatch import fnmatch
|
||||
import click
|
||||
import serial
|
||||
|
||||
from platformio.compat import IS_WINDOWS
|
||||
from platformio.compat import IS_MACOS, IS_WINDOWS
|
||||
from platformio.device.list.util import list_logical_devices, list_serial_ports
|
||||
from platformio.package.manager.platform import PlatformPackageManager
|
||||
from platformio.platform.factory import PlatformFactory
|
||||
from platformio.util import retry
|
||||
|
||||
KNOWN_UART_HWIDS = (
|
||||
BLACK_MAGIC_HWIDS = [
|
||||
"1D50:6018",
|
||||
]
|
||||
KNOWN_UART_HWIDS = BLACK_MAGIC_HWIDS + [
|
||||
# Silicon Labs
|
||||
"10C4:EA60", # CP210X
|
||||
"10C4:EA61", # CP210X
|
||||
@ -33,7 +36,7 @@ KNOWN_UART_HWIDS = (
|
||||
"10C4:EA71", # CP2108
|
||||
"10C4:EA80", # CP2110
|
||||
"10C4:80A9", # CP210X
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def normalize_board_hwid(value):
|
||||
@ -91,18 +94,44 @@ def find_serial_port(
|
||||
return best_port or port
|
||||
|
||||
|
||||
def find_blackmagic_serial_port(timeout=0):
|
||||
def find_blackmagic_serial_port(timeout=0, only_gdb_port=False):
|
||||
try:
|
||||
|
||||
@retry(timeout=timeout)
|
||||
def wrapper():
|
||||
for item in list_serial_ports():
|
||||
port = item["port"]
|
||||
if IS_WINDOWS and port.startswith("COM") and len(port) > 4:
|
||||
port = "\\\\.\\%s" % port
|
||||
if "GDB" in item["description"]:
|
||||
return port
|
||||
raise retry.RetryNextException()
|
||||
candidates = []
|
||||
for item in list_serial_ports(filter_hwid=True):
|
||||
if (
|
||||
not any(hwid in item["hwid"].upper() for hwid in BLACK_MAGIC_HWIDS)
|
||||
and not "Black Magic" in item["description"]
|
||||
):
|
||||
continue
|
||||
if (
|
||||
IS_WINDOWS
|
||||
and item["port"].startswith("COM")
|
||||
and len(item["port"]) > 4
|
||||
):
|
||||
item["port"] = "\\\\.\\%s" % item["port"]
|
||||
candidates.append(item)
|
||||
|
||||
if not candidates:
|
||||
raise retry.RetryNextException()
|
||||
|
||||
for item in candidates:
|
||||
if ("GDB" if only_gdb_port else "UART") in item["description"]:
|
||||
return item["port"]
|
||||
if IS_MACOS:
|
||||
# 1 - GDB, 3 - UART
|
||||
for item in candidates:
|
||||
if item["port"].endswith("1" if only_gdb_port else "3"):
|
||||
return item["port"]
|
||||
|
||||
candidates = sorted(candidates, key=lambda item: item["port"])
|
||||
return (
|
||||
candidates[0] # first port is GDB?
|
||||
if len(candidates) == 1 or only_gdb_port
|
||||
else candidates[1]
|
||||
)["port"]
|
||||
|
||||
return wrapper()
|
||||
except retry.RetryStopException:
|
||||
@ -193,3 +222,15 @@ def find_mbed_disk(initial_port):
|
||||
if item["name"] and any(l in item["name"].lower() for l in msdlabels):
|
||||
return item["path"]
|
||||
return None
|
||||
|
||||
|
||||
def find_debug_port(initial_port, tool_name, tool_settings):
|
||||
if initial_port:
|
||||
if not is_pattern_port(initial_port):
|
||||
return initial_port
|
||||
return match_serial_port(initial_port)
|
||||
if not tool_settings.get("require_debug_port"):
|
||||
return None
|
||||
if tool_name.startswith("blackmagic"):
|
||||
return find_blackmagic_serial_port(timeout=0, only_gdb_port=True)
|
||||
return None
|
||||
|
Reference in New Issue
Block a user