🛠 C SDK : cyw43_arch, lwIP threadbackground vs poll, et verrous d'arch
Objetivos
Pasar a C para un control total: en el Pico SDK, el controlador CYW43 está integrado en el propio SDK (src/rp2_common/pico_cyw43_driver, pico_cyw43_arch) y lwIP se ha trasladado desde pico-extras (pico_lwip, pico_lwip_arch). La cadena de hardware es notable: cyw43_arch_init alimenta el CYW43439 a través de GP23, carga su firmware desde tu flash QSPI e inicia un bus SPI controlado por una máquina PIO a ~33 MHz. Este tutorial compara los dos modos de arquitectura — pico_cyw43_arch_lwip_threadbackground (lwIP en un hilo) frente a pico_cyw43_arch_poll (bucle explícito) — y sus reglas de bloqueo, fuente n.º 1 de errores de red en C.
Material
- 1 × Raspberry Pi Pico W + cable micro-USB de datos
- Pico SDK 2.x,
PICO_BOARD=pico_w, toolchain gcc-arm-none-eabi + CMake - Un servidor TCP de prueba en la LAN (p. ej.
nc -l -p 4242) - Consola serie a 115200 baudios
Código completo
// picow_tcp_client.c — squelette basé sur l'exemple officiel
// pico_w/wifi/tcp_client (BSD-3, © Raspberry Pi (Trading) Ltd.)
// CMake : pico_stdlib pico_cyw43_arch_lwip_threadbackground
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h" // Wi-Fi + glue lwIP, désormais dans le SDK
#include "lwip/tcp.h"
#define WIFI_SSID "myssid"
#define WIFI_PASS "mypass"
#define TEST_TCP_SERVER_IP "192.168.1.50"
#define TCP_PORT 4242
int main(void) {
stdio_init_all;
// Alimente le CYW43 via GP23, charge le firmware, démarre le SPI PIO 33 MHz
if (cyw43_arch_init) { printf("failed to initialise\n"); return 1; }
cyw43_arch_enable_sta_mode;
if (cyw43_arch_wifi_connect_timeout_ms(
WIFI_SSID, WIFI_PASS, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
printf("failed to connect.\n"); return 1;
}
printf("Connected.\n");
// Règle d'or (variante threadbackground) : tout appel lwIP depuis TON
// code est entouré du verrou d'arch ; depuis un callback lwIP, inutile :
// cyw43_arch_lwip_begin;
// err_t err = tcp_connect(pcb, &remote, TCP_PORT, cb);
// cyw43_arch_lwip_end;
// Avec pico_cyw43_arch_poll à la place : appeler cyw43_arch_poll
// régulièrement dans la boucle principale, sinon rien ne bouge.
// ... tcp_new_ip_type / tcp_connect / tcp_write ...
cyw43_arch_disable_sta_mode;
cyw43_arch_deinit;
return 0;
}
Verificación esperada
Connected. en la consola, y el servidor TCP de prueba recibe la conexión. Para decidir entre las dos variantes: con threadbackground, tu main puede bloquearse (sleep_ms) y lwIP sigue funcionando en su hilo; con _poll, si olvidas cyw43_arch_poll en un bucle de cálculo, los callbacks TCP se congelan — síntoma: la conexión se degrada en cuanto la CPU está ocupada.
Errores frecuentes
- Llamar a lwIP sin bloqueo en threadbackground: corrupción de estado, asserts, deadlocks —
cyw43_arch_lwip_begin/endes obligatorio fuera de los callbacks. - Elegir
_polly luego escribir un bucle sincyw43_arch_poll: la pila de red nunca se ejecuta; elegir_threadbackgroundal principio es el consejo de los ejemplos oficiales. printfde red sinstdio_init_allprimero: la consola serie está muda y buscas un error de Wi-Fi que no existe.- Confundir las variantes de arquitectura con
pico_cyw43_arch_none: esta solo aporta el chip (¡LED!), no la red. - Enlazar varias variantes de arquitectura juntas: símbolos duplicados en el enlace — solo una de las tres por objetivo.
- Olvidar que el firmware CYW43 se almacena en tu flash (2 MB): un binario inflado puede saturar el espacio — los ejemplos de red ya son bastante pesados.
Otros tutoriales para esta placa
- Faire clignoter la LED embarquée (elle est derrière la puce Wi-Fi !)
- Se connecter à un réseau Wi-Fi (station, WPA2/WPA3)
- Bouton et potentiomètre sans marcher sur le sans-fil (GPIO libres & ADC)
- Servir une page web depuis la Pico W (socket TCP + HTTP)
- Client HTTP : consommer une API depuis la Pico W
- Heure exacte via NTP : l'horloge temps réel des projets connectés
Ejemplos de código para esta placa
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython