Compare commits

...

2 Commits

Author SHA1 Message Date
J. Nick Koston
8f367571f8 Add precondition comment to process_dump_config_() 2026-02-09 20:01:43 -06:00
J. Nick Koston
1213774168 [core] Extract dump_config from Application::loop() hot path
Extract the dump_config block (version/chip info logging + per-component
dump_config iteration) into a separate noinline process_dump_config_()
method.

This code runs once at startup and once on API reconnect, but was
inlined into loop() which runs ~7000 times/minute. On ESP32 the
dump_config block compiled to ~140 bytes (38% of loop's 368 bytes),
including esp_chip_info(), integer division for revision formatting,
and multiple ESP_LOG calls. Extracting it frees ~2 icache lines for
the hot path.
2026-02-09 19:43:25 -06:00
2 changed files with 30 additions and 21 deletions

View File

@@ -204,36 +204,40 @@ void Application::loop() {
this->last_loop_ = last_op_end_time;
if (this->dump_config_at_ < this->components_.size()) {
if (this->dump_config_at_ == 0) {
char build_time_str[Application::BUILD_TIME_STR_SIZE];
this->get_build_time_string(build_time_str);
ESP_LOGI(TAG, "ESPHome version " ESPHOME_VERSION " compiled on %s", build_time_str);
this->process_dump_config_();
}
}
void Application::process_dump_config_() {
if (this->dump_config_at_ == 0) {
char build_time_str[Application::BUILD_TIME_STR_SIZE];
this->get_build_time_string(build_time_str);
ESP_LOGI(TAG, "ESPHome version " ESPHOME_VERSION " compiled on %s", build_time_str);
#ifdef ESPHOME_PROJECT_NAME
ESP_LOGI(TAG, "Project " ESPHOME_PROJECT_NAME " version " ESPHOME_PROJECT_VERSION);
ESP_LOGI(TAG, "Project " ESPHOME_PROJECT_NAME " version " ESPHOME_PROJECT_VERSION);
#endif
#ifdef USE_ESP32
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
ESP_LOGI(TAG, "ESP32 Chip: %s rev%d.%d, %d core(s)", ESPHOME_VARIANT, chip_info.revision / 100,
chip_info.revision % 100, chip_info.cores);
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
ESP_LOGI(TAG, "ESP32 Chip: %s rev%d.%d, %d core(s)", ESPHOME_VARIANT, chip_info.revision / 100,
chip_info.revision % 100, chip_info.cores);
#if defined(USE_ESP32_VARIANT_ESP32) && !defined(USE_ESP32_MIN_CHIP_REVISION_SET)
// Suggest optimization for chips that don't need the PSRAM cache workaround
if (chip_info.revision >= 300) {
// Suggest optimization for chips that don't need the PSRAM cache workaround
if (chip_info.revision >= 300) {
#ifdef USE_PSRAM
ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to save ~10KB IRAM", chip_info.revision / 100,
chip_info.revision % 100);
ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to save ~10KB IRAM", chip_info.revision / 100,
chip_info.revision % 100);
#else
ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to reduce binary size", chip_info.revision / 100,
chip_info.revision % 100);
#endif
}
#endif
ESP_LOGW(TAG, "Set minimum_chip_revision: \"%d.%d\" to reduce binary size", chip_info.revision / 100,
chip_info.revision % 100);
#endif
}
this->components_[this->dump_config_at_]->call_dump_config();
this->dump_config_at_++;
#endif
#endif
}
this->components_[this->dump_config_at_]->call_dump_config();
this->dump_config_at_++;
}
void IRAM_ATTR HOT Application::feed_wdt(uint32_t time) {

View File

@@ -519,6 +519,11 @@ class Application {
void before_loop_tasks_(uint32_t loop_start_time);
void after_loop_tasks_();
/// Process dump_config output one component per loop iteration.
/// Extracted from loop() to keep cold startup/reconnect logging out of the hot path.
/// Caller must ensure dump_config_at_ < components_.size().
void __attribute__((noinline)) process_dump_config_();
void feed_wdt_arch_();
/// Perform a delay while also monitoring socket file descriptors for readiness