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 <tiago.medicci@espressif.com>
This commit is contained in:
Tiago Medicci Serrano
2026-04-28 17:24:55 -03:00
committed by Xiang Xiao
parent 5c4c60f9d2
commit 34bfa0d68d
9 changed files with 156 additions and 217 deletions
@@ -115,6 +115,7 @@ int esp_wifi_api_adapter_init(void)
esp_wifi_lock(true); esp_wifi_lock(true);
esp_evt_work_init(); esp_evt_work_init();
esp_wifi_evt_work_init();
wifi_cfg.nvs_enable = 0; wifi_cfg.nvs_enable = 0;
@@ -27,9 +27,10 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/debug.h> #include <nuttx/debug.h>
#include <nuttx/spinlock.h>
#include <nuttx/signal.h> #include <nuttx/signal.h>
#include <nuttx/wqueue.h>
#include "esp_event.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_wifi_utils.h" #include "esp_wifi_utils.h"
@@ -69,23 +70,13 @@ struct wifi_notify
struct sigwork_s work; /* Signal work private data */ 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 * Private Data
****************************************************************************/ ****************************************************************************/
static struct wifi_notify g_wifi_notify[WIFI_EVENT_MAX]; static struct wifi_notify g_wifi_notify[WIFI_EVENT_MAX];
static struct work_s g_wifi_evt_work; static struct work_s g_wifi_reconnect_work;
static sq_queue_t g_wifi_evt_queue; static bool g_wifi_handler_registered;
static spinlock_t g_lock;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
@@ -102,7 +93,7 @@ static spinlock_t g_lock;
* asked to disconnect from the AP. * asked to disconnect from the AP.
* *
* Input Parameters: * Input Parameters:
* arg - Not used. * arg - Unused work queue argument.
* *
* Returned Value: * Returned Value:
* None. * None.
@@ -129,151 +120,154 @@ static void esp_reconnect_work_cb(void *arg)
wlerr("Failed to reconnect to Wi-Fi on callback\n"); 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: * 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: * 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: * Returned Value:
* None. * 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; int ret;
irqstate_t flags;
struct evt_adpt *evt_adpt;
struct wifi_notify *notify; struct wifi_notify *notify;
wifi_ps_type_t ps_type = DEFAULT_PS_MODE; 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 #ifdef ESP_WLAN_DEVS
case WIFI_EVENT_SCAN_DONE: case WIFI_EVENT_SCAN_DONE:
esp_wifi_scan_event_parse(); esp_wifi_scan_event_parse();
break; break;
#endif #endif
case WIFI_EVENT_HOME_CHANNEL_CHANGE: case WIFI_EVENT_HOME_CHANNEL_CHANGE:
wlinfo("Wi-Fi home channel change\n"); wlinfo("Wi-Fi home channel change\n");
break; break;
#ifdef ESP_WLAN_HAS_STA #ifdef ESP_WLAN_HAS_STA
case WIFI_EVENT_STA_START: case WIFI_EVENT_STA_START:
wlinfo("Wi-Fi sta start\n"); {
wlinfo("Wi-Fi sta start\n");
ret = esp_wifi_set_ps(ps_type); ret = esp_wifi_set_ps(ps_type);
if (ret != 0) 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:
{ {
wifi_event_sta_disconnected_t *event = wlerr("Failed to set power save type\n");
(wifi_event_sta_disconnected_t *)evt_adpt->buf; break;
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);
}
} }
}
break;
break; case WIFI_EVENT_STA_STOP:
wlinfo("Wi-Fi station stopped\n");
break;
case WIFI_EVENT_STA_AUTHMODE_CHANGE: case WIFI_EVENT_STA_CONNECTED:
wlinfo("Wi-Fi station auth mode change\n"); {
break; 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 */ #endif /* ESP_WLAN_HAS_STA */
#ifdef ESP_WLAN_HAS_SOFTAP #ifdef ESP_WLAN_HAS_SOFTAP
case WIFI_EVENT_AP_START: case WIFI_EVENT_AP_START:
wlinfo("INFO: Wi-Fi softap start\n"); {
esp_wlan_softap_connect_success_hook(); wlinfo("INFO: Wi-Fi softap start\n");
ret = esp_wifi_set_ps(ps_type); esp_wlan_softap_connect_success_hook();
if (ret != 0) ret = esp_wifi_set_ps(ps_type);
{ if (ret != 0)
wlerr("Failed to set power save type\n"); {
break; 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;
} }
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) 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, &notify->event, ret = nxsig_notification(notify->pid, &notify->event,
SI_QUEUE, &notify->work); SI_QUEUE, &notify->work);
if (ret < 0) if (ret < 0)
{ {
wlwarn("nxsig_notification event ID=%d failed: %d\n", 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: * Description:
* Posts an event to the event loop system. The event is queued in a FIFO * Register the Wi-Fi event handler against the generic esp_event loop.
* and processed asynchronously in the low-priority work queue. * 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: * Input Parameters:
* event_base - Identifier for the event category (e.g. WIFI_EVENT) * None.
* 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: * Returned Value:
* 0 on success * None.
* -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, void esp_wifi_evt_work_init(void)
int32_t event_id,
void *event_data,
size_t event_data_size,
uint32_t ticks)
{ {
size_t size; if (g_wifi_handler_registered)
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)
{ {
wlerr("ERROR: Failed to alloc %d memory\n", size); return;
return -1;
} }
evt_adpt->id = event_id; esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
memcpy(evt_adpt->buf, event_data, event_data_size); esp_wifi_event_handler, NULL);
g_wifi_handler_registered = true;
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);
} }
@@ -99,7 +99,7 @@ int esp_freq_to_channel(uint16_t freq);
* Name: esp_evt_work_init * Name: esp_evt_work_init
* *
* Description: * Description:
* Initialize the event work queue * Initialize the generic esp_event backend queue.
* *
* Input Parameters: * Input Parameters:
* None * None
@@ -111,6 +111,22 @@ int esp_freq_to_channel(uint16_t freq);
void esp_evt_work_init(void); 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 * 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); 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 #ifdef __cplusplus
} }
#endif #endif
+1 -1
View File
@@ -194,7 +194,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed
endif endif
ifndef ESP_HAL_3RDPARTY_URL ifndef ESP_HAL_3RDPARTY_URL
+4
View File
@@ -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)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 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) # Security components (for WiFi/crypto support)
# Note: ESP32 doesn't support HMAC, so esp_security sources are excluded # Note: ESP32 doesn't support HMAC, so esp_security sources are excluded
+1 -1
View File
@@ -127,7 +127,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed
endif endif
ifndef ESP_HAL_3RDPARTY_URL ifndef ESP_HAL_3RDPARTY_URL
+4
View File
@@ -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)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 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 # Interrupt allocator
# NOTE: ESP-IDF's xtensa_intr_asm.S cannot be used because it conflicts with # 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 # NuttX's Xtensa core macro definitions. Instead, esp_xtensa_intr.c provides
+1 -1
View File
@@ -192,7 +192,7 @@ endif
ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
ifndef ESP_HAL_3RDPARTY_VERSION ifndef ESP_HAL_3RDPARTY_VERSION
ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647 ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed
endif endif
ifndef ESP_HAL_3RDPARTY_URL ifndef ESP_HAL_3RDPARTY_URL
+4
View File
@@ -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)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 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) 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 CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)esp_system$(DELIM)esp_ipc.c
endif endif