El Wi-Fi en Zephyr es una interfaz de red integrada en el stack del sistema operativo.
A diferencia de Arduino, donde el Wi-Fi suele ser una librería externa, en Zephyr se integra con el stack de red común. Eso significa que una vez tienes IP, tu código para abrir un socket TCP se parece mucho si usas Wi-Fi, Ethernet o Thread.
Si usas un ESP32, un nRF7002 o una placa con un módulo Wi-Fi soportado, Zephyr ofrece IPv4, IPv6, sockets, TLS, DHCP y herramientas de diagnóstico.
Configuración (prj.conf)
El stack de red es enorme. Para un ESP32 o similar, necesitamos activar bastantes cosas. Esta es una configuración básica para conectarse y obtener una dirección mediante DHCP:
# Habilitar Networking
CONFIG_NETWORKING=y
CONFIG_NET_L2_WIFI_MGMT=y
CONFIG_NET_IPV4=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
# Habilitar Wi-Fi en modo estación
CONFIG_WIFI=y
CONFIG_WIFI_USAGE_MODE_STA=y
# Gestión de red (Network Management API)
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048
# Logs para ver qué pasa
CONFIG_NET_LOG=y
CONFIG_WIFI_LOG_LEVEL_INF=yEl driver concreto depende de vuestra placa. CONFIG_WIFI_ESP32=y es un ejemplo para ESP32; en otras placas puede venir activado por la propia definición de placa o tener otro símbolo de configuración.
API de gestión Wi-Fi (wifi_mgmt)
Zephyr utiliza una API de eventos. No llamamos a connect() y esperamos bloqueados. Le decimos al sistema “Conéctate” y nos suscribimos a un evento que nos avise cuando tengamos IP.
Vamos a ver un ejemplo de cómo conectarse a una red WPA2.
#include <zephyr/kernel.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/net_event.h>
#include <errno.h>
#include <string.h>
/* Callback para eventos de red (IP obtenida, desconexión...) */
static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
uint64_t mgmt_event, struct net_if *iface)
{
if (mgmt_event == NET_EVENT_WIFI_CONNECT_RESULT) {
const struct wifi_status *status = cb->info;
if (status->status) {
printk("La conexión Wi-Fi falló (%d)\n", status->status);
} else {
printk("Asociado al punto de acceso; esperando DHCP...\n");
}
} else if (mgmt_event == NET_EVENT_IPV4_ADDR_ADD) {
printk("¡Conexión Exitosa! Tenemos dirección IP.\n");
/* Aquí podríamos liberar un semáforo para avisar al main */
}
}
/* Estructura para registrar el callback */
static struct net_mgmt_event_callback mgmt_cb;
int main(void)
{
struct net_if *iface = net_if_get_default();
struct wifi_connect_req_params params = {0};
printk("Iniciando Wi-Fi...\n");
/* 1. Nos suscribimos a eventos de red (cuando obtengamos IP) */
net_mgmt_init_event_callback(&mgmt_cb, net_mgmt_event_handler,
NET_EVENT_WIFI_CONNECT_RESULT |
NET_EVENT_IPV4_ADDR_ADD);
net_mgmt_add_event_callback(&mgmt_cb);
/* 2. Configuramos credenciales */
params.ssid = (const uint8_t *)"MiCasa_2.4G";
params.ssid_length = strlen("MiCasa_2.4G");
params.psk = (const uint8_t *)"ContrasenaSuperSegura";
params.psk_length = strlen("ContrasenaSuperSegura");
params.security = WIFI_SECURITY_TYPE_PSK;
params.channel = WIFI_CHANNEL_ANY;
/* 3. Solicitamos conexión */
if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, ¶ms, sizeof(params))) {
printk("Error al solicitar conexión Wi-Fi\n");
return -EIO;
}
printk("Conectando... Esperando IP...\n");
/* El main puede dormir, el evento saltará en 'net_mgmt_event_handler' */
while(1) k_sleep(K_FOREVER);
}Shell de red: Si activas CONFIG_NET_SHELL=y, tendrás comandos muy útiles en la consola como net iface (ver IP), net ping google.com o wifi scan.
Con una interfaz que ya tiene dirección IP podemos utilizar sockets, HTTP, MQTT u otros protocolos del stack común.