[esp32_camera] Enable PicolibC Newlib compatibility on IDF 6.0+ (#16703)
This commit is contained in:
1 parent
dd961156d0
commit
091a05ccde
3 files changed
+45
-13
No files matched your search
@@ -1,5 +1,8 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components.esp32 import add_idf_component
|
from esphome.components.esp32 import (
|
||||||
|
add_idf_component,
|
||||||
|
require_libc_picolibc_newlib_compat,
|
||||||
|
)
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_BUFFER_SIZE, CONF_ID, CONF_TYPE
|
from esphome.const import CONF_BUFFER_SIZE, CONF_ID, CONF_TYPE
|
||||||
from esphome.types import ConfigType
|
from esphome.types import ConfigType
|
||||||
@@ -51,6 +54,8 @@ async def to_code(config: ConfigType) -> None:
|
|||||||
cg.add(buffer.set_buffer_size(config[CONF_BUFFER_SIZE]))
|
cg.add(buffer.set_buffer_size(config[CONF_BUFFER_SIZE]))
|
||||||
if config[CONF_TYPE] == ESP32_CAMERA_ENCODER:
|
if config[CONF_TYPE] == ESP32_CAMERA_ENCODER:
|
||||||
add_idf_component(name="espressif/esp32-camera", ref="2.1.5")
|
add_idf_component(name="espressif/esp32-camera", ref="2.1.5")
|
||||||
|
# esp32-camera 2.1.5 needs the Newlib shim on IDF 6.0+; remove when fixed upstream
|
||||||
|
require_libc_picolibc_newlib_compat()
|
||||||
cg.add_define("USE_ESP32_CAMERA_JPEG_ENCODER")
|
cg.add_define("USE_ESP32_CAMERA_JPEG_ENCODER")
|
||||||
var = cg.new_Pvariable(
|
var = cg.new_Pvariable(
|
||||||
config[CONF_ID],
|
config[CONF_ID],
|
||||||
|
|||||||
@@ -1245,6 +1245,7 @@ KEY_MBEDTLS_PKCS7_REQUIRED = "mbedtls_pkcs7_required"
|
|||||||
KEY_FATFS_REQUIRED = "fatfs_required"
|
KEY_FATFS_REQUIRED = "fatfs_required"
|
||||||
KEY_MBEDTLS_SHA512_REQUIRED = "mbedtls_sha512_required"
|
KEY_MBEDTLS_SHA512_REQUIRED = "mbedtls_sha512_required"
|
||||||
KEY_ADC_ONESHOT_IRAM_REQUIRED = "adc_oneshot_iram_required"
|
KEY_ADC_ONESHOT_IRAM_REQUIRED = "adc_oneshot_iram_required"
|
||||||
|
KEY_LIBC_PICOLIBC_NEWLIB_COMPAT_REQUIRED = "libc_picolibc_newlib_compat_required"
|
||||||
|
|
||||||
|
|
||||||
def require_vfs_select() -> None:
|
def require_vfs_select() -> None:
|
||||||
@@ -1353,6 +1354,15 @@ def require_adc_oneshot_iram() -> None:
|
|||||||
CORE.data[KEY_ESP32][KEY_ADC_ONESHOT_IRAM_REQUIRED] = True
|
CORE.data[KEY_ESP32][KEY_ADC_ONESHOT_IRAM_REQUIRED] = True
|
||||||
|
|
||||||
|
|
||||||
|
def require_libc_picolibc_newlib_compat() -> None:
|
||||||
|
"""Keep CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY enabled on IDF 6.0+.
|
||||||
|
|
||||||
|
Call this from components that link against precompiled Newlib binaries
|
||||||
|
referencing types/symbols the shim provides (e.g. esp32-camera).
|
||||||
|
"""
|
||||||
|
CORE.data[KEY_ESP32][KEY_LIBC_PICOLIBC_NEWLIB_COMPAT_REQUIRED] = True
|
||||||
|
|
||||||
|
|
||||||
def _parse_idf_component(value: str) -> ConfigType:
|
def _parse_idf_component(value: str) -> ConfigType:
|
||||||
"""Parse IDF component shorthand syntax like 'owner/component^version'"""
|
"""Parse IDF component shorthand syntax like 'owner/component^version'"""
|
||||||
# Match operator followed by version-like string (digit or *)
|
# Match operator followed by version-like string (digit or *)
|
||||||
@@ -1758,6 +1768,26 @@ async def _write_arduino_libraries_sdkconfig() -> None:
|
|||||||
add_idf_sdkconfig_option(f"CONFIG_ARDUINO_SELECTIVE_{lib}", lib in enabled_libs)
|
add_idf_sdkconfig_option(f"CONFIG_ARDUINO_SELECTIVE_{lib}", lib in enabled_libs)
|
||||||
|
|
||||||
|
|
||||||
|
@coroutine_with_priority(CoroPriority.FINAL)
|
||||||
|
async def _set_libc_picolibc_newlib_compat() -> None:
|
||||||
|
"""Apply the PicolibC Newlib compatibility shim option on IDF 6.0+.
|
||||||
|
|
||||||
|
IDF 6.0 switched from Newlib to PicolibC; the shim is disabled by default.
|
||||||
|
Runs at FINAL priority so every require_libc_picolibc_newlib_compat() call
|
||||||
|
(default priority) is seen before the option is written. A user-supplied
|
||||||
|
sdkconfig_options value takes precedence.
|
||||||
|
"""
|
||||||
|
if idf_version() < cv.Version(6, 0, 0):
|
||||||
|
return
|
||||||
|
option = "CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY"
|
||||||
|
if option in CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS]:
|
||||||
|
return
|
||||||
|
add_idf_sdkconfig_option(
|
||||||
|
option,
|
||||||
|
CORE.data[KEY_ESP32].get(KEY_LIBC_PICOLIBC_NEWLIB_COMPAT_REQUIRED, False),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(CoroPriority.FINAL)
|
@coroutine_with_priority(CoroPriority.FINAL)
|
||||||
async def _add_yaml_idf_components(components: list[ConfigType]):
|
async def _add_yaml_idf_components(components: list[ConfigType]):
|
||||||
"""Add IDF components from YAML config with final priority to override code-added components."""
|
"""Add IDF components from YAML config with final priority to override code-added components."""
|
||||||
@@ -2291,17 +2321,8 @@ async def to_code(config):
|
|||||||
add_idf_sdkconfig_option("CONFIG_MBEDTLS_SHA384_C", False)
|
add_idf_sdkconfig_option("CONFIG_MBEDTLS_SHA384_C", False)
|
||||||
add_idf_sdkconfig_option("CONFIG_MBEDTLS_SHA512_C", False)
|
add_idf_sdkconfig_option("CONFIG_MBEDTLS_SHA512_C", False)
|
||||||
|
|
||||||
# Disable PicolibC Newlib compatibility shim on IDF 6.0+
|
# FINAL priority: runs after every require_libc_picolibc_newlib_compat() call
|
||||||
# IDF 6.0 switched from Newlib to PicolibC. The shim provides thread-local
|
CORE.add_job(_set_libc_picolibc_newlib_compat)
|
||||||
# stdin/stdout/stderr and getreent() for code compiled against Newlib.
|
|
||||||
# ESPHome doesn't link against Newlib-built libraries that use stdio.
|
|
||||||
# If a component needs it (e.g. precompiled Newlib binaries), re-enable via:
|
|
||||||
# esp32:
|
|
||||||
# framework:
|
|
||||||
# sdkconfig_options:
|
|
||||||
# CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY: "y"
|
|
||||||
if idf_version() >= cv.Version(6, 0, 0):
|
|
||||||
add_idf_sdkconfig_option("CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY", False)
|
|
||||||
|
|
||||||
# Disable regi2c control functions in IRAM
|
# Disable regi2c control functions in IRAM
|
||||||
# Only needed if using analog peripherals (ADC, DAC, etc.) from ISRs while cache is disabled
|
# Only needed if using analog peripherals (ADC, DAC, etc.) from ISRs while cache is disabled
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import logging
|
|||||||
from esphome import automation, pins
|
from esphome import automation, pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import i2c
|
from esphome.components import i2c
|
||||||
from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
|
from esphome.components.esp32 import (
|
||||||
|
add_idf_component,
|
||||||
|
add_idf_sdkconfig_option,
|
||||||
|
require_libc_picolibc_newlib_compat,
|
||||||
|
)
|
||||||
from esphome.components.psram import DOMAIN as psram_domain
|
from esphome.components.psram import DOMAIN as psram_domain
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
@@ -402,6 +406,8 @@ async def to_code(config):
|
|||||||
add_idf_component(name="espressif/esp32-camera", ref="2.1.5")
|
add_idf_component(name="espressif/esp32-camera", ref="2.1.5")
|
||||||
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_NEW", True)
|
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_NEW", True)
|
||||||
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_LEGACY", False)
|
add_idf_sdkconfig_option("CONFIG_SCCB_HARDWARE_I2C_DRIVER_LEGACY", False)
|
||||||
|
# esp32-camera 2.1.5 needs the Newlib shim on IDF 6.0+; remove when fixed upstream
|
||||||
|
require_libc_picolibc_newlib_compat()
|
||||||
|
|
||||||
for conf in config.get(CONF_ON_STREAM_START, []):
|
for conf in config.get(CONF_ON_STREAM_START, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
|
|||||||
Reference in new issue
Block a user