1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
19119: makefiles/tools/serial.inc.mk: Allow detection of debug adapter r=benpicco a=maribu

### Contribution description

This PR adds the ability to automatically detect the debug adapter for boards with an integrated programmer/debugger, if that debugger also provides the TTY.

This extends the TTY detection that can be enabled with `MOST_RECENT_PORT=1` to set `DEBUG_ADAPTER_ID` to the TTY's serial, but only if `DEBUG_ADAPTER_ID_IS_TTY_SERIAL` is set to `1` by the board (as not all boards have an integrated programmer/debugger).

### Testing procedure

Connect a HiFive-1B and a nRF52840DK at the same time and try `make BOARD=<nrf52840dk|hifive1b> MOST_RECENT_PORT=1 -C examples/default flash term` for both. The programmer will not reliably select the correct programmer in `master`. With this PR, it will.

### Issues/PRs references

None

19313: gnrc_static: don't parse address as prefix r=benpicco a=benpicco



Co-authored-by: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
Co-authored-by: Benjamin Valentin <benpicco@beuth-hochschule.de>
This commit is contained in:
bors[bot] 2023-02-24 17:46:10 +00:00 committed by GitHub
commit 9d1d4bb1b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 34 deletions

View File

@ -25,11 +25,11 @@ ARDUINO_MEGA2560_COMPAT_WITH_CLONES ?= 1
ifeq (1,$(ARDUINO_MEGA2560_COMPAT_WITH_CLONES)) ifeq (1,$(ARDUINO_MEGA2560_COMPAT_WITH_CLONES))
TTY_SELECT_CMD := $(RIOTTOOLS)/usb-serial/ttys.py \ TTY_SELECT_CMD := $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \ --most-recent \
--format path \ --format path serial \
$(TTY_BOARD_FILTER) || \ $(TTY_BOARD_FILTER) || \
$(RIOTTOOLS)/usb-serial/ttys.py \ $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \ --most-recent \
--format path \ --format path serial \
$(TTY_BOARD_FILTER_CLONE) $(TTY_BOARD_FILTER_CLONE)
endif endif

View File

@ -11,6 +11,10 @@ include $(RIOTMAKE)/boards/stm32.inc.mk
# USB serials to only select the UART bridge of embedded STLink debuggers. # USB serials to only select the UART bridge of embedded STLink debuggers.
TTY_BOARD_FILTER := --model 'STM32 STLink' TTY_BOARD_FILTER := --model 'STM32 STLink'
# The TTY serial also is the ID of the debug adapter, as the TTY is provided by
# the debug adapter
DEBUG_ADAPTER_ID_IS_TTY_SERIAL := 1
# variable needed by cpy2remed PROGRAMMER # variable needed by cpy2remed PROGRAMMER
# it contains name of ST-Link removable media # it contains name of ST-Link removable media

View File

@ -25,5 +25,9 @@ endif
# the UART bridge to the ESP32-SOLO-1 MCU instead of the FE310 MCU on the board. # the UART bridge to the ESP32-SOLO-1 MCU instead of the FE310 MCU on the board.
TTY_BOARD_FILTER := --model HiFive --iface-num 0 TTY_BOARD_FILTER := --model HiFive --iface-num 0
# The TTY serial also is the ID of the debug adapter, as the TTY is provided by
# the debug adapter
DEBUG_ADAPTER_ID_IS_TTY_SERIAL := 1
TESTRUNNER_RESET_DELAY = 1 TESTRUNNER_RESET_DELAY = 1
$(call target-export-variables,test,TESTRUNNER_RESET_DELAY) $(call target-export-variables,test,TESTRUNNER_RESET_DELAY)

View File

@ -7,6 +7,10 @@ PROGRAMMERS_SUPPORTED += pyocd
# programmer firmware revisions "fix" that. # programmer firmware revisions "fix" that.
TTY_BOARD_FILTER := --model ".?BBC micro:bit CMSIS-DAP.?" TTY_BOARD_FILTER := --model ".?BBC micro:bit CMSIS-DAP.?"
# The TTY serial also is the ID of the debug adapter, as the TTY is provided by
# the debug adapter
DEBUG_ADAPTER_ID_IS_TTY_SERIAL := 1
# The board is not recognized automatically by pyocd, so the CPU target # The board is not recognized automatically by pyocd, so the CPU target
# option is passed explicitly # option is passed explicitly
PYOCD_FLASH_TARGET_TYPE ?= -t $(CPU) PYOCD_FLASH_TARGET_TYPE ?= -t $(CPU)

View File

@ -2,4 +2,8 @@
# USB serials to only select the UART bridge of integrated J-Link debugger. # USB serials to only select the UART bridge of integrated J-Link debugger.
TTY_BOARD_FILTER := --model J-Link TTY_BOARD_FILTER := --model J-Link
# The TTY serial also is the ID of the debug adapter, as the TTY is provided by
# the debug adapter
DEBUG_ADAPTER_ID_IS_TTY_SERIAL := 1
include $(RIOTBOARD)/common/nrf52xxxdk/Makefile.include include $(RIOTBOARD)/common/nrf52xxxdk/Makefile.include

View File

@ -7,5 +7,9 @@ CFLAGS += \
QN908X_JLINK ?= $(QN9080DK_JLINK) QN908X_JLINK ?= $(QN9080DK_JLINK)
JLINK_DEVICE ?= QN9080A JLINK_DEVICE ?= QN9080A
# The TTY serial also is the ID of the debug adapter, as the TTY is provided by
# the debug adapter
DEBUG_ADAPTER_ID_IS_TTY_SERIAL := 1
# Include default QN908x board config # Include default QN908x board config
include $(RIOTBOARD)/common/qn908x/Makefile.include include $(RIOTBOARD)/common/qn908x/Makefile.include

View File

@ -23,7 +23,19 @@ With the parameter `--format FORMAT` a different format than the default
markdown table can be selected, e.g. `json` results in JSON output and `path` markdown table can be selected, e.g. `json` results in JSON output and `path`
will print the paths of the matching TTYs without any formatting (useful for will print the paths of the matching TTYs without any formatting (useful for
scripting). The full list of formats can be obtained by running the script with scripting). The full list of formats can be obtained by running the script with
the `--help` parameter the `--help` parameter.
Note: Formats other than `json` and `table` can be combined. A script that
required both path and serial of TTYs could use:
```
./ttys.py --format path serial
```
This will output one TTY per line with the selected fields separated by space.
To use a different separator than space (e.g. to create CSV files), the option
`--format-sep` can be used. If a field value contains the separator, it will
be quoted and quotation chars inside will be escaped.
### Filtering ### Filtering

View File

@ -61,9 +61,7 @@ def parse_args(args):
Parse the given command line style arguments with argparse Parse the given command line style arguments with argparse
""" """
desc = "List and filter TTY interfaces that might belong to boards" desc = "List and filter TTY interfaces that might belong to boards"
supported_formats = { formats_combinable = {
"table",
"json",
"path", "path",
"serial", "serial",
"vendor", "vendor",
@ -74,13 +72,20 @@ def parse_args(args):
"ctime", "ctime",
"iface_num", "iface_num",
} }
formats_uncombinable = {
"table",
"json",
}
supported_formats = formats_combinable.union(formats_uncombinable)
parser = argparse.ArgumentParser(description=desc) parser = argparse.ArgumentParser(description=desc)
parser.add_argument("--most-recent", action="store_true", parser.add_argument("--most-recent", action="store_true",
help="Print only the most recently connected matching " help="Print only the most recently connected matching "
+ "TTY") + "TTY")
parser.add_argument("--format", default="table", type=str, parser.add_argument("--format", default=["table"], type=str, nargs='+',
help=f"How to format the TTYs. Supported formats: " help=f"How to format the TTYs. Supported formats: "
f"{sorted(supported_formats)}") f"{sorted(supported_formats)}")
parser.add_argument("--format-sep", default=" ", type=str,
help="Separator between formats (default: space)")
parser.add_argument("--serial", default=None, type=str, parser.add_argument("--serial", default=None, type=str,
help="Print only devices matching this serial") help="Print only devices matching this serial")
parser.add_argument("--driver", default=None, type=str, parser.add_argument("--driver", default=None, type=str,
@ -108,8 +113,17 @@ def parse_args(args):
args = parser.parse_args() args = parser.parse_args()
if args.format not in supported_formats: if len(args.format) == 1:
sys.exit(f"Format \"{args.format}\" not supported") if args.format[0] not in supported_formats:
sys.exit(f"Format \"{args.format[0]}\" not supported")
else:
for fmt in args.format:
if fmt not in formats_combinable:
if fmt in formats_uncombinable:
sys.exit(f"Format \"{fmt}\" cannot be combined with " +
"other formats")
else:
sys.exit(f"Format \"{fmt}\" not supported")
if args.exclude_serial is None: if args.exclude_serial is None:
if "EXCLUDE_TTY_SERIAL" in os.environ: if "EXCLUDE_TTY_SERIAL" in os.environ:
@ -154,21 +168,31 @@ def print_results(args, ttys):
""" """
Print the given TTY devices according to the given args Print the given TTY devices according to the given args
""" """
if args.format == "json": if len(args.format) == 1:
print(json.dumps(ttys, indent=2)) if args.format[0] == "json":
return print(json.dumps(ttys, indent=2))
return
if args.format == "table": if args.format[0] == "table":
for tty in ttys: for tty in ttys:
tty["ctime"] = time.strftime("%H:%M:%S", tty["ctime"] = time.strftime("%H:%M:%S",
time.localtime(tty["ctime"])) time.localtime(tty["ctime"]))
headers = ["path", "driver", "vendor", "model", "model_db", "serial", headers = ["path", "driver", "vendor", "model", "model_db",
"ctime", "iface_num"] "serial", "ctime", "iface_num"]
print_table(ttys, headers) print_table(ttys, headers)
return return
for tty in ttys: for tty in ttys:
print(tty[args.format]) line = ""
for fmt in args.format:
item = tty[fmt]
if item.rfind(args.format_sep) >= 0:
# item contains separator --> quote it
# using json.dumps to also escape quotation chars and other
# unsafe stuff
item = json.dumps(item)
line += f"{args.format_sep}{item}"
print(line[len(args.format_sep):])
def generate_filters(args): def generate_filters(args):

View File

@ -478,20 +478,20 @@ In most cases, just adding a simple `TTY_BOARD_FILTER` is sufficient. If we
however have wildly different flavors of the same board (e.g. genuine Arduino however have wildly different flavors of the same board (e.g. genuine Arduino
Mega 2560 with an ATmega16U2 and clones with a cheap USB to UART bridge) that we Mega 2560 with an ATmega16U2 and clones with a cheap USB to UART bridge) that we
all want to support, we have to instead provide a `TTY_SELECT_CMD` that prints all want to support, we have to instead provide a `TTY_SELECT_CMD` that prints
the path to the TTY and exists with `0` if a TTY was found, or that exists with the path to and the serial of the TTY (separated by a space) and exists with
`1` and prints nothing when no TTY was found. We can still use the `ttys.py` `0` if a TTY was found, or that exists with `1` and prints nothing when no TTY
script to detect all Arduino Mega 2560 versions: We first try to detect a was found. We can still use the `ttys.py` script to detect all Arduino Mega
genuine Arduino Mega and fall back to selecting cheap USB UART bridges when that 2560 versions: We first try to detect a genuine Arduino Mega and fall back to
fails using the `||` shell operator: selecting cheap USB UART bridges when that fails using the `||` shell operator:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TTY_SELECT_CMD := $(RIOTTOOLS)/usb-serial/ttys.py \ TTY_SELECT_CMD := $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \ --most-recent \
--format path \ --format path serial \
--vendor 'Arduino' \ --vendor 'Arduino' \
--model-db 'Mega 2560|Mega ADK' || \ --model-db 'Mega 2560|Mega ADK' || \
$(RIOTTOOLS)/usb-serial/ttys.py \ $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \ --most-recent \
--format path \ --format path serial \
--driver 'cp210x' --driver 'cp210x'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -5,10 +5,15 @@ ifeq (1,$(MOST_RECENT_PORT))
endif endif
TTY_SELECT_CMD ?= $(RIOTTOOLS)/usb-serial/ttys.py \ TTY_SELECT_CMD ?= $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \ --most-recent \
--format path \ --format path serial \
$(TTY_BOARD_FILTER) $(TTY_BOARD_FILTER)
PORT_DETECTED := $(shell $(TTY_SELECT_CMD) || echo 'no-tty-detected') TTY_DETECTED := $(shell $(TTY_SELECT_CMD) || echo 'no-tty-detected no-serial-detected')
PORT ?= $(PORT_DETECTED) PORT_DETECTED := $(firstword $(TTY_DETECTED))
PORT_SERIAL_DETECTED := $(lastword $(TTY_DETECTED))
PORT ?= $(firstword $(TTY_DETECTED))
ifeq (1,$(DEBUG_ADAPTER_ID_IS_TTY_SERIAL))
DEBUG_ADAPTER_ID ?= $(PORT_SERIAL_DETECTED)
endif
endif endif
# Otherwise, use as default the most commonly used ports on Linux and OSX # Otherwise, use as default the most commonly used ports on Linux and OSX
PORT_LINUX ?= /dev/ttyACM0 PORT_LINUX ?= /dev/ttyACM0

View File

@ -60,10 +60,9 @@ static void _config_upstream(gnrc_netif_t *upstream)
DEBUG("gnrc_ipv6_static_addr: interface %u selected as upstream\n", upstream->pid); DEBUG("gnrc_ipv6_static_addr: interface %u selected as upstream\n", upstream->pid);
/* configure static address */ /* configure static address */
int addr_len;
if (static_addr != NULL && if (static_addr != NULL &&
(addr_len = ipv6_prefix_from_str(&addr, static_addr)) > 0) { ipv6_addr_from_str(&addr, static_addr) != NULL) {
gnrc_netif_ipv6_addr_add_internal(upstream, &addr, addr_len, gnrc_netif_ipv6_addr_add_internal(upstream, &addr, 128,
GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID); GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID);
} }