1
0
Fork 0
mirror of https://github.com/imjasonh/esp32 synced 2026-07-06 23:52:24 +00:00
esp32/sdkconfig.defaults.in
Jason Hall f0c23bbe1b Serialize short HTTPS calls; tighten mbedtls per-session heap
The metrics work in PR #10 added a third concurrent TLS client
(metrics → monitoring.googleapis.com) on top of cloud_log → logging
and OTA → ghcr. Three concurrent handshakes pinned ~90 KB of mbedtls
context and pushed `min_free_heap` into the single-digit-KB range,
producing intermittent ESP_ERR_HTTP_CONNECT failures (mbedtls
ALLOC_FAILED at -0x7F00).

Serialize via a shared `Arc<Mutex<()>>` constructed in main and held
**at the call sites** in each sender — std `Mutex` isn't reentrant and
`auth.get_or_refresh()` mints a token (an HTTPS POST to oauth2) that
must run inside the same critical section. Lock granularity:

- cloud_log: token-refresh + entries:write under one lock window.
- metrics: token-refresh + timeSeries.create under one lock window.
- ota::poll_once: token + manifest under lock; release for the
  signature bundle fetch's lock; release; verify (CPU, no TLS);
  download_and_apply UNLOCKED. Releasing between phases avoids
  blocking cloud_log/metrics behind ~2s of pure-Rust X.509/ECDSA work.
- ota::download_and_apply: deliberately not in the lock — multi-second
  blob downloads must not block per-5-s log flushes or per-30-s
  metrics POSTs.

Plus mbedtls heap knobs that compose with the dynamic-buffer config
already in sdkconfig:

- CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n: drop the parsed peer
  cert chain after handshake. We don't reuse sessions or do mutual
  TLS, so we never need it post-handshake. Saves ~3-5 KB per active
  session.

Known limitation, deferred to a follow-up: cloud_log/metrics handshakes
can still collide with the held-open OTA download session and OOM the
download mid-stream. The plan there is an `OTA_DOWNLOAD_IN_PROGRESS`
atomic that cloud_log + metrics check before locking — they skip the
POST and let the queue accumulate until the download finishes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:48:53 -04:00

48 lines
2.4 KiB
Text

CONFIG_ESP_MAIN_TASK_STACK_SIZE=7000
# Default for std::thread::spawn() without explicit stack_size. Bumped from
# 8192 because anything that does HTTPS + JSON + SHA blows past 8 KB.
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=16384
# HTTPS via ESP-IDF's bundled root CA store (esp_crt_bundle_attach in main.rs)
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y
# mbedtls heap budgeting. We routinely have 2-3 concurrent TLS sessions
# (cloud_log → logging.googleapis.com, metrics → monitoring.googleapis.com,
# OTA → ghcr.io / pkg-containers); without these knobs the per-session
# heap pinned for I/O buffers + cert chain blows our budget and the
# next handshake fails with MBEDTLS_ERR_SSL_ALLOC_FAILED (-0x7F00).
#
# Even with serialization (cloud_log + metrics + OTA short fetches share
# a Mutex; OTA blob download deliberately doesn't), the OTA download
# holds its session open for tens of seconds while metrics/cloud_log
# handshakes need to fit alongside it.
#
# - DYNAMIC_BUFFER: I/O buffers grow per-session up to the configured
# max instead of being pinned at 16+16 KB.
# - DYNAMIC_FREE_CONFIG_DATA: free the mbedtls_ssl_config struct after
# handshake.
# - DYNAMIC_FREE_CA_CERT: drop the CA bundle data after handshake (we
# re-attach it from esp_crt_bundle on the next handshake).
# - SSL_KEEP_PEER_CERTIFICATE=n: drop the parsed peer cert chain after
# handshake. We don't reuse sessions or do mutual TLS, so we never
# need it post-handshake. Saves ~3-5 KB per active session.
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
# OTA: custom partition table with two app slots, plus app-rollback support
# so a bad OTA can be reverted by the bootloader on next boot.
CONFIG_PARTITION_TABLE_CUSTOM=y
# Absolute path because IDF resolves this relative to its CMake project,
# which for embuild is the synthetic project under target/, not our repo
# root. The Makefile generates sdkconfig.defaults from this template
# (sdkconfig.defaults.in), substituting @PROJECT_DIR@ at build time.
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="@PROJECT_DIR@/partitions.csv"
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
# Inland board has 4MB flash; default IDF assumes 2MB which is too small
# for our 1.5MB-each OTA partition layout.
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"