From 5dd7ab7ce7a41ee3da4fd964c6ea555b4af4c61b Mon Sep 17 00:00:00 2001 From: "Sameer .I. Siddiqui" Date: Mon, 22 Sep 2025 00:41:03 +0530 Subject: [PATCH 1/2] fix(wifi): stabilize hosted softap bringup --- .../tab5/main/hal/components/hal_wifi.cpp | 382 +++++++++++------- 1 file changed, 235 insertions(+), 147 deletions(-) diff --git a/platforms/tab5/main/hal/components/hal_wifi.cpp b/platforms/tab5/main/hal/components/hal_wifi.cpp index eebbc95..100348e 100644 --- a/platforms/tab5/main/hal/components/hal_wifi.cpp +++ b/platforms/tab5/main/hal/components/hal_wifi.cpp @@ -3,21 +3,21 @@ * * SPDX-License-Identifier: MIT */ -#include "hal/hal_esp32.h" -#include -#include -#include -#include +#include #include -#include -#include -#include -#include +#include +#include #include +#include #include -#include #include -#include +#include +#include +#include +#include +#include + +#include "hal/hal_esp32.h" #define TAG "wifi" @@ -25,172 +25,257 @@ #define WIFI_PASS "" #define MAX_STA_CONN 4 -// HTTP 处理函数 -esp_err_t hello_get_handler(httpd_req_t* req) +namespace { - const char* html_response = R"rawliteral( - - - - Hello - - - -

Hello World

-

From M5Tab5

- - - )rawliteral"; - - httpd_resp_set_type(req, "text/html"); - httpd_resp_send(req, html_response, HTTPD_RESP_USE_STRLEN); - return ESP_OK; -} -// URI 路由 -httpd_uri_t hello_uri = {.uri = "/", .method = HTTP_GET, .handler = hello_get_handler, .user_ctx = nullptr}; + struct WifiRuntimeState + { + bool attempted = false; + bool started = false; + bool failed = false; + }; -// 启动 Web Server -httpd_handle_t start_webserver() -{ - httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - httpd_handle_t server = nullptr; + WifiRuntimeState& wifi_state() + { + static WifiRuntimeState state; + return state; + } - if (httpd_start(&server, &config) == ESP_OK) { - httpd_register_uri_handler(server, &hello_uri); + portMUX_TYPE& wifi_state_spinlock() + { + static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + return spinlock; } - return server; -} -// 初始化 Wi-Fi AP 模式 -void wifi_init_softap() -{ - static bool s_netif_ready = false; - static bool s_event_loop_ready = false; - - if (!s_netif_ready) { - esp_err_t err = esp_netif_init(); - if (err == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "esp_netif already initialized"); - } else if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_netif_init failed: %s", esp_err_to_name(err)); - return; - } - s_netif_ready = true; + struct NetifGuards + { + bool netif_ready = false; + bool event_loop_ready = false; + }; + + NetifGuards& netif_guards() + { + static NetifGuards guards; + return guards; } - if (!s_event_loop_ready) { - esp_err_t err = esp_event_loop_create_default(); - if (err == ESP_ERR_INVALID_STATE) { - ESP_LOGW(TAG, "default event loop already created"); - } else if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_event_loop_create_default failed: %s", esp_err_to_name(err)); - return; + esp_err_t ensure_nvs_initialised() + { + static bool initialised = false; + if (initialised) + { + return ESP_OK; } - s_event_loop_ready = true; - } - esp_netif_t* netif = esp_netif_create_default_wifi_ap(); - if (netif == nullptr) { - ESP_LOGE(TAG, "failed to create default Wi-Fi AP netif"); - return; - } + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + ESP_RETURN_ON_ERROR(nvs_flash_erase(), TAG, "Failed to erase NVS"); + err = nvs_flash_init(); + } + ESP_RETURN_ON_ERROR(err, TAG, "Failed to initialise NVS"); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - esp_err_t err = esp_wifi_init(&cfg); - if (err == ESP_ERR_WIFI_INIT_STATE) { - ESP_LOGW(TAG, "Wi-Fi already initialized"); - } else if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_wifi_init failed: %s", esp_err_to_name(err)); - return; + initialised = true; + return ESP_OK; } - wifi_config_t wifi_config = {}; - std::strncpy(reinterpret_cast(wifi_config.ap.ssid), WIFI_SSID, sizeof(wifi_config.ap.ssid)); - std::strncpy(reinterpret_cast(wifi_config.ap.password), WIFI_PASS, sizeof(wifi_config.ap.password)); - wifi_config.ap.ssid_len = std::strlen(WIFI_SSID); - wifi_config.ap.max_connection = MAX_STA_CONN; - wifi_config.ap.authmode = WIFI_AUTH_OPEN; - - err = esp_wifi_set_mode(WIFI_MODE_AP); - if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_wifi_set_mode failed: %s", esp_err_to_name(err)); - return; - } + esp_err_t ensure_netif_ready() + { + auto& guards = netif_guards(); - err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config); - if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_wifi_set_config failed: %s", esp_err_to_name(err)); - return; - } + if (!guards.netif_ready) + { + esp_err_t err = esp_netif_init(); + if (err == ESP_ERR_INVALID_STATE) + { + ESP_LOGW(TAG, "esp_netif already initialised"); + } + else + { + ESP_RETURN_ON_ERROR(err, TAG, "Failed to initialise esp_netif"); + } + guards.netif_ready = true; + } - err = esp_wifi_start(); - if (err != ESP_OK && err != ESP_ERR_WIFI_CONN) { - ESP_LOGE(TAG, "esp_wifi_start failed: %s", esp_err_to_name(err)); - return; + if (!guards.event_loop_ready) + { + esp_err_t err = esp_event_loop_create_default(); + if (err == ESP_ERR_INVALID_STATE) + { + ESP_LOGW(TAG, "Event loop already created"); + } + else + { + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create default event loop"); + } + guards.event_loop_ready = true; + } + + return ESP_OK; } - ESP_LOGI(TAG, "Wi-Fi AP started. SSID:%s password:%s", WIFI_SSID, WIFI_PASS); -} + esp_err_t start_softap() + { + ESP_RETURN_ON_ERROR(ensure_nvs_initialised(), TAG, "NVS init failed"); + ESP_RETURN_ON_ERROR(ensure_netif_ready(), TAG, "netif init failed"); -static void wifi_ap_test_task(void* param) -{ - wifi_init_softap(); - start_webserver(); + esp_netif_t* netif = esp_netif_create_default_wifi_ap(); + if (netif == nullptr) + { + ESP_LOGE(TAG, "Failed to create AP netif"); + return ESP_FAIL; + } + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t err = esp_wifi_init(&cfg); + bool wifi_newly_initialised = false; + if (err == ESP_ERR_WIFI_INIT_STATE) + { + ESP_LOGW(TAG, "Wi-Fi already initialised"); + } + else if (err == ESP_OK) + { + wifi_newly_initialised = true; + } + else + { + esp_netif_destroy(netif); + return err; + } + + auto cleanup = [&](esp_err_t failure) + { + if (wifi_newly_initialised) + { + esp_wifi_stop(); + esp_wifi_deinit(); + } + if (netif != nullptr) + { + esp_netif_destroy(netif); + netif = nullptr; + } + return failure; + }; + + wifi_config_t wifi_config = {}; + std::fill(std::begin(wifi_config.ap.ssid), std::end(wifi_config.ap.ssid), 0); + std::fill(std::begin(wifi_config.ap.password), std::end(wifi_config.ap.password), 0); + std::strncpy(reinterpret_cast(wifi_config.ap.ssid), + WIFI_SSID, + sizeof(wifi_config.ap.ssid) - 1); + wifi_config.ap.ssid_len = std::strlen(WIFI_SSID); + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + wifi_config.ap.max_connection = MAX_STA_CONN; + wifi_config.ap.channel = 1; + + err = esp_wifi_set_mode(WIFI_MODE_AP); + if (err == ESP_ERR_NOT_SUPPORTED) + { + ESP_LOGW(TAG, "SoftAP mode not supported by remote Wi-Fi firmware"); + return cleanup(ESP_ERR_NOT_SUPPORTED); + } + if (err != ESP_OK) + { + return cleanup(err); + } + + err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config); + if (err != ESP_OK) + { + return cleanup(err); + } + + err = esp_wifi_start(); + if (err == ESP_ERR_WIFI_CONN) + { + ESP_LOGW(TAG, "Wi-Fi already started"); + esp_netif_destroy(netif); + netif = nullptr; + return ESP_OK; + } + if (err != ESP_OK) + { + return cleanup(err); + } + + // Ownership of the netif transfers to esp-netif after a successful start. + netif = nullptr; - while (1) { - vTaskDelay(pdMS_TO_TICKS(1000)); + ESP_LOGI(TAG, "SoftAP started (SSID:%s)", WIFI_SSID); + return ESP_OK; } - vTaskDelete(NULL); -} + +} // namespace bool HalEsp32::wifi_init() { - static bool s_wifi_task_started = false; + auto& state = wifi_state(); + portMUX_TYPE& spinlock = wifi_state_spinlock(); - mclog::tagInfo(TAG, "wifi init"); + portENTER_CRITICAL(&spinlock); + bool already_started = state.started; + bool previously_failed = state.failed; + state.attempted = true; + portEXIT_CRITICAL(&spinlock); - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); + if (already_started) + { + return true; + } + if (previously_failed) + { + ESP_LOGW(TAG, "Skipping Wi-Fi init after previous failure"); + return false; } - ESP_ERROR_CHECK(ret); - if (s_wifi_task_started) { - ESP_LOGW(TAG, "Wi-Fi init already in progress"); - return true; + mclog::tagInfo(TAG, "wifi init"); + + bsp_set_wifi_power_enable(true); + + // The hosted C6 coprocessor requires a short guard time after power up before it + // responds to the transport reset sequence. Without the delay the first RPC + // request races the SDIO link initialisation and the transport driver frees an + // uninitialised buffer, crashing the TLSF heap. Give the module time to boot + // and then explicitly request a transport re-sync before touching the Wi-Fi + // stack. + vTaskDelay(pdMS_TO_TICKS(200)); + + esp_err_t host_err = esp_hosted_slave_reset(); + if (host_err != ESP_OK) + { + ESP_LOGE(TAG, "Failed to bring ESP-Hosted transport up: %s", esp_err_to_name(host_err)); + portENTER_CRITICAL(&spinlock); + state.failed = true; + portEXIT_CRITICAL(&spinlock); + bsp_set_wifi_power_enable(false); + return false; } - BaseType_t task_created = xTaskCreate(wifi_ap_test_task, "ap", 4096, nullptr, 5, nullptr); - if (task_created == pdPASS) { - s_wifi_task_started = true; - return true; + esp_err_t err = start_softap(); + if (err == ESP_ERR_NOT_SUPPORTED) + { + ESP_LOGW(TAG, "SoftAP unsupported on hosted slave; Wi-Fi will stay disabled"); + portENTER_CRITICAL(&spinlock); + state.failed = true; + portEXIT_CRITICAL(&spinlock); + bsp_set_wifi_power_enable(false); + return false; + } + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Failed to start Wi-Fi: %s", esp_err_to_name(err)); + portENTER_CRITICAL(&spinlock); + state.failed = true; + portEXIT_CRITICAL(&spinlock); + bsp_set_wifi_power_enable(false); + return false; } - ESP_LOGE(TAG, "failed to create Wi-Fi AP task"); - return false; + portENTER_CRITICAL(&spinlock); + state.started = true; + portEXIT_CRITICAL(&spinlock); + return true; } void HalEsp32::setExtAntennaEnable(bool enable) @@ -207,5 +292,8 @@ bool HalEsp32::getExtAntennaEnable() void HalEsp32::startWifiAp() { - wifi_init(); + if (!wifi_init()) + { + mclog::tagWarn(TAG, "Wi-Fi AP init failed"); + } } From 11334fad1f644dcf372c5df5b578e1565270e5b1 Mon Sep 17 00:00:00 2001 From: "Sameer .I. Siddiqui" Date: Mon, 22 Sep 2025 01:25:54 +0530 Subject: [PATCH 2/2] fix(wifi): guard init in progress --- platforms/tab5/main/hal/components/hal_wifi.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/platforms/tab5/main/hal/components/hal_wifi.cpp b/platforms/tab5/main/hal/components/hal_wifi.cpp index 100348e..803ffd1 100644 --- a/platforms/tab5/main/hal/components/hal_wifi.cpp +++ b/platforms/tab5/main/hal/components/hal_wifi.cpp @@ -216,7 +216,11 @@ bool HalEsp32::wifi_init() portENTER_CRITICAL(&spinlock); bool already_started = state.started; bool previously_failed = state.failed; - state.attempted = true; + bool in_progress = state.attempted && !state.started && !state.failed; + if (!state.attempted) + { + state.attempted = true; + } portEXIT_CRITICAL(&spinlock); if (already_started) @@ -228,6 +232,11 @@ bool HalEsp32::wifi_init() ESP_LOGW(TAG, "Skipping Wi-Fi init after previous failure"); return false; } + if (in_progress) + { + ESP_LOGW(TAG, "Wi-Fi init already in progress"); + return false; + } mclog::tagInfo(TAG, "wifi init");