Compare commits

...
17 Commits
Author SHA1 Message Date
J. Nick Koston f12f5d3a1f [noise] Initialize reserved field for gcc 15
gcc 15 extends -Wmissing-field-initializers to designated
initializers; NoiseProtocolId's reserved array was omitted.
2026-08-26 21:59:10 -05:00
J. Nick Koston 33a9439d8f [esp32_ble_client] Value initialize conn params for IDF 6.1
gcc 15 on IDF 6.1 rejects the partial {{0}} initializer of
esp_ble_conn_update_params_t under -Werror=missing-field-initializers;
empty braces value initialize the whole struct. Same fix in
bluetooth_connection.
2026-08-26 21:51:44 -05:00
J. Nick Koston c0ed06215a TEMP: point IDF 6.1 PlatformIO builds at forked platform and framework
pioarduino has no 6.1 packaging, and only 6.1 has the Log V2 option,
so the PlatformIO toolchain uses a repack of espressif v6.1 plus a
platform fork carrying the 6.1 fixes: newer idf-component-manager and
esp-idf-kconfig, the bootloader ld include dir, dropping app --wrap
flags from the bootloader link, and linking the transitive
tf-psa-crypto sublibs. Revert with the 6.1 default before merge.
2026-08-26 21:44:37 -05:00
J. Nick Koston 7235c2a8d6 [logger] Move the Log V2 wrap into the logger component
The Log V2 enable block and the esp_log_format wrap belong to the
logger: the wrap routes IDF output through the logger's hook, and the
logger already owns the esp8266 ets_putc wrap and esp32 console
sdkconfig options. This also drops the CORE.config peek at the logger
key from the esp32 platform. The direct formatter now reuses LogBuffer
and the logger's level tables instead of hand rolled equivalents, uses
a smaller stack buffer, and the hot path tests the common case first.
2026-08-26 21:44:28 -05:00
J. Nick Koston 07b8bb53f8 TEMP: default to ESP-IDF 6.1.0 for CI testing of Log V2
Sets recommended/latest/dev to 6.1.0, maps it to the pioarduino
prep_IDF6 platform branch, and points the PlatformIO framework source
at a pioarduino style repack of espressif v6.1 hosted at
bdraco/esp-idf, since pioarduino has not published 6.1 yet. The native
toolchain needs no hosting; esphome-libs/esp-idf already has v6.1.
Revert this commit and restore 5.5.5 before merge.
2026-08-26 21:17:29 -05:00
J. Nick Koston 6d1cd3f62e [esp32] Intercept the Log V2 formatter with linker wrap
A plain strong definition of esp_log_format collides with liblog's copy
on IDF 6.1: log.c.obj references the symbol and the linker resolves it
from log_format_text.c.obj inside the same archive before reaching
ESPHome's archive, producing a duplicate definition error. Use
-Wl,--wrap=esp_log_format and define __wrap_esp_log_format instead,
which also lets the unused liblog formatter be dead stripped.
2026-08-26 21:17:21 -05:00
J. Nick Koston 5cbf994b28 Merge upstream/dev into esp32-log-v2-idf61 2026-08-26 21:00:30 -05:00
J. Nick Koston 6cf30012a5 Merge branch 'dev' into esp32-log-v2-idf61 2026-07-01 21:42:02 -05:00
J. Nick Koston beff1dec4f [esp32] Clamp header length in the Log V2 direct formatter 2026-07-01 20:26:55 -05:00
J. Nick Koston e5e92b1e22 [esp32] Simplify custom hook forwarding in the Log V2 override 2026-07-01 20:21:02 -05:00
J. Nick Koston f843cc81c6 [esp32] Drop IRAM_ATTR from the Log V2 esp_log_format override 2026-07-01 20:17:07 -05:00
J. Nick Koston e8e5f6366d [esp32] Only enable Log V2 when the logger component is configured 2026-07-01 20:06:03 -05:00
J. Nick Koston a00982af2a [esp32] Skip the Log V2 format override when the logger component is absent 2026-07-01 20:02:46 -05:00
J. Nick Koston e0e0e3cb8f [esp32] Route Log V2 messages to the logger with real tag and severity 2026-07-01 19:45:21 -05:00
J. Nick Koston 20bda75684 [esp32] Preserve IDF component tag on routed Log V2 messages 2026-07-01 19:28:22 -05:00
J. Nick Koston 8a4959eb6c [esp32] Fix clang-tidy identifier naming in log.cpp V2 override 2026-07-01 19:25:18 -05:00
J. Nick Koston d0bb1e5a98 [esp32] Enable ESP-IDF Log V2 on IDF 6.1+ 2026-07-01 18:52:48 -05:00
8 changed files with 100 additions and 7 deletions
@@ -334,7 +334,7 @@ void BluedroidGattClient::set_disconnecting_() {
esp_err_t BluedroidGattClient::update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency,
uint16_t timeout, const char *param_type) {
esp_ble_conn_update_params_t conn_params = {{0}};
esp_ble_conn_update_params_t conn_params = {};
memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t));
conn_params.min_int = min_interval;
conn_params.max_int = max_interval;
+22 -3
View File
@@ -854,6 +854,10 @@ def _format_framework_pio_espidf_version(
) -> str:
# format the given espidf (https://github.com/pioarduino/esp-idf/releases) version to
# a PIO platformio/framework-espidf value
# TEMP: pioarduino has no 6.1 package yet; pioarduino-style repack of
# espressif v6.1. Remove before merge.
if ver == cv.Version(6, 1, 0):
return "pioarduino/framework-espidf@https://github.com/bdraco/esp-idf/releases/download/v6.1.0/esp-idf-v6.1.0.tar.xz"
if ver == cv.Version(5, 4, 3) or ver >= cv.Version(5, 5, 1):
ext = "tar.xz"
else:
@@ -944,12 +948,19 @@ ARDUINO_IDF_VERSION_LOOKUP = {
# The default/recommended esp-idf framework version
# - https://github.com/espressif/esp-idf/releases
ESP_IDF_FRAMEWORK_VERSION_LOOKUP = {
"recommended": cv.Version(5, 5, 5),
"latest": cv.Version(5, 5, 5),
"dev": cv.Version(5, 5, 5),
# TEMP: default to 6.1.0 for CI testing of Log V2; revert to 5.5.5 before merge
"recommended": cv.Version(6, 1, 0),
"latest": cv.Version(6, 1, 0),
"dev": cv.Version(6, 1, 0),
}
ESP_IDF_PLATFORM_VERSION_LOOKUP = {
# TEMP: prep_IDF6 plus the IDF 6.1 fixes (deps, bootloader ld, --wrap,
# tf-psa sublibs); only 6.1 has the Log V2 defines. Remove with the 6.1
# default once pioarduino publishes 6.1 support.
cv.Version(
6, 1, 0
): "https://github.com/bdraco/platform-espressif32.git#idf61-test",
cv.Version(
6, 0, 1
): "https://github.com/pioarduino/platform-espressif32.git#prep_IDF6",
@@ -1045,6 +1056,14 @@ def _check_pio_versions(config: ConfigType) -> ConfigType:
version = _resolve_framework_version(value)
# TEMP: named versions take the platform from PLATFORM_VERSION_LOOKUP
# above, bypassing the per-IDF-version lookup; force the IDF 6 platform
# without disturbing Arduino (still on 5.5.5). Remove with the 6.1 default.
if value[CONF_TYPE] != FRAMEWORK_ARDUINO and version == cv.Version(6, 1, 0):
value[CONF_PLATFORM_VERSION] = _parse_pio_platform_version(
ESP_IDF_PLATFORM_VERSION_LOOKUP[version]
)
if value[CONF_TYPE] == FRAMEWORK_ARDUINO:
platform_lookup = ARDUINO_PLATFORM_VERSION_LOOKUP.get(version)
value[CONF_SOURCE] = value.get(
@@ -267,7 +267,7 @@ void BLEClientBase::log_warning_(const char *message) {
esp_err_t BLEClientBase::update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency,
uint16_t timeout, const char *param_type) {
esp_ble_conn_update_params_t conn_params = {{0}};
esp_ble_conn_update_params_t conn_params = {};
memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t));
conn_params.min_int = min_interval;
conn_params.max_int = max_interval;
+11
View File
@@ -20,6 +20,7 @@ from esphome.components.esp32 import (
VARIANT_ESP32S31,
add_idf_sdkconfig_option,
get_esp32_variant,
idf_version,
require_usb_serial_jtag_secondary,
require_vfs_termios,
)
@@ -459,6 +460,16 @@ async def _late_logger_init(config: ConfigType) -> None:
elif config[CONF_HARDWARE_UART] == USB_SERIAL_JTAG:
add_idf_sdkconfig_option("CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG", True)
cg.add_define("USE_LOGGER_UART_SELECTION_USB_SERIAL_JTAG")
# Log V2 formats centrally in esp_log() (~4KB flash, ~180B RAM). 6.1
# adds CONSTRAINED_ENV_SAFE=n, keeping early/DRAM logs on
# esp_rom_printf instead of pulling ~1.2KB esp_rom_vprintf into IRAM.
if idf_version() >= cv.Version(6, 1, 0):
add_idf_sdkconfig_option("CONFIG_LOG_VERSION_1", False)
add_idf_sdkconfig_option("CONFIG_LOG_VERSION_2", True)
add_idf_sdkconfig_option("CONFIG_LOG_API_CONSTRAINED_ENV_SAFE", False)
cg.add_define("USE_ESP32_LOG_V2")
# --wrap: a strong definition collides; see logger_esp32.cpp
cg.add_build_flag("-Wl,--wrap=esp_log_format")
# Define platform support flags for components that need auto-detection
try:
uart_selection(USB_SERIAL_JTAG)
@@ -149,4 +149,64 @@ const LogString *Logger::get_uart_selection_() {
}
} // namespace esphome::logger
#ifdef USE_ESP32_LOG_V2
#include <esp_private/log_message.h>
#include <esp_log_write.h>
#include <esp_rom_sys.h>
namespace esphome::logger {
// IDF levels NONE=0 E=1 W=2 I=3 D=4 V=5; ESPHome inserts CONFIG at 4
static inline uint8_t idf_to_esphome_level(uint8_t idf_level) {
if (idf_level <= 3)
return idf_level;
return idf_level >= 5 ? ESPHOME_LOG_LEVEL_VERBOSE : ESPHOME_LOG_LEVEL_DEBUG;
}
// Console output without the logger hook: early boot and constrained env
// (fwrite locks crash during PHY init on USB JTAG). Cold path.
static void __attribute__((noinline)) esp_log_format_direct(esp_log_msg_t *message) {
// Constrained-env stacks are small; enough for IDF's own one-liners
char stack_buf[256];
LogBuffer buf{stack_buf, sizeof(stack_buf)};
buf.write_header(idf_to_esphome_level(message->config.opts.log_level), message->tag ? message->tag : "esp-idf", 0,
nullptr);
buf.format_body(message->format, message->args);
esp_rom_printf("%s\n", stack_buf);
}
} // namespace esphome::logger
extern "C" {
// Replaces liblog's formatter, which calls the vprintf hook 3x per message
// (header, body, newline). --wrap because a strong definition collides:
// liblog resolves the symbol within its own archive. Not IRAM_ATTR: cache-off
// callers bypass esp_log() under CONSTRAINED_ENV_SAFE=n.
void __wrap_esp_log_format(esp_log_msg_t *message) { // NOLINT
extern vprintf_like_t esp_log_vprint_func;
if (esp_log_vprint_func == &esphome::esp_idf_log_vprintf_) [[likely]] {
if (message->config.opts.constrained_env) [[unlikely]] {
esphome::logger::esp_log_format_direct(message);
return;
}
// Call the logger directly with V2's separate tag and severity so lines
// render as e.g. "[E][wifi]:"; the hook signature cannot carry them.
// global_logger is set before the hook is installed (pre_setup above).
esphome::logger::global_logger->log_vprintf_(esphome::logger::idf_to_esphome_level(message->config.opts.log_level),
message->tag ? message->tag : "esp-idf", 0, message->format,
message->args);
return;
}
extern int vprintf(const char *, __gnuc_va_list); // NOLINT
if (esp_log_vprint_func == &vprintf || message->config.opts.constrained_env) {
// No hook yet (early boot) or constrained env: direct console output
esphome::logger::esp_log_format_direct(message);
return;
}
// Custom hook via esp_log_set_vprintf: forward the body as-is
esp_log_vprint_func(message->format, message->args);
}
} // extern "C"
#endif // USE_ESP32_LOG_V2
#endif
@@ -37,6 +37,7 @@ int NoiseResponderHandshake::init(const psk_t &psk, const uint8_t *prologue, siz
.cipher_id = NOISE_CIPHER_CHACHAPOLY,
.hash_id = NOISE_HASH_SHA256,
.hybrid_id = NOISE_DH_NONE,
.reserved = {},
};
int err = noise_handshakestate_new_by_id(&this->handshake_, &nid, NOISE_ROLE_RESPONDER);
+1
View File
@@ -307,6 +307,7 @@
#define USE_ESPNOW_MAX_PAYLOAD_SIZE 1470
#define USE_CAPTIVE_PORTAL
#define USE_ESP32_LOG_V2
#define USE_WIFI_SCAN_RESULTS_LOCK
#define USE_ESP32_BLE
#define USE_ESP32_BLE_MAX_CONNECTIONS 3
+3 -2
View File
@@ -178,9 +178,10 @@ extra_scripts =
; This are common settings for the ESP32 (all variants) using IDF.
[common:esp32-idf]
extends = common:idf
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
; TEMP: IDF 6.1 for Log V2 CI testing; revert to 55.03.311 / v5.5.5 before merge
platform = https://github.com/bdraco/platform-espressif32.git#idf61-test
platform_packages =
pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v5.5.5/esp-idf-v5.5.5.tar.xz
pioarduino/framework-espidf@https://github.com/bdraco/esp-idf/releases/download/v6.1.0/esp-idf-v6.1.0.tar.xz
framework = espidf
lib_deps =