mirror of
https://github.com/espressif/esptool.git
synced 2025-10-21 15:10:33 +08:00
feat(esptool): allow picking UART by VID/PID/Name
Enable user to specify USB VID, USB PID, or port name to filter the com port list before checking for ESP chips. Implements https://github.com/espressif/esptool/issues/987
This commit is contained in:
@@ -117,3 +117,21 @@ An example of this is available in the :ref:`merge_bin <merge-bin>` command desc
|
|||||||
.. note:: PowerShell users
|
.. note:: PowerShell users
|
||||||
|
|
||||||
Because of `splatting <https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7.3>`__ in PowerShell (method of passing a collection of parameter values to a command as a unit) there is a need to add quotes around @filename.txt ("@filename.txt") to be correctly resolved.
|
Because of `splatting <https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7.3>`__ in PowerShell (method of passing a collection of parameter values to a command as a unit) there is a need to add quotes around @filename.txt ("@filename.txt") to be correctly resolved.
|
||||||
|
|
||||||
|
Filtering serial ports
|
||||||
|
----------------------
|
||||||
|
.. _filtering_serial_ports:
|
||||||
|
|
||||||
|
``--port-filter <FilterType>=<FilterValue>`` allows limiting ports that will be tried. This can be useful when esptool is run on a system
|
||||||
|
with many serial ports. There are a few different types that can be combined. A port must match all specified FilterTypes, and must match
|
||||||
|
at least one FilterValue for each specified FilterType to be considered. Example filter configurations:
|
||||||
|
|
||||||
|
.. list::
|
||||||
|
|
||||||
|
* ``--port-filter vid=0x303A`` matches ports with the Espressif USB VID.
|
||||||
|
* ``--port-filter vid=0x303A --port-filter vid=0x0403`` matches Espressif and FTDI ports by VID.
|
||||||
|
* ``--port-filter vid=0x303A --port-filter pid=0x0002`` matches Espressif ESP32-S2 in USB-OTG mode by VID and PID.
|
||||||
|
* ``--port-filter vid=0x303A --port-filter pid=0x1001`` matches Espressif USB-Serial/JTAG unit used by multiple chips by VID and PID.
|
||||||
|
* ``--port-filter name=ttyUSB`` matches ports where the port name contains the specified text.
|
||||||
|
|
||||||
|
See also the `Espressif USB customer-allocated PID repository <https://github.com/espressif/usb-pids>`_
|
||||||
|
@@ -123,6 +123,14 @@ def main(argv=None, esp=None):
|
|||||||
default=os.environ.get("ESPTOOL_BAUD", ESPLoader.ESP_ROM_BAUD),
|
default=os.environ.get("ESPTOOL_BAUD", ESPLoader.ESP_ROM_BAUD),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--port-filter",
|
||||||
|
action="append",
|
||||||
|
help="Serial port device filter, can be vid=NUMBER, pid=NUMBER, name=SUBSTRING",
|
||||||
|
type=str,
|
||||||
|
default=[],
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--before",
|
"--before",
|
||||||
help="What to do before connecting to the chip",
|
help="What to do before connecting to the chip",
|
||||||
@@ -690,6 +698,23 @@ def main(argv=None, esp=None):
|
|||||||
|
|
||||||
StubFlasher.set_preferred_stub_subdir(args.stub_version)
|
StubFlasher.set_preferred_stub_subdir(args.stub_version)
|
||||||
|
|
||||||
|
# Parse filter arguments into separate lists
|
||||||
|
args.filterVids = []
|
||||||
|
args.filterPids = []
|
||||||
|
args.filterNames = []
|
||||||
|
for f in args.port_filter:
|
||||||
|
kvp = f.split("=")
|
||||||
|
if len(kvp) != 2:
|
||||||
|
raise FatalError("Option --port-filter argument must consist of key=value")
|
||||||
|
if kvp[0] == "vid":
|
||||||
|
args.filterVids.append(arg_auto_int(kvp[1]))
|
||||||
|
elif kvp[0] == "pid":
|
||||||
|
args.filterPids.append(arg_auto_int(kvp[1]))
|
||||||
|
elif kvp[0] == "name":
|
||||||
|
args.filterNames.append(kvp[1])
|
||||||
|
else:
|
||||||
|
raise FatalError("Option --port-filter argument key not recognized")
|
||||||
|
|
||||||
# operation function can take 1 arg (args), 2 args (esp, arg)
|
# operation function can take 1 arg (args), 2 args (esp, arg)
|
||||||
# or be a member function of the ESPLoader class.
|
# or be a member function of the ESPLoader class.
|
||||||
|
|
||||||
@@ -725,7 +750,7 @@ def main(argv=None, esp=None):
|
|||||||
initial_baud = args.baud
|
initial_baud = args.baud
|
||||||
|
|
||||||
if args.port is None:
|
if args.port is None:
|
||||||
ser_list = get_port_list()
|
ser_list = get_port_list(args.filterVids, args.filterPids, args.filterNames)
|
||||||
print("Found %d serial ports" % len(ser_list))
|
print("Found %d serial ports" % len(ser_list))
|
||||||
else:
|
else:
|
||||||
ser_list = [args.port]
|
ser_list = [args.port]
|
||||||
@@ -1010,21 +1035,29 @@ def arg_auto_chunk_size(string: str) -> int:
|
|||||||
return num
|
return num
|
||||||
|
|
||||||
|
|
||||||
def get_port_list():
|
def get_port_list(vids=[], pids=[], names=[]):
|
||||||
if list_ports is None:
|
if list_ports is None:
|
||||||
raise FatalError(
|
raise FatalError(
|
||||||
"Listing all serial ports is currently not available. "
|
"Listing all serial ports is currently not available. "
|
||||||
"Please try to specify the port when running esptool.py or update "
|
"Please try to specify the port when running esptool.py or update "
|
||||||
"the pyserial package to the latest version"
|
"the pyserial package to the latest version"
|
||||||
)
|
)
|
||||||
port_list = sorted(ports.device for ports in list_ports.comports())
|
ports = []
|
||||||
if sys.platform == "darwin":
|
for port in list_ports.comports():
|
||||||
port_list = [
|
if sys.platform == "darwin" and port.device.endswith(
|
||||||
port
|
("Bluetooth-Incoming-Port", "wlan-debug")
|
||||||
for port in port_list
|
):
|
||||||
if not port.endswith(("Bluetooth-Incoming-Port", "wlan-debug"))
|
continue
|
||||||
]
|
if vids and (port.vid is None or port.vid not in vids):
|
||||||
return port_list
|
continue
|
||||||
|
if pids and (port.pid is None or port.pid not in pids):
|
||||||
|
continue
|
||||||
|
if names and (
|
||||||
|
port.name is None or all(name not in port.name for name in names)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
ports.append(port.device)
|
||||||
|
return sorted(ports)
|
||||||
|
|
||||||
|
|
||||||
def expand_file_arguments(argv):
|
def expand_file_arguments(argv):
|
||||||
|
Reference in New Issue
Block a user