fix(t1000e): restore single-port usb logging

This commit is contained in:
mikecarper
2026-09-22 07:46:11 -07:00
parent 04e6aa38f2
commit 8ecdd31585
4 changed files with 48 additions and 26 deletions
+10 -20
View File
@@ -2736,11 +2736,7 @@ requires_full_usb_packet_logging() {
# Full Companion and the combined USB+WiFi infrastructure artifact always
# carry the logger behind runtime controls. Other Full profiles retain the
# ordinary explicit logging-off/disable-debug behavior.
# T1000-E Full has a single, stability-critical USB CDC endpoint. It keeps
# that endpoint for Companion data and the terminal, not optional packet
# logging, so its packaged contract must not promise a logger.
[ "$env_name" != "t1000e_companion_radio_full" ] \
&& is_companion_radio_full_target "$env_name" && return 0
is_companion_radio_full_target "$env_name" && return 0
[ "$ESP32_FULL_BUILD" = "1" ] || return 1
is_companion_build "$env_name" && return 1
[ "${PACKET_LOGGING_OVERRIDE,,}" = "on" ] && return 0
@@ -3291,9 +3287,7 @@ declare_build_capability_contract() {
record_build_expectation "companion.usb" "+++MESHCORE-TERM-START"
record_build_expectation "companion.bluetooth" \
"Companion: starting Bluetooth"
if [ "$env_name" != "t1000e_companion_radio_full" ]; then
record_build_expectation "companion.usb_logging" "get usb.logging"
fi
record_build_expectation "companion.usb_logging" "get usb.logging"
record_build_expectation "companion.usb_mota_source" "ota folder on"
record_build_expectation "companion.mota_sender" \
"_ZN4mesh3ota16SerialMotaSource4read"
@@ -3852,9 +3846,9 @@ apply_companion_radio_full_profile() {
# an exclusive host-folder mode with its existing `ota folder on` preamble.
# CDC 1 is a write-only plaintext packet/debug logging stream; BLE remains
# an independent Companion link. ESP32 intentionally does not use this
# dual-CDC capability. The T1000-E's nRF52840 USB hardware resets when
# its persisted logging preference asks TinyUSB to activate CDC 1, so it
# intentionally keeps logging on the primary USB interface instead.
# dual-CDC capability. The T1000-E has one stable CDC endpoint only: its
# logging preference claims that primary port as an ASCII terminal plus
# logs, and therefore never creates CDC 1 or mixes logs with framed USB.
append_platformio_build_unflags "-UOTA_FOLDER_SERIAL"
# The nRF52 core's production-safe Bluefruit bootstrap must retain its
# early SoftDevice diagnostics. Without CFG_DEBUG, a few nRF52840 USB
@@ -3864,15 +3858,11 @@ apply_companion_radio_full_profile() {
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DOTA_FOLDER_SERIAL=1 -DCOMPANION_FEATURE_USB_MOTA_SOURCE=1 -DCOMPANION_FEATURE_BLE_MOTA_SOURCE=1 -DMESH_DEBUG=1 -DMESH_PACKET_LOGGING=1 -DCFG_DEBUG=1 -DRECOVERABLE_EXTERNAL_RADIO=1"
if [ "$env_name" = "t1000e_companion_radio_full" ]; then
# The T1000-E's primary CDC transport is the only USB interface. Its
# optional packet/debug logger can make the device reset while a host is
# enumerating, so keep Full Companion USB strictly data/terminal-only.
# This also ignores a stale persisted `usb.logging on` preference from
# an older dual-CDC image, allowing the device to recover automatically.
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DMESH_USB_LOGGING_DISABLED=1"
# MESH_USB_LOGGING_DISABLED still silences MeshCore's optional packet
# logger on the shared CDC endpoint. The shared nRF52 Full profile above
# retains the validated BLE bootstrap and radio recovery behavior.
append_platformio_build_unflags "-UMESH_DEBUG -UMESH_PACKET_LOGGING"
# `usb.logging on` selects an input-capable ASCII logging terminal on
# CDC 0. `usb.logging off` restores automatic framed-Companion detection.
# Do not instantiate or re-enumerate a second CDC interface on this
# board: its native USB/SoftDevice handoff is sensitive to that change.
:
else
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DCOMPANION_FEATURE_DEDICATED_USB_LOGGING=1 -DCFG_TUD_CDC=2 -DMESH_DUAL_CDC_LOGGING=1"
fi
+22
View File
@@ -976,6 +976,19 @@ static void beginUsbDefaultSession() {
static void serviceUsbTerminal() {
#if COMPANION_FEATURE_USB_MOTA_SOURCE
if (usb_mota_mode) {
#if MESH_USB_LOGGING_AVAILABLE
// A single-TTY logger and framed USB mOTA cannot share the primary USB
// stream. A remote logging change can arrive while mOTA owns USB, so stop
// the transfer before its next binary exchange and return to ASCII.
if (!mesh::hasDedicatedUsbLoggingPort()
&& mesh::isUsbLoggingEnabled()) {
leaveUsbMotaMode(false);
enterUsbLoggingTerminalMode();
usbTerminalOutput().print(
"\r\nUSB mOTA stopped: USB logging owns this port\r\n> ");
return;
}
#endif
serviceUsbMota();
return;
}
@@ -1093,6 +1106,15 @@ static void serviceUsbTerminal() {
// instead of letting the ordinary terminal command handler leave the
// stream in line-oriented mode.
if (strcmp(usb_terminal_line, USB_MOTA_START_TOKEN) == 0) {
#if MESH_USB_LOGGING_AVAILABLE
if (!mesh::hasDedicatedUsbLoggingPort()
&& mesh::isUsbLoggingEnabled()) {
clearUsbTerminalLine();
usbTerminalOutput().print(
"\r\nERROR: set usb.logging off before USB mOTA\r\n> ");
return;
}
#endif
leaveUsbTerminalMode(false);
enterUsbMotaMode(mesh::UsbMotaEntryOrigin::ASCII);
return;
+7 -3
View File
@@ -598,8 +598,12 @@ for full_env in "${SUPPORTED_PIO_ENVS[@]}"; do
|| fail "$full_env must keep a single USB CDC interface"
[[ "$PLATFORMIO_BUILD_FLAGS" != *"MESH_DUAL_CDC_LOGGING=1"* ]] \
|| fail "$full_env must keep USB logging on its primary interface"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"MESH_USB_LOGGING_DISABLED=1"* ]] \
|| fail "$full_env must disable its unstable primary USB logger"
[[ "$PLATFORMIO_BUILD_FLAGS" != *"MESH_USB_LOGGING_DISABLED=1"* ]] \
|| fail "$full_env must retain its single-port USB logging terminal"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"MESH_DEBUG=1"* ]] \
|| fail "$full_env must retain USB diagnostics on its logging terminal"
[[ "$PLATFORMIO_BUILD_FLAGS" == *"MESH_PACKET_LOGGING=1"* ]] \
|| fail "$full_env must retain packet logging on its logging terminal"
[[ "$PLATFORMIO_BUILD_FLAGS" != *"COMPANION_BLE_PRPH_MTU="* ]] \
|| fail "$full_env must retain the normal Full-Companion BLE bandwidth"
[[ "$PLATFORMIO_BUILD_FLAGS" != *"COMPANION_BLUETOOTH_BOOT_DELAY_MS="* ]] \
@@ -794,7 +798,7 @@ done
for logging_target in Station_G2_companion_radio_full RAK_4631_companion_radio_full; do
verify_full_logging_contract "$logging_target" 0 off 1 yes no
done
verify_full_logging_contract t1000e_companion_radio_full 0 off 1 no no
verify_full_logging_contract t1000e_companion_radio_full 0 off 1 yes no
# Synthetic inventory: ESP32 and nRF52 repeater/room-server targets with the
# same lean OTA policy. The sensor deliberately has no lean sibling.
+9 -3
View File
@@ -339,12 +339,12 @@ def test_canonical_bulk_matrix_omits_runtime_and_transport_aliases():
assert "-DCFG_TUD_CDC=2" in nrf52_full
assert "-DMESH_DUAL_CDC_LOGGING=1" in nrf52_full
# Every nRF52 Full image keeps the proven Bluefruit bootstrap and radio
# recovery profile. T1000-E alone disables its optional packet logger
# because its sole CDC endpoint is reserved for Companion data/terminal.
# recovery profile. T1000-E keeps its sole CDC endpoint for a mutually
# exclusive ASCII logging terminal rather than instantiating CDC 1.
assert "-DCFG_DEBUG=1" in nrf52_full
assert "-DRECOVERABLE_EXTERNAL_RADIO=1" in nrf52_full
assert 'if [ "$env_name" = "t1000e_companion_radio_full" ]; then' in nrf52_full
assert "-DMESH_USB_LOGGING_DISABLED=1" in nrf52_full
assert "MESH_USB_LOGGING_DISABLED" not in nrf52_full
esp32_full = full.split("return 0\n fi", 1)[1]
assert "-DCFG_TUD_CDC=2" not in esp32_full
assert "-DMESH_DUAL_CDC_LOGGING=1" not in esp32_full
@@ -481,6 +481,12 @@ def test_single_tty_logging_off_restores_each_builds_default_mode():
"if (strcmp(usb_terminal_line, USB_TERMINAL_STOP_TOKEN) == 0) {", 1
)[1].split("}", 1)[0]
assert "leaveUsbTerminalMode(true);" in terminal_stop
usb_mota_start = service.split(
"if (strcmp(usb_terminal_line, USB_MOTA_START_TOKEN) == 0) {", 1
)[1].split("leaveUsbTerminalMode(false);", 1)[0]
assert "set usb.logging off before USB mOTA" in usb_mota_start
assert "!mesh::hasDedicatedUsbLoggingPort()" in usb_mota_start
assert "mesh::isUsbLoggingEnabled()" in usb_mota_start
assert "if (!usb_logging_terminal_mode" in service
assert "usb_binary_startup_probe.shouldStart(" in service