[wifi] Defer esp_wifi_init() to lazy-init so enable_on_boot: false actually saves RAM (#16606)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
805aa252d5
commit
4e48682468
4 files changed
+54
-3
No files matched your search
@@ -632,6 +632,9 @@ void WiFiComponent::setup() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (this->enable_on_boot_) {
|
if (this->enable_on_boot_) {
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
this->wifi_lazy_init_();
|
||||||
|
#endif
|
||||||
this->start();
|
this->start();
|
||||||
} else {
|
} else {
|
||||||
this->state_ = WIFI_COMPONENT_STATE_DISABLED;
|
this->state_ = WIFI_COMPONENT_STATE_DISABLED;
|
||||||
@@ -1275,6 +1278,11 @@ void WiFiComponent::enable() {
|
|||||||
|
|
||||||
ESP_LOGD(TAG, "Enabling");
|
ESP_LOGD(TAG, "Enabling");
|
||||||
this->state_ = WIFI_COMPONENT_STATE_OFF;
|
this->state_ = WIFI_COMPONENT_STATE_OFF;
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
// Idempotent — only allocates DMA buffers + netifs on the first call. After this,
|
||||||
|
// start() can safely run.
|
||||||
|
this->wifi_lazy_init_();
|
||||||
|
#endif
|
||||||
this->start();
|
this->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -694,6 +694,12 @@ class WiFiComponent final : public Component {
|
|||||||
bool wifi_apply_hostname_();
|
bool wifi_apply_hostname_();
|
||||||
bool wifi_sta_connect_(const WiFiAP &ap);
|
bool wifi_sta_connect_(const WiFiAP &ap);
|
||||||
void wifi_pre_setup_();
|
void wifi_pre_setup_();
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
// ESP-IDF only: defers esp_wifi_init() + netif creation (which allocate ~15-30KB of
|
||||||
|
// DMA-capable internal SRAM) until wifi actually needs to come up. Idempotent.
|
||||||
|
// Called from setup() only when enable_on_boot_=true, and from enable() on first use.
|
||||||
|
void wifi_lazy_init_();
|
||||||
|
#endif
|
||||||
WiFiSTAConnectStatus wifi_sta_connect_status_() const;
|
WiFiSTAConnectStatus wifi_sta_connect_status_() const;
|
||||||
bool is_connected_() const {
|
bool is_connected_() const {
|
||||||
return this->state_ == WIFI_COMPONENT_STATE_STA_CONNECTED &&
|
return this->state_ == WIFI_COMPONENT_STATE_STA_CONNECTED &&
|
||||||
@@ -889,6 +895,12 @@ class WiFiComponent final : public Component {
|
|||||||
bool rrm_{false};
|
bool rrm_{false};
|
||||||
#endif
|
#endif
|
||||||
bool enable_on_boot_{true};
|
bool enable_on_boot_{true};
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
// Tracks whether esp_wifi_init() + netif creation has happened. Allows enable()
|
||||||
|
// to be called at runtime without re-allocating, and ensures the heavy init is
|
||||||
|
// skipped entirely when enable_on_boot_ is false until first enable().
|
||||||
|
bool wifi_initialized_{false};
|
||||||
|
#endif
|
||||||
bool got_ipv4_address_{false};
|
bool got_ipv4_address_{false};
|
||||||
bool keep_scan_results_{false};
|
bool keep_scan_results_{false};
|
||||||
bool has_completed_scan_after_captive_portal_start_{
|
bool has_completed_scan_after_captive_portal_start_{
|
||||||
|
|||||||
@@ -163,11 +163,26 @@ void WiFiComponent::wifi_pre_setup_() {
|
|||||||
ESP_LOGE(TAG, "esp_event_handler_instance_register failed: %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "esp_event_handler_instance_register failed: %s", esp_err_to_name(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// NOTE: netif creation + esp_wifi_init() used to live here. They allocate ~15-30KB of
|
||||||
|
// DMA-capable internal SRAM, which competes with W5500 SPI DMA and I2S DMA on
|
||||||
|
// memory-tight devices. They are now deferred to wifi_lazy_init_(), called from
|
||||||
|
// setup() when enable_on_boot_ is true, or from enable() on first runtime enable.
|
||||||
|
// This makes enable_on_boot:false genuinely skip the wifi DMA allocation.
|
||||||
|
}
|
||||||
|
|
||||||
s_sta_netif = esp_netif_create_default_wifi_sta();
|
void WiFiComponent::wifi_lazy_init_() {
|
||||||
|
if (this->wifi_initialized_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Guard each creation so partial init (e.g. a failed esp_wifi_init() below)
|
||||||
|
// followed by a retry via enable() does not leak the existing netif handle
|
||||||
|
// nor re-register the default WiFi handlers.
|
||||||
|
if (s_sta_netif == nullptr)
|
||||||
|
s_sta_netif = esp_netif_create_default_wifi_sta();
|
||||||
|
|
||||||
#ifdef USE_WIFI_AP
|
#ifdef USE_WIFI_AP
|
||||||
s_ap_netif = esp_netif_create_default_wifi_ap();
|
if (s_ap_netif == nullptr)
|
||||||
|
s_ap_netif = esp_netif_create_default_wifi_ap();
|
||||||
#endif // USE_WIFI_AP
|
#endif // USE_WIFI_AP
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
@@ -175,7 +190,7 @@ void WiFiComponent::wifi_pre_setup_() {
|
|||||||
ESP_LOGW(TAG, "starting wifi without nvs");
|
ESP_LOGW(TAG, "starting wifi without nvs");
|
||||||
cfg.nvs_enable = false;
|
cfg.nvs_enable = false;
|
||||||
}
|
}
|
||||||
err = esp_wifi_init(&cfg);
|
esp_err_t err = esp_wifi_init(&cfg);
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
ESP_LOGE(TAG, "esp_wifi_init failed: %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "esp_wifi_init failed: %s", esp_err_to_name(err));
|
||||||
return;
|
return;
|
||||||
@@ -185,6 +200,7 @@ void WiFiComponent::wifi_pre_setup_() {
|
|||||||
ESP_LOGE(TAG, "esp_wifi_set_storage failed: %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "esp_wifi_set_storage failed: %s", esp_err_to_name(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this->wifi_initialized_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
|
bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
wifi:
|
||||||
|
ssid: MySSID
|
||||||
|
password: password1
|
||||||
|
enable_on_boot: false
|
||||||
|
|
||||||
|
esphome:
|
||||||
|
on_boot:
|
||||||
|
priority: 200
|
||||||
|
then:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
not:
|
||||||
|
wifi.enabled:
|
||||||
|
then:
|
||||||
|
- wifi.enable:
|
||||||
Reference in new issue
Block a user