Skip to content

Commit ed1a44d

Browse files
authoredFeb 13, 2025··
Merge pull request #10027 from eightycc/issue-9837
Resolve RP2 Network Performance Issue
2 parents dabb0aa + f14e5ce commit ed1a44d

File tree

6 files changed

+112
-15
lines changed

6 files changed

+112
-15
lines changed
 

‎.gitmodules

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@
312312
[submodule "ports/raspberrypi/lib/lwip"]
313313
path = ports/raspberrypi/lib/lwip
314314
url = https://github.com/adafruit/lwip.git
315-
branch = circuitpython8
315+
branch = circuitpython9
316316
[submodule "lib/mbedtls"]
317317
path = lib/mbedtls
318318
url = https://github.com/ARMmbed/mbedtls.git

‎ports/raspberrypi/lib/lwip

Submodule lwip updated 151 files

‎ports/raspberrypi/lwip_inc/lwip_mem.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#pragma once
8+
9+
#include <stddef.h>
10+
11+
void *lwip_heap_malloc(size_t size);
12+
void lwip_heap_free(void *ptr);
13+
void *lwip_heap_calloc(size_t num, size_t size);

‎ports/raspberrypi/lwip_inc/lwipopts.h

+54-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// Common settings used in most of the pico_w examples
66
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
77

8+
#include "lwip_mem.h"
9+
810
// allow override in some examples
911
#ifndef NO_SYS
1012
#define NO_SYS 1
@@ -20,14 +22,62 @@
2022
#define MEM_LIBC_MALLOC 0
2123
#endif
2224
#define MEM_ALIGNMENT 4
23-
#define MEM_SIZE 4000
24-
#define MEMP_NUM_TCP_SEG 32
25-
#define MEMP_NUM_ARP_QUEUE 10
26-
#define PBUF_POOL_SIZE 24
25+
// MEM_USE_POOLS: mem_malloc uses pools of fixed size memory blocks. Default is 0.
26+
#define MEM_USE_POOLS 0
27+
// MEM_USE_POOLS_TRY_BIGGER_POOL: if one pool is empty, try the next bigger pool. Default is 0.
28+
#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
29+
// MEMP_USE_CUSTOM_POOLS: Use custom pools defined in lwippools.h. Default is 0.
30+
#define MEMP_USE_CUSTOM_POOLS 0
31+
// MEMP_MEM_MALLOC: Use mem_malloc() for pool memory. Default is 0.
32+
#define MEMP_MEM_MALLOC 1
33+
#define MEM_CUSTOM_ALLOCATOR 1
34+
#define MEM_CUSTOM_FREE lwip_heap_free
35+
#define MEM_CUSTOM_MALLOC lwip_heap_malloc
36+
#define MEM_CUSTOM_CALLOC lwip_heap_calloc
37+
38+
// MEM_SIZE: The LWIP heap size. Memory for mem_malloc and mem_calloc are allocated from
39+
// this heap. If MEMP_MEM_MALLOC is set to 1, memory for memp_malloc is also allocated from
40+
// this heap; if it is 0, memory is statically pre-allocated for each pool.
41+
// Default is 1600.
42+
#define MEM_SIZE 1600
43+
// MEMP_NUM_PBUF: memp pbufs used when sending from static memory. Default is 16.
44+
#define MEMP_NUM_PBUF 16
45+
// MEMP_NUM_RAW_PCB: Number of raw connection PCBs. Default is 4.
46+
#define MEMP_NUM_RAW_PCB 4
47+
// MEMP_NUM_UDP_PCB: Number of UDP PCBs. Default is 4.
48+
#define MEMP_NUM_UDP_PCB 4
49+
// MEMP_NUM_TCP_PCB: Number of simultaneously active TCP connections. Default is 5.
50+
#define MEMP_NUM_TCP_PCB 5
51+
// MEMP_NUM_TCP_PCB_LISTEN: Number of listening TCP PCBs. Default is 8.
52+
#define MEMP_NUM_TCP_PCB_LISTEN 8
53+
// MEMP_NUM_TCP_SEG: Number of simultaneously queued TCP segments. Default is 16.
54+
#define MEMP_NUM_TCP_SEG 16
55+
// MEMP_NUM_ALTCP_PCB: Number of simultaneously active altcp connections. Default is 5.
56+
#define MEMP_NUM_ALTCP_PCB 5
57+
// MEMP_NUM_REASSDATA: Number of simultaneously IP packets queued for reassembly. Default is 5.
58+
#define MEMP_NUM_REASSDATA 5
59+
// MEMP_NUM_FRAG_PBUF: Number of simultaneously IP fragments. Default is 15.
60+
#define MEMP_NUM_FRAG_PBUF 15
61+
// MEMP_NUM_ARP_QUEUE: Number of simultaneously queued ARP packets. Default is 30.
62+
#define MEMP_NUM_ARP_QUEUE 30
63+
// MEMP_NUM_IGMP_GROUP: Number of simultaneously active IGMP groups. Default is 8.
64+
#define MEMP_NUM_IGMP_GROUP 8
65+
// MEMP_NUM_SYS_TIMEOUT: Number of simultaneously active timeouts.
66+
// Use calculated default based on enabled modules.
67+
68+
// PBUF_POOL_SIZE: Number of pbufs in the pbuf pool. Default is 16.
69+
#define PBUF_POOL_SIZE 16
70+
71+
// LWIP's default 250 ms periodic timer interval is too long, resulting in network
72+
// performance issues. We reduce it to 25 ms giving a slow-timer of 50 ms and a
73+
// fast-timer of 25 ms.
74+
#define TCP_TMR_INTERVAL 25
75+
2776
#define LWIP_ARP 1
2877
#define LWIP_ETHERNET 1
2978
#define LWIP_ICMP 1
3079
#define LWIP_RAW 1
80+
3181
#define TCP_WND (8 * TCP_MSS)
3282
#define TCP_MSS 1460
3383
#define TCP_SND_BUF (8 * TCP_MSS)

‎ports/raspberrypi/lwip_src/lwip_mem.c

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// This file is part of the CircuitPython project: https://circuitpython.org
2+
//
3+
// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles
4+
//
5+
// SPDX-License-Identifier: MIT
6+
7+
#include <stdint.h>
8+
#include <string.h>
9+
#include "lib/tlsf/tlsf.h"
10+
#include "lwip_mem.h"
11+
#include "supervisor/port_heap.h"
12+
13+
void *lwip_heap_malloc(size_t size) {
14+
return port_malloc(size, true);
15+
}
16+
17+
void lwip_heap_free(void *ptr) {
18+
port_free(ptr);
19+
}
20+
21+
void *lwip_heap_calloc(size_t num, size_t size) {
22+
void *ptr = lwip_heap_malloc(num * size);
23+
if (ptr != NULL) {
24+
memset(ptr, 0, num * size);
25+
}
26+
return ptr;
27+
}

‎ports/raspberrypi/supervisor/port.c

+16-9
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060

6161
#include "tusb.h"
6262
#include <cmsis_compiler.h>
63+
#include "lib/tlsf/tlsf.h"
6364

6465
critical_section_t background_queue_lock;
6566

@@ -87,20 +88,18 @@ extern uint32_t _ld_itcm_destination;
8788
extern uint32_t _ld_itcm_size;
8889
extern uint32_t _ld_itcm_flash_copy;
8990

90-
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
91+
static tlsf_t _heap = NULL;
92+
static pool_t _ram_pool = NULL;
93+
static pool_t _psram_pool = NULL;
94+
static size_t _psram_size = 0;
9195

92-
#include "lib/tlsf/tlsf.h"
96+
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
9397

9498
#include "src/rp2350/hardware_regs/include/hardware/regs/qmi.h"
9599
#include "src/rp2350/hardware_regs/include/hardware/regs/xip.h"
96100
#include "src/rp2350/hardware_structs/include/hardware/structs/qmi.h"
97101
#include "src/rp2350/hardware_structs/include/hardware/structs/xip_ctrl.h"
98102

99-
static tlsf_t _heap = NULL;
100-
static pool_t _ram_pool = NULL;
101-
static pool_t _psram_pool = NULL;
102-
static size_t _psram_size = 0;
103-
104103
static void __no_inline_not_in_flash_func(setup_psram)(void) {
105104
gpio_set_function(CIRCUITPY_PSRAM_CHIP_SELECT->number, GPIO_FUNC_XIP_CS1);
106105
_psram_size = 0;
@@ -240,8 +239,9 @@ static void __no_inline_not_in_flash_func(setup_psram)(void) {
240239
return;
241240
}
242241
}
242+
#endif
243243

244-
void port_heap_init(void) {
244+
static void _port_heap_init(void) {
245245
uint32_t *heap_bottom = port_heap_get_bottom();
246246
uint32_t *heap_top = port_heap_get_top();
247247
size_t size = (heap_top - heap_bottom) * sizeof(uint32_t);
@@ -252,6 +252,10 @@ void port_heap_init(void) {
252252
}
253253
}
254254

255+
void port_heap_init(void) {
256+
// We call _port_heap_init from port_init to initialize the heap early.
257+
}
258+
255259
void *port_malloc(size_t size, bool dma_capable) {
256260
void *block = tlsf_malloc(_heap, size);
257261
return block;
@@ -282,7 +286,6 @@ size_t port_heap_get_largest_free_size(void) {
282286
// IDF does this. Not sure why.
283287
return tlsf_fit_size(_heap, max_size);
284288
}
285-
#endif
286289

287290
safe_mode_t port_init(void) {
288291
_binary_info();
@@ -348,6 +351,9 @@ safe_mode_t port_init(void) {
348351
setup_psram();
349352
#endif
350353

354+
// Initialize heap early to allow for early allocation.
355+
_port_heap_init();
356+
351357
// Check brownout.
352358

353359
#if CIRCUITPY_CYW43
@@ -356,6 +362,7 @@ safe_mode_t port_init(void) {
356362
// are intended to meet the power on timing requirements, but apparently
357363
// are inadequate. We'll back off this long delay based on future testing.
358364
mp_hal_delay_ms(1000);
365+
359366
// Change this as a placeholder as to how to init with country code.
360367
// Default country code is CYW43_COUNTRY_WORLDWIDE)
361368
if (cyw43_arch_init_with_country(PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE)) {

0 commit comments

Comments
 (0)
Please sign in to comment.