[usb_uart] Only compile the vendor drivers that are configured (#20190)

This commit is contained in:
J. Nick Koston
2026-10-05 17:56:10 -04:00
committed by GitHub
parent fc441646f4
commit a778baddca
5 changed files with 62 additions and 0 deletions
+21
View File
@@ -7,6 +7,7 @@ from esphome.components.usb_host import (
register_usb_client,
usb_device_schema,
)
from esphome.config_helpers import filter_source_files_from_defines
import esphome.config_validation as cv
from esphome.const import (
CONF_BAUD_RATE,
@@ -15,6 +16,7 @@ from esphome.const import (
CONF_DEBUG,
CONF_DUMMY_RECEIVER,
CONF_ID,
CONF_TYPE,
)
from esphome.core import CORE
from esphome.cpp_types import Component
@@ -64,6 +66,8 @@ class Type:
self.vid = vid
self.pid = pid
self.cls = usb_uart_ns.class_(f"USBUartType{cls}", USBUartComponent)
# CDC ACM lives in usb_uart.cpp; each vendor driver has its own <cls>.cpp
self.driver = None if cls == "CdcAcm" else cls
self._max_channels = max_channels
self.baud_rate_required = baud_rate_required
self.max_baud = max_baud
@@ -121,6 +125,21 @@ uart_types = (
),
)
_TYPES_BY_NAME = {it.name: it for it in uart_types}
def _driver_define(driver: str) -> str:
return f"USE_USB_UART_{driver}"
FILTER_SOURCE_FILES = filter_source_files_from_defines(
{
f"{it.driver.lower()}.cpp": _driver_define(it.driver)
for it in uart_types
if it.driver is not None
}
)
def channel_schema(type_: "Type") -> cv.Schema:
schema = cv.Schema(
@@ -211,6 +230,8 @@ async def to_code(config: list[ConfigType]) -> None:
cg.add_define("USB_UART_OUTPUT_CHUNK_COUNT", output_chunk_count)
for device in config:
if (driver := _TYPES_BY_NAME[device[CONF_TYPE]].driver) is not None:
cg.add_define(_driver_define(driver))
var = await register_usb_client(device)
# The C++ default is true; only emit the override
if not device.get(CONF_CLAIM_COMM_INTERFACE, True):
+4
View File
@@ -459,6 +459,10 @@
#define USB_HOST_MAX_REQUESTS 16
#define USB_HOST_MAX_PACKET_SIZE 64
#define USB_UART_OUTPUT_CHUNK_COUNT 5
#define USE_USB_UART_CH34X
#define USE_USB_UART_CP210X
#define USE_USB_UART_FT23XX
#define USE_USB_UART_PL2303
#ifdef USE_ARDUINO
#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 3, 7)
@@ -0,0 +1,19 @@
"""Tests for the usb_uart component's driver source filtering."""
from collections.abc import Callable
from esphome.core import CORE
def test_only_configured_driver_compiled(
generate_main: Callable[[str], str],
) -> None:
generate_main("tests/component_tests/usb_uart/test_usb_uart_ft232.yaml")
from esphome.components.usb_uart import FILTER_SOURCE_FILES
defines = {define.name for define in CORE.defines}
# cdc_acm is built into usb_uart.cpp and adds no driver define
assert {d for d in defines if d.startswith("USE_USB_UART_")} == {
"USE_USB_UART_FT23XX"
}
assert sorted(FILTER_SOURCE_FILES()) == ["ch34x.cpp", "cp210x.cpp", "pl2303.cpp"]
@@ -0,0 +1,18 @@
esphome:
name: test
esp32:
variant: esp32s3
framework:
type: esp-idf
usb_uart:
- type: ft232
channels:
- id: ft_channel
baud_rate: 115200
- type: cdc_acm
vid: 0x1234
pid: 0x5678
channels:
- id: cdc_channel