From 34bfa0d68dfa40ffae012b9596f623f052fdec38 Mon Sep 17 00:00:00 2001 From: Tiago Medicci Serrano Date: Tue, 28 Apr 2026 17:24:55 -0300 Subject: [PATCH] arch/xtensa: Update common-source base for ESP32[|S2|S3] After recent changes on the event handler for the RISC-V-based Espressif SoCs, the same set of changes were ported back to xtensa devices. Signed-off-by: Tiago Medicci Serrano --- .../src/common/espressif/esp_wifi_api.c | 1 + .../common/espressif/esp_wifi_event_handler.c | 303 +++++++----------- .../src/common/espressif/esp_wifi_utils.h | 51 +-- arch/xtensa/src/esp32/Make.defs | 2 +- arch/xtensa/src/esp32/hal.mk | 4 + arch/xtensa/src/esp32s2/Make.defs | 2 +- arch/xtensa/src/esp32s2/hal.mk | 4 + arch/xtensa/src/esp32s3/Make.defs | 2 +- arch/xtensa/src/esp32s3/hal.mk | 4 + 9 files changed, 156 insertions(+), 217 deletions(-) diff --git a/arch/xtensa/src/common/espressif/esp_wifi_api.c b/arch/xtensa/src/common/espressif/esp_wifi_api.c index 4ddf7038561..8904a588789 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_api.c +++ b/arch/xtensa/src/common/espressif/esp_wifi_api.c @@ -115,6 +115,7 @@ int esp_wifi_api_adapter_init(void) esp_wifi_lock(true); esp_evt_work_init(); + esp_wifi_evt_work_init(); wifi_cfg.nvs_enable = 0; diff --git a/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c b/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c index 6148d36d9ff..1e75b8554d5 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c +++ b/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c @@ -27,9 +27,10 @@ #include #include -#include #include +#include +#include "esp_event.h" #include "esp_wifi.h" #include "esp_wifi_utils.h" @@ -69,23 +70,13 @@ struct wifi_notify struct sigwork_s work; /* Signal work private data */ }; -/* Wi-Fi event private data */ - -struct evt_adpt -{ - sq_entry_t entry; /* Sequence entry */ - wifi_event_t id; /* Event ID */ - uint8_t buf[0]; /* Event private data */ -}; - /**************************************************************************** * Private Data ****************************************************************************/ static struct wifi_notify g_wifi_notify[WIFI_EVENT_MAX]; -static struct work_s g_wifi_evt_work; -static sq_queue_t g_wifi_evt_queue; -static spinlock_t g_lock; +static struct work_s g_wifi_reconnect_work; +static bool g_wifi_handler_registered; /**************************************************************************** * Private Functions @@ -102,7 +93,7 @@ static spinlock_t g_lock; * asked to disconnect from the AP. * * Input Parameters: - * arg - Not used. + * arg - Unused work queue argument. * * Returned Value: * None. @@ -129,151 +120,154 @@ static void esp_reconnect_work_cb(void *arg) wlerr("Failed to reconnect to Wi-Fi on callback\n"); } } -#endif /* ESP_WLAN_HAS_STA */ +#endif /**************************************************************************** - * Name: esp_evt_work_cb + * Name: esp_wifi_event_handler * * Description: - * Process Wi-Fi events. + * Handler registered against WIFI_EVENT / ESP_EVENT_ANY_ID with the + * generic esp_event dispatcher (see esp_event.c). Translates Wi-Fi + * driver events into NuttX-visible actions (link-layer hooks and the + * optional sigevent notification subsystem). * * Input Parameters: - * arg - Not used. + * arg - Handler-specific argument registered with the event + * dispatcher (unused). + * event_base - Event base identifier; always WIFI_EVENT here (unused). + * event_id - Wi-Fi event ID as defined by the ESP-IDF wifi_event_t + * enumeration. + * event_data - Pointer to the event-specific payload, whose concrete + * type depends on event_id. * * Returned Value: * None. * ****************************************************************************/ -static void esp_evt_work_cb(void *arg) +static void esp_wifi_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) { int ret; - irqstate_t flags; - struct evt_adpt *evt_adpt; struct wifi_notify *notify; wifi_ps_type_t ps_type = DEFAULT_PS_MODE; - while (1) + UNUSED(arg); + UNUSED(event_base); + + net_lock(); + esp_wifi_lock(true); + + switch (event_id) { - flags = spin_lock_irqsave(&g_lock); - evt_adpt = (struct evt_adpt *)sq_remfirst(&g_wifi_evt_queue); - spin_unlock_irqrestore(&g_lock, flags); - if (evt_adpt == NULL) - { - break; - } - - /* Some of the following logic (eg. esp_wlan_sta_set_linkstatus) - * can take net_lock(). To maintain the consistent locking order, - * we take net_lock() here before taking esp_wifi_lock. Note that - * net_lock() is a recursive lock. - */ - - net_lock(); - esp_wifi_lock(true); - - switch (evt_adpt->id) - { #ifdef ESP_WLAN_DEVS - case WIFI_EVENT_SCAN_DONE: - esp_wifi_scan_event_parse(); - break; + case WIFI_EVENT_SCAN_DONE: + esp_wifi_scan_event_parse(); + break; #endif - case WIFI_EVENT_HOME_CHANNEL_CHANGE: - wlinfo("Wi-Fi home channel change\n"); - break; + case WIFI_EVENT_HOME_CHANNEL_CHANGE: + wlinfo("Wi-Fi home channel change\n"); + break; #ifdef ESP_WLAN_HAS_STA - case WIFI_EVENT_STA_START: - wlinfo("Wi-Fi sta start\n"); + case WIFI_EVENT_STA_START: + { + wlinfo("Wi-Fi sta start\n"); - ret = esp_wifi_set_ps(ps_type); - if (ret != 0) - { - wlerr("Failed to set power save type\n"); - break; - } - break; - - case WIFI_EVENT_STA_STOP: - wlinfo("Wi-Fi station stopped\n"); - break; - - case WIFI_EVENT_STA_CONNECTED: - wlinfo("Wi-Fi station connected\n"); - esp_wlan_sta_connect_success_hook(); - break; - - case WIFI_EVENT_STA_DISCONNECTED: + ret = esp_wifi_set_ps(ps_type); + if (ret != 0) { - wifi_event_sta_disconnected_t *event = - (wifi_event_sta_disconnected_t *)evt_adpt->buf; - wifi_err_reason_t reason = event->reason; - - wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); - esp_wlan_sta_disconnect_hook(); - if (reason == WIFI_REASON_ASSOC_LEAVE) - { - work_queue(LPWORK, &g_wifi_evt_work, esp_reconnect_work_cb, - NULL, 0); - } + wlerr("Failed to set power save type\n"); + break; } + } + break; - break; + case WIFI_EVENT_STA_STOP: + wlinfo("Wi-Fi station stopped\n"); + break; - case WIFI_EVENT_STA_AUTHMODE_CHANGE: - wlinfo("Wi-Fi station auth mode change\n"); - break; + case WIFI_EVENT_STA_CONNECTED: + { + wlinfo("Wi-Fi station connected\n"); + esp_wlan_sta_connect_success_hook(); + } + break; + + case WIFI_EVENT_STA_DISCONNECTED: + { + wifi_event_sta_disconnected_t *event = + (wifi_event_sta_disconnected_t *)event_data; + wifi_err_reason_t reason = event->reason; + + wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); + esp_wlan_sta_disconnect_hook(); + if (reason == WIFI_REASON_ASSOC_LEAVE) + { + work_queue(LPWORK, &g_wifi_reconnect_work, + esp_reconnect_work_cb, NULL, 0); + } + } + break; + + case WIFI_EVENT_STA_AUTHMODE_CHANGE: + wlinfo("Wi-Fi station auth mode change\n"); + break; #endif /* ESP_WLAN_HAS_STA */ #ifdef ESP_WLAN_HAS_SOFTAP - case WIFI_EVENT_AP_START: - wlinfo("INFO: Wi-Fi softap start\n"); - esp_wlan_softap_connect_success_hook(); - ret = esp_wifi_set_ps(ps_type); - if (ret != 0) - { - wlerr("Failed to set power save type\n"); - break; - } - break; - - case WIFI_EVENT_AP_STOP: - wlinfo("Wi-Fi softap stop\n"); - esp_wlan_softap_disconnect_hook(); - break; - - case WIFI_EVENT_AP_STACONNECTED: - wlinfo("Wi-Fi station joined AP\n"); - break; - - case WIFI_EVENT_AP_STADISCONNECTED: - wlinfo("Wi-Fi station left AP\n"); - break; -#endif /* ESP_WLAN_HAS_SOFTAP */ - default: - break; + case WIFI_EVENT_AP_START: + { + wlinfo("INFO: Wi-Fi softap start\n"); + esp_wlan_softap_connect_success_hook(); + ret = esp_wifi_set_ps(ps_type); + if (ret != 0) + { + wlerr("Failed to set power save type\n"); + break; + } } + break; - notify = &g_wifi_notify[evt_adpt->id]; + case WIFI_EVENT_AP_STOP: + { + wlinfo("Wi-Fi softap stop\n"); + esp_wlan_softap_disconnect_hook(); + } + break; + + case WIFI_EVENT_AP_STACONNECTED: + wlinfo("Wi-Fi station joined AP\n"); + break; + + case WIFI_EVENT_AP_STADISCONNECTED: + wlinfo("Wi-Fi station left AP\n"); + break; +#endif /* ESP_WLAN_HAS_SOFTAP */ + + default: + break; + } + + if (event_id >= 0 && event_id < WIFI_EVENT_MAX) + { + notify = &g_wifi_notify[event_id]; if (notify->assigned) { - notify->event.sigev_value.sival_ptr = evt_adpt->buf; + notify->event.sigev_value.sival_ptr = event_data; ret = nxsig_notification(notify->pid, ¬ify->event, SI_QUEUE, ¬ify->work); if (ret < 0) { wlwarn("nxsig_notification event ID=%d failed: %d\n", - evt_adpt->id, ret); + (int)event_id, ret); } } - - esp_wifi_lock(false); - net_unlock(); - - kmm_free(evt_adpt); } + + esp_wifi_lock(false); + net_unlock(); } /**************************************************************************** @@ -281,81 +275,30 @@ static void esp_evt_work_cb(void *arg) ****************************************************************************/ /**************************************************************************** - * Name: esp_event_post + * Name: esp_wifi_evt_work_init * * Description: - * Posts an event to the event loop system. The event is queued in a FIFO - * and processed asynchronously in the low-priority work queue. + * Register the Wi-Fi event handler against the generic esp_event loop. + * Kept under the original name so existing callers (esp_wifi_api.c) + * continue to compile unchanged. Idempotent: subsequent calls after the + * first successful registration are silently ignored. * * Input Parameters: - * event_base - Identifier for the event category (e.g. WIFI_EVENT) - * event_id - Event ID within the event base category - * event_data - Pointer to event data structure - * event_data_size - Size of event data structure - * ticks - Number of ticks to wait (currently unused) + * None. * * Returned Value: - * 0 on success - * -1 on failure with following error conditions: - * - Invalid event ID - * - Memory allocation failure - * - * Assumptions/Limitations: - * - Event data is copied into a new buffer, so the original can be freed - * - Events are processed in FIFO order in the low priority work queue - * - The function is thread-safe and can be called from interrupt context + * None. * ****************************************************************************/ -int esp_event_post(const char *event_base, - int32_t event_id, - void *event_data, - size_t event_data_size, - uint32_t ticks) +void esp_wifi_evt_work_init(void) { - size_t size; - int32_t id; - irqstate_t flags; - struct evt_adpt *evt_adpt; - - wlinfo("Event: base=%s id=%ld data=%p data_size=%u ticks=%lu\n", - event_base, event_id, event_data, event_data_size, ticks); - - size = event_data_size + sizeof(struct evt_adpt); - evt_adpt = kmm_malloc(size); - if (evt_adpt == NULL) + if (g_wifi_handler_registered) { - wlerr("ERROR: Failed to alloc %d memory\n", size); - return -1; + return; } - evt_adpt->id = event_id; - memcpy(evt_adpt->buf, event_data, event_data_size); - - flags = enter_critical_section(); - sq_addlast(&evt_adpt->entry, &g_wifi_evt_queue); - leave_critical_section(flags); - - work_queue(LPWORK, &g_wifi_evt_work, esp_evt_work_cb, NULL, 0); - - return 0; -} - -/**************************************************************************** - * Name: esp_evt_work_init - * - * Description: - * Initialize the event work queue - * - * Input Parameters: - * None. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void esp_evt_work_init(void) -{ - sq_init(&g_wifi_evt_queue); + esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, + esp_wifi_event_handler, NULL); + g_wifi_handler_registered = true; } diff --git a/arch/xtensa/src/common/espressif/esp_wifi_utils.h b/arch/xtensa/src/common/espressif/esp_wifi_utils.h index 0871ad1b02e..70b5080a938 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_utils.h +++ b/arch/xtensa/src/common/espressif/esp_wifi_utils.h @@ -99,7 +99,7 @@ int esp_freq_to_channel(uint16_t freq); * Name: esp_evt_work_init * * Description: - * Initialize the event work queue + * Initialize the generic esp_event backend queue. * * Input Parameters: * None @@ -111,6 +111,22 @@ int esp_freq_to_channel(uint16_t freq); void esp_evt_work_init(void); +/**************************************************************************** + * Name: esp_wifi_evt_work_init + * + * Description: + * Initialize the event work queue + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_wifi_evt_work_init(void); + /**************************************************************************** * Name: esp_wifi_start_scan * @@ -212,39 +228,6 @@ wifi_mode_t esp_wifi_mode_translate(uint32_t wireless_mode); int esp_wifi_lock(bool lock); -/**************************************************************************** - * Name: esp_event_post - * - * Description: - * Posts an event to the event loop system. The event is queued in a FIFO - * and processed asynchronously in the low-priority work queue. - * - * Input Parameters: - * event_base - Identifier for the event category (e.g. WIFI_EVENT) - * event_id - Event ID within the event base category - * event_data - Pointer to event data structure - * event_data_size - Size of event data structure - * ticks - Number of ticks to wait (currently unused) - * - * Returned Value: - * 0 on success - * -1 on failure with following error conditions: - * - Invalid event ID - * - Memory allocation failure - * - * Assumptions/Limitations: - * - Event data is copied into a new buffer, so the original can be freed - * - Events are processed in FIFO order in the low priority work queue - * - The function is thread-safe and can be called from interrupt context - * - ****************************************************************************/ - -int esp_event_post(const char *event_base, - int32_t event_id, - void *event_data, - size_t event_data_size, - uint32_t ticks); - #ifdef __cplusplus } #endif diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index e072a06322b..71b0e8c4203 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -194,7 +194,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 + ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/xtensa/src/esp32/hal.mk b/arch/xtensa/src/esp32/hal.mk index 71d3e575643..c029da65e2e 100644 --- a/arch/xtensa/src/esp32/hal.mk +++ b/arch/xtensa/src/esp32/hal.mk @@ -320,6 +320,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c +ifneq ($(CONFIG_ESPRESSIF_WIFI),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + # Security components (for WiFi/crypto support) # Note: ESP32 doesn't support HMAC, so esp_security sources are excluded diff --git a/arch/xtensa/src/esp32s2/Make.defs b/arch/xtensa/src/esp32s2/Make.defs index cf75d566028..5a252a88ba6 100644 --- a/arch/xtensa/src/esp32s2/Make.defs +++ b/arch/xtensa/src/esp32s2/Make.defs @@ -127,7 +127,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 + ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/xtensa/src/esp32s2/hal.mk b/arch/xtensa/src/esp32s2/hal.mk index 0d99c6589ee..341a03a172b 100644 --- a/arch/xtensa/src/esp32s2/hal.mk +++ b/arch/xtensa/src/esp32s2/hal.mk @@ -331,6 +331,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c +ifneq ($(CONFIG_ESPRESSIF_WIFI),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + # Interrupt allocator # NOTE: ESP-IDF's xtensa_intr_asm.S cannot be used because it conflicts with # NuttX's Xtensa core macro definitions. Instead, esp_xtensa_intr.c provides diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index 3e0355ceaef..70648621eb7 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -192,7 +192,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 + ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/xtensa/src/esp32s3/hal.mk b/arch/xtensa/src/esp32s3/hal.mk index 3f9948bcb0f..5d55af58d81 100644 --- a/arch/xtensa/src/esp32s3/hal.mk +++ b/arch/xtensa/src/esp32s3/hal.mk @@ -360,6 +360,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c +ifneq ($(CONFIG_ESPRESSIF_WIFI),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + ifeq ($(CONFIG_SMP),y) CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)esp_system$(DELIM)esp_ipc.c endif