pico_cyw43_arch FreeRTOS+lwIP: route errno through newlib (LWIP_ERRNO_STDINCLUDE)#2974
Open
skycmoon wants to merge 1 commit into
Open
pico_cyw43_arch FreeRTOS+lwIP: route errno through newlib (LWIP_ERRNO_STDINCLUDE)#2974skycmoon wants to merge 1 commit into
skycmoon wants to merge 1 commit into
Conversation
The freertos+lwIP variant unconditionally sets LWIP_PROVIDE_ERRNO=1, which makes lwIP declare its own `extern int errno` global. Under FreeRTOS+newlib (the only libc shipped with the SDK's FreeRTOS port) newlib already provides a thread-local errno via <errno.h>, so any POSIX-style code that reads errno via <errno.h> diverges from the storage lwIP writes to. The standard mbedTLS BIO pattern (stock net_sockets.c) is exactly this — `recv()` returns -1, the shim reads errno and never sees the EWOULDBLOCK lwIP set, so it treats every non-blocking poll as a fatal error and tears the session down. LWIP_ERRNO_STDINCLUDE=1 keeps lwIP's errno-constants behaviour but routes through <errno.h>, so lwIP and the rest of the program share newlib's thread-local storage. Behaviour for users not exercising the BIO-shim pattern is unchanged.
peterharperuk
approved these changes
Jun 11, 2026
kilograham
reviewed
Jun 16, 2026
| target_compile_definitions(pico_cyw43_arch_lwip_sys_freertos_headers INTERFACE | ||
| CYW43_LWIP=1 | ||
| LWIP_PROVIDE_ERRNO=1 | ||
| # FreeRTOS+lwIP uses newlib, which provides a thread-local errno |
Contributor
There was a problem hiding this comment.
um, who says it uses newlib? surely it is dependent on the compiler/toolchain?
kilograham
requested changes
Jun 19, 2026
kilograham
left a comment
Contributor
There was a problem hiding this comment.
i'm not convinced by this yet - as i say, who says that newlib is used? and this is non-overridable now as implemented
Contributor
|
Yes. I think it was a mistake to add this to the library. It should have been left to be defined in lwipopts.h |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2973.
What
Swap
LWIP_PROVIDE_ERRNO=1forLWIP_ERRNO_STDINCLUDE=1on thepico_cyw43_arch_lwip_sys_freertosvariant. Single hunk insrc/rp2_common/pico_cyw43_arch/CMakeLists.txt.Why
LWIP_PROVIDE_ERRNO=1is correct for bare-metal builds (no libc ownserrno), but the FreeRTOS+lwIP variant always ships with newlib, which already provides a thread-localerrnovia<errno.h>. The unconditionalLWIP_PROVIDE_ERRNO=1makes lwIP declare its ownextern int errnoglobal, diverging from newlib's storage. Any code readingerrnovia<errno.h>— including the standard mbedTLSlibrary/net_sockets.cBIO — misses theEWOULDBLOCKlwIP wrote, treats every non-blockingrecv()poll as fatal, and tears the TLS session down right after handshake.LWIP_ERRNO_STDINCLUDE=1keeps lwIP'sE*constants available but routes them via<errno.h>, so lwIP and the rest of the program share newlib's thread-local storage. Issue #2973 has the full diagnosis and an observable symptom description (TLS handshake completes → application sends e.g. MQTTCONNECT→ server queuesCONNACK→ client immediately FINs without reading the response → loop forever at the application's backoff cadence).Scope
pico_cyw43_arch_lwip_sys_freertos_headersis touched.pico_cyw43_arch_lwip_threadsafe_background(bare-metal) does not currently setLWIP_PROVIDE_ERRNO=1, so no change needed there.Compatibility
Behaviour-preserving for users who don't touch
errnodirectly — lwIP'sE*constants still resolve, just through<errno.h>. Correcting for users on the stock mbedTLS BIO pattern (or any equivalent POSIX-style errno shim).Test
I verified the equivalent fix locally as a project-side override in
lwipopts.h: cancelling the SDK's-D LWIP_PROVIDE_ERRNO=1and settingLWIP_ERRNO_STDINCLUDE=1resolved a persistent MQTTCONNECT/CONNACK/closestorm on Pico 2W (FreeRTOS + lwIP + mbedTLS + coreMQTT). This PR moves that fix from a per-project workaround to the SDK default for the variant.