mirror of
https://github.com/esphome/esphome.git
synced 2025-08-03 17:07:54 +00:00
Add heap tracing capability to API component
- Add heap tracing configuration options to API component - Implement periodic heap trace dumping (every 30 seconds) - Configure ESP-IDF settings for heap tracing - Add sample YAML configuration - Useful for debugging memory reallocation overhead issues
This commit is contained in:
parent
8e29437900
commit
35238c1437
@ -1,8 +1,10 @@
|
||||
import base64
|
||||
import logging
|
||||
|
||||
from esphome import automation
|
||||
from esphome.automation import Condition
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.esp32 import add_idf_sdkconfig_option
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ACTION,
|
||||
@ -23,12 +25,14 @@ from esphome.const import (
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_VARIABLES,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
|
||||
DEPENDENCIES = ["network"]
|
||||
AUTO_LOAD = ["socket"]
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
api_ns = cg.esphome_ns.namespace("api")
|
||||
APIServer = api_ns.class_("APIServer", cg.Component, cg.Controller)
|
||||
HomeAssistantServiceCallAction = api_ns.class_(
|
||||
@ -49,6 +53,9 @@ SERVICE_ARG_NATIVE_TYPES = {
|
||||
"string[]": cg.std_vector.template(cg.std_string),
|
||||
}
|
||||
CONF_ENCRYPTION = "encryption"
|
||||
CONF_HEAP_TRACING = "heap_tracing"
|
||||
CONF_HEAP_TRACING_STANDALONE = "standalone" # vs SYSTEM
|
||||
CONF_HEAP_TRACING_RECORDS = "num_records"
|
||||
|
||||
|
||||
def validate_encryption_key(value):
|
||||
@ -95,6 +102,20 @@ def _encryption_schema(config):
|
||||
return ENCRYPTION_SCHEMA(config)
|
||||
|
||||
|
||||
HEAP_TRACING_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_HEAP_TRACING_STANDALONE, default=True): cv.boolean,
|
||||
cv.Optional(CONF_HEAP_TRACING_RECORDS, default=100): cv.positive_int,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _heap_tracing_schema(config):
|
||||
if config is None:
|
||||
config = {}
|
||||
return HEAP_TRACING_SCHEMA(config)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
@ -109,6 +130,7 @@ CONFIG_SCHEMA = cv.All(
|
||||
): ACTIONS_SCHEMA,
|
||||
cv.Exclusive(CONF_ACTIONS, group_of_exclusion=CONF_ACTIONS): ACTIONS_SCHEMA,
|
||||
cv.Optional(CONF_ENCRYPTION): _encryption_schema,
|
||||
cv.Optional(CONF_HEAP_TRACING): _heap_tracing_schema,
|
||||
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
|
||||
single=True
|
||||
),
|
||||
@ -176,6 +198,59 @@ async def to_code(config):
|
||||
else:
|
||||
cg.add_define("USE_API_PLAINTEXT")
|
||||
|
||||
# Handle heap tracing configuration if ESP32 platform and using ESP-IDF
|
||||
if (heap_tracing_config := config.get(CONF_HEAP_TRACING, None)) is not None:
|
||||
if CORE.using_esp_idf:
|
||||
# Enable heap tracing in sdkconfig
|
||||
add_idf_sdkconfig_option("CONFIG_HEAP_TRACING", True)
|
||||
|
||||
# Set tracing mode (standalone or system)
|
||||
if heap_tracing_config[CONF_HEAP_TRACING_STANDALONE]:
|
||||
add_idf_sdkconfig_option("CONFIG_HEAP_TRACING_STANDALONE", True)
|
||||
else:
|
||||
add_idf_sdkconfig_option("CONFIG_HEAP_TRACING_SYSTEM", True)
|
||||
|
||||
# Generate code to implement heap tracing
|
||||
cg.add_global(cg.RawStatement('#include "esp_heap_trace.h"'))
|
||||
|
||||
# Define the trace record buffer
|
||||
num_records = heap_tracing_config[CONF_HEAP_TRACING_RECORDS]
|
||||
cg.add_global(
|
||||
cg.RawStatement(
|
||||
f"static heap_trace_record_t trace_record[{num_records}];"
|
||||
)
|
||||
)
|
||||
|
||||
# Add helper functions for heap tracing
|
||||
cg.add_global(
|
||||
cg.RawStatement(
|
||||
"""
|
||||
void start_heap_trace() {
|
||||
heap_trace_init_standalone(trace_record, """
|
||||
+ str(num_records)
|
||||
+ """);
|
||||
heap_trace_start(HEAP_TRACE_LEAKS);
|
||||
}
|
||||
|
||||
void stop_and_dump_heap_trace() {
|
||||
heap_trace_stop();
|
||||
heap_trace_dump();
|
||||
}
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
# Add periodic heap trace dumping to the api_server.cpp file
|
||||
# This will be added in C++ code
|
||||
cg.add_define("USE_API_HEAP_TRACE")
|
||||
|
||||
else:
|
||||
# Not using ESP-IDF, so we can't use heap tracing
|
||||
_LOGGER.warning(
|
||||
"Heap tracing is only available when using ESP-IDF. "
|
||||
"Disabling heap tracing configuration."
|
||||
)
|
||||
|
||||
cg.add_define("USE_API")
|
||||
cg.add_global(api_ns.using)
|
||||
|
||||
|
@ -30,6 +30,11 @@ void APIServer::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Setting up Home Assistant API server...");
|
||||
this->setup_controller();
|
||||
|
||||
#ifdef USE_API_HEAP_TRACE
|
||||
ESP_LOGI(TAG, "Initializing heap tracing");
|
||||
start_heap_trace();
|
||||
#endif
|
||||
|
||||
#ifdef USE_API_NOISE
|
||||
uint32_t hash = 88491486UL;
|
||||
|
||||
@ -154,6 +159,21 @@ void APIServer::loop() {
|
||||
this->status_clear_warning();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_API_HEAP_TRACE
|
||||
// Periodically dump heap trace information (every 30 seconds)
|
||||
static uint32_t last_heap_trace_dump = 0;
|
||||
const uint32_t now = millis();
|
||||
if (now - last_heap_trace_dump > 30000) { // 30 seconds
|
||||
ESP_LOGI(TAG, "Dumping heap trace information");
|
||||
stop_and_dump_heap_trace();
|
||||
|
||||
// Start a new trace for the next period
|
||||
start_heap_trace();
|
||||
|
||||
last_heap_trace_dump = now;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void APIServer::dump_config() {
|
||||
@ -466,6 +486,12 @@ void APIServer::on_shutdown() {
|
||||
c->send_disconnect_request(DisconnectRequest());
|
||||
}
|
||||
delay(10);
|
||||
|
||||
#ifdef USE_API_HEAP_TRACE
|
||||
// Make sure to stop tracing on shutdown to get final results
|
||||
ESP_LOGI(TAG, "Final heap trace dump on shutdown");
|
||||
stop_and_dump_heap_trace();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
33
heap_trace_example.yaml
Normal file
33
heap_trace_example.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
esphome:
|
||||
name: esp32-heap-trace
|
||||
platform: ESP32
|
||||
board: esp32dev
|
||||
# Use ESP-IDF framework which is required for heap tracing
|
||||
framework:
|
||||
type: esp-idf
|
||||
version: recommended
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
level: INFO
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
# Enable heap tracing with the following configuration
|
||||
heap_tracing:
|
||||
# Use standalone tracing (vs system tracing)
|
||||
standalone: true
|
||||
# Number of trace records to keep (more records = more memory usage)
|
||||
num_records: 100
|
||||
|
||||
# Enable OTA updates
|
||||
ota:
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
# Enable fallback hotspot in case wifi connection fails
|
||||
ap:
|
||||
ssid: "Esp32-Heap-Trace"
|
||||
password: "12345678"
|
Loading…
x
Reference in New Issue
Block a user