lwip_freertos_init() never restores lwip_context after lwip_freertos_deinit(), causing LOCK_TCPIP_CORE() to deadlock on re-init (e.g. cyw43 Wi-Fi power-cycling) #3175
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#3175
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Title
lwip_freertos_init()never restoreslwip_contextafterlwip_freertos_deinit(), causingLOCK_TCPIP_CORE()to deadlock on re-init (e.g. cyw43 Wi-Fi power-cycling)Environment
98a542c1a6)configSUPPORT_STATIC_ALLOCATION= 0,configSUPPORT_DYNAMIC_ALLOCATION= 1cyw43_arch_freertos(PICO_CYW43_ARCH_FREERTOS)Summary
An application that calls
cyw43_arch_init()/cyw43_arch_deinit()repeatedly (e.g. to power down Wi-Fi between transmissions to save power) can successfully connect the first time, but every subsequentcyw43_arch_init()→ Wi-Fi join fails/hangs until timeout. The failure is caused by a bug insrc/rp2_common/pico_lwip/lwip_freertos.c.Root cause
done_lwip_initis a function-static bool that persists for the entire lifetime of the program — it is set totruethe first timelwip_freertos_init()is ever called, and is never reset bylwip_freertos_deinit().lwip_freertos_deinit()setslwip_context = NULL.cyw43_arch_init(),done_lwip_initisfalse, solwip_contextis correctly set andtcpip_init()runs.cyw43_arch_init()(after any earliercyw43_arch_deinit()),done_lwip_initis alreadytrue, so theelsebranch runs — which givestcpip_task_blockerbut never restoreslwip_context.This port's
LOCK_TCPIP_CORE()implementation is:Because
lwip_contextis never set back to non-NULL after the secondlwip_freertos_init(), any caller waiting in this loop consumes the one semaphore "give," re-checkslwip_context(still NULL), and blocks onxSemaphoreTakeagain — permanently, since nothing gives the semaphore again. Any lwIP operation that needs the tcpip core lock during the second Wi-Fi session (netif setup, DHCP, etc., invoked fromcyw43_wifi_join/cyw43_arch_wifi_connect_timeout_ms) hangs until the caller's own timeout expires, which surfaces to the application as a failed/timed-out Wi-Fi join.Reproduction
Suggested fix
Restore
lwip_contextin theelsebranch oflwip_freertos_init():Files involved
src/rp2_common/pico_lwip/lwip_freertos.c(lwip_freertos_init,lwip_context,pico_lwip_custom_lock_tcpip_core)Note
This is separate from, but related in spirit to, the static-allocation task-TCB race in
async_context_freertos_deinit()that can also crash FreeRTOS apps doing Wi-Fi power-cycling (see report for that issue) — both surfaced while implementing power-saving Wi-Fi on/off cycling withcyw43_arch_init()/cyw43_arch_deinit().