[rp2] Address review: correct the sizing numbers and pin the invariants

Segment pool entries are 20 bytes on this build, not the nominal 16 that
struct tcp_seg suggests; the comment now quotes the measured figure.

The MEM_SIZE justification did not close as written: two connections at
~6KB each is ~12KB, which fits inside the old 16KB heap. The missing
term is that mem.c is first-fit, so what has to be free is a contiguous
1.5KB block, and at 75% occupancy interleaved with ARP, DHCP/DNS and
mDNS allocations the largest run collapses long before the total does.
That is also why the failure looked intermittent. Spelled out in both
the Python comment and the header template.

Hoist the lwIP sizing values to module constants so the two numeric
invariants can be tested: the segment pool must stay above the per-PCB
send queue, and MEM_SIZE must stay under 64000 or lwIP widens
mem_size_t to u32_t. Both were previously enforced by prose alone, and
the first would silently rebuild the starvation this change removes.
The generated header is byte identical.
This commit is contained in:
J. Nick Koston
2026-08-10 22:33:58 -05:00
parent c7bf312b1b
commit ac259c1565
3 changed files with 83 additions and 39 deletions
+26
View File
@@ -93,3 +93,29 @@ def test_rp2040_submodule_imports_resolve_to_rp2_submodules() -> None:
assert rp2040_boards is rp2_boards
assert rp2040_generate is rp2_generate
def test_lwip_segment_pool_exceeds_per_pcb_queue() -> None:
"""The segment pool is global while the send queue is per-PCB.
lwIP's sanity check only requires ``MEMP_NUM_TCP_SEG >= TCP_SND_QUEUELEN``,
which is the floor for a *single* connection: at equality one busy PCB can
drain the pool for every other PCB. Dropping back to equality would rebuild
the starvation this sizing exists to prevent, and nothing in the build would
complain.
"""
from esphome.components import rp2
assert rp2.LWIP_MEMP_NUM_TCP_SEG >= rp2.LWIP_TCP_SND_QUEUELEN
assert rp2.LWIP_MEMP_NUM_TCP_SEG >= 2 * rp2.LWIP_TCP_SND_QUEUELEN
def test_lwip_mem_size_keeps_mem_size_t_narrow() -> None:
"""``MEM_SIZE`` above 64000 silently widens lwIP's ``mem_size_t`` to
``u32_t`` (``lwip/mem.h``), growing the header on every heap block. Raising
the heap past that bound is a real option, but it should be a deliberate
one rather than a side effect of tuning.
"""
from esphome.components import rp2
assert rp2.LWIP_MEM_SIZE < 64000