Description
Describe the bug
Using GPIO (button) interrupts on m5stack_atoms3_lite/esp32s3/procpu
freezes the board when Wi-Fi interface is being used. When the interrupts are configured and enabled before Wi-Fi connection is established, they work fine. After invoking net_mgmt(NET_REQUEST_WIFI_CONNECT, ...)
the board freezes if the button is being pressed.
This has been tested on 8f2f97ce320ae184e3b2f572436a3758580205fe
and the newest main
.
Regression
- This is a regression.
Steps to reproduce
To reproduce the behavior, you can use simple application based on the button
sample:
main.c
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);
static K_SEM_DEFINE(wifi_connected, 0, 1);
static struct net_mgmt_event_callback wifi_mgmt_cb;
#define WIFI_MGMT_EVENTS \
(NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \
NET_EVENT_WIFI_IFACE_STATUS)
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
struct net_if *iface)
{
switch (mgmt_event) {
case NET_EVENT_WIFI_CONNECT_RESULT:
LOG_INF("Wi-Fi connect result event received");
k_sem_give(&wifi_connected);
break;
case NET_EVENT_WIFI_DISCONNECT_RESULT:
LOG_INF("Wi-Fi disconnect result event received");
break;
case NET_EVENT_WIFI_IFACE_STATUS:
LOG_INF("Wi-Fi interface status event received");
break;
default:
break;
}
}
static void wifi_connect(void)
{
net_mgmt_init_event_callback(&wifi_mgmt_cb, wifi_mgmt_event_handler, WIFI_MGMT_EVENTS);
net_mgmt_add_event_callback(&wifi_mgmt_cb);
struct net_if *iface = net_if_get_first_wifi();
// Replace with your Wi-Fi SSID and password
static const char *wifi_ssid = "<SSID>";
static const char *wifi_key = "<KEY>";
__ASSERT(strlen(wifi_ssid) < WIFI_SSID_MAX_LEN, "SSID too long, check buffer size.");
__ASSERT(strlen(wifi_key) < WIFI_PSK_MAX_LEN, "WiFi key too long, check buffer size.");
struct wifi_connect_req_params cnx_params = {
.band = WIFI_FREQ_BAND_UNKNOWN,
.channel = WIFI_CHANNEL_ANY,
.ssid = wifi_ssid,
.ssid_length = strlen(wifi_ssid),
.psk = wifi_key,
.psk_length = strlen(wifi_key),
.security = WIFI_SECURITY_TYPE_PSK,
.mfp = WIFI_MFP_OPTIONAL,
};
if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params,
sizeof(struct wifi_connect_req_params))) {
LOG_ERR("Connection request failed");
k_sleep(K_FOREVER);
}
LOG_INF("Connection requested, SSID: %s, Key: %s", cnx_params.ssid, cnx_params.psk);
k_sem_take(&wifi_connected, K_FOREVER);
LOG_INF("Wi-Fi connected successfully");
}
#define SW0_NODE DT_ALIAS(sw0)
#if !DT_NODE_HAS_STATUS_OKAY(SW0_NODE)
#error "Unsupported board: sw0 devicetree alias is not defined"
#endif
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
static struct gpio_callback button_cb_data;
static void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
}
static void button_setup(void)
{
int ret;
if (!gpio_is_ready_dt(&button)) {
LOG_ERR("Error: button device %s is not ready", button.port->name);
return;
}
ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
if (ret != 0) {
LOG_ERR("Error %d: failed to configure %s pin %d", ret, button.port->name,
button.pin);
return;
}
ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
if (ret != 0) {
LOG_ERR("Error %d: failed to configure interrupt on %s pin %d", ret,
button.port->name, button.pin);
return;
}
gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb_data);
LOG_INF("Set up button at %s pin %d", button.port->name, button.pin);
LOG_INF("Press the button");
}
int main(void)
{
wifi_connect();
button_setup();
return 0;
}
NOTE: replace <SSID>
and <KEY>
in wifi_connect()
.
prj.conf
CONFIG_GPIO=y
CONFIG_LOG=y
CONFIG_NETWORKING=y
CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4=y
CONFIG_NET_DHCPV4_LOG_LEVEL_INF=y
CONFIG_NET_LOG=y
Build and flash
west build -p auto -S wifi-ipv4 -b m5stack_atoms3_lite/esp32s3/procpu
west flash && west espressif monitor -b 115200
Testing
To test it, you can do the following:
- run the sample with replaced
<SSID>
and<KEY>
, after connecting to the Wi-Fi, press the built-in button on the board - the application freezes - comment the
wifi_connect();
line inmain()
to run the sample without the Wi-Fi, after flashing press the button to see that the interrupts work fine - optionally, in the
main()
you can first initialize buttons, dok_sleep(K_SECONDS(10));
to delay the wifi_initialization and check that the interrupts work, then invokewifi_connect();
to see that after connecting, the board freezes when the button is pressed
Relevant log output
Impact
Major – Severely degrades functionality; workaround is difficult or unavailable.
Environment
- OS: Linux
- Zephyr: newest main
- toolchain:
zephyr-sdk-0.17.0
Additional Context
No response