Skip to content

Commit

Permalink
Merge pull request #10027 from eightycc/issue-9837
Browse files Browse the repository at this point in the history
Resolve RP2 Network Performance Issue
  • Loading branch information
tannewt authored Feb 13, 2025
2 parents dabb0aa + f14e5ce commit ed1a44d
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@
[submodule "ports/raspberrypi/lib/lwip"]
path = ports/raspberrypi/lib/lwip
url = https://github.com/adafruit/lwip.git
branch = circuitpython8
branch = circuitpython9
[submodule "lib/mbedtls"]
path = lib/mbedtls
url = https://github.com/ARMmbed/mbedtls.git
Expand Down
2 changes: 1 addition & 1 deletion ports/raspberrypi/lib/lwip
Submodule lwip updated 151 files
13 changes: 13 additions & 0 deletions ports/raspberrypi/lwip_inc/lwip_mem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles
//
// SPDX-License-Identifier: MIT

#pragma once

#include <stddef.h>

void *lwip_heap_malloc(size_t size);
void lwip_heap_free(void *ptr);
void *lwip_heap_calloc(size_t num, size_t size);
58 changes: 54 additions & 4 deletions ports/raspberrypi/lwip_inc/lwipopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

#include "lwip_mem.h"

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
Expand All @@ -20,14 +22,62 @@
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
// MEM_USE_POOLS: mem_malloc uses pools of fixed size memory blocks. Default is 0.
#define MEM_USE_POOLS 0
// MEM_USE_POOLS_TRY_BIGGER_POOL: if one pool is empty, try the next bigger pool. Default is 0.
#define MEM_USE_POOLS_TRY_BIGGER_POOL 0
// MEMP_USE_CUSTOM_POOLS: Use custom pools defined in lwippools.h. Default is 0.
#define MEMP_USE_CUSTOM_POOLS 0
// MEMP_MEM_MALLOC: Use mem_malloc() for pool memory. Default is 0.
#define MEMP_MEM_MALLOC 1
#define MEM_CUSTOM_ALLOCATOR 1
#define MEM_CUSTOM_FREE lwip_heap_free
#define MEM_CUSTOM_MALLOC lwip_heap_malloc
#define MEM_CUSTOM_CALLOC lwip_heap_calloc

// MEM_SIZE: The LWIP heap size. Memory for mem_malloc and mem_calloc are allocated from
// this heap. If MEMP_MEM_MALLOC is set to 1, memory for memp_malloc is also allocated from
// this heap; if it is 0, memory is statically pre-allocated for each pool.
// Default is 1600.
#define MEM_SIZE 1600
// MEMP_NUM_PBUF: memp pbufs used when sending from static memory. Default is 16.
#define MEMP_NUM_PBUF 16
// MEMP_NUM_RAW_PCB: Number of raw connection PCBs. Default is 4.
#define MEMP_NUM_RAW_PCB 4
// MEMP_NUM_UDP_PCB: Number of UDP PCBs. Default is 4.
#define MEMP_NUM_UDP_PCB 4
// MEMP_NUM_TCP_PCB: Number of simultaneously active TCP connections. Default is 5.
#define MEMP_NUM_TCP_PCB 5
// MEMP_NUM_TCP_PCB_LISTEN: Number of listening TCP PCBs. Default is 8.
#define MEMP_NUM_TCP_PCB_LISTEN 8
// MEMP_NUM_TCP_SEG: Number of simultaneously queued TCP segments. Default is 16.
#define MEMP_NUM_TCP_SEG 16
// MEMP_NUM_ALTCP_PCB: Number of simultaneously active altcp connections. Default is 5.
#define MEMP_NUM_ALTCP_PCB 5
// MEMP_NUM_REASSDATA: Number of simultaneously IP packets queued for reassembly. Default is 5.
#define MEMP_NUM_REASSDATA 5
// MEMP_NUM_FRAG_PBUF: Number of simultaneously IP fragments. Default is 15.
#define MEMP_NUM_FRAG_PBUF 15
// MEMP_NUM_ARP_QUEUE: Number of simultaneously queued ARP packets. Default is 30.
#define MEMP_NUM_ARP_QUEUE 30
// MEMP_NUM_IGMP_GROUP: Number of simultaneously active IGMP groups. Default is 8.
#define MEMP_NUM_IGMP_GROUP 8
// MEMP_NUM_SYS_TIMEOUT: Number of simultaneously active timeouts.
// Use calculated default based on enabled modules.

// PBUF_POOL_SIZE: Number of pbufs in the pbuf pool. Default is 16.
#define PBUF_POOL_SIZE 16

// LWIP's default 250 ms periodic timer interval is too long, resulting in network
// performance issues. We reduce it to 25 ms giving a slow-timer of 50 ms and a
// fast-timer of 25 ms.
#define TCP_TMR_INTERVAL 25

#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1

#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
Expand Down
27 changes: 27 additions & 0 deletions ports/raspberrypi/lwip_src/lwip_mem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles
//
// SPDX-License-Identifier: MIT

#include <stdint.h>
#include <string.h>
#include "lib/tlsf/tlsf.h"
#include "lwip_mem.h"
#include "supervisor/port_heap.h"

void *lwip_heap_malloc(size_t size) {
return port_malloc(size, true);
}

void lwip_heap_free(void *ptr) {
port_free(ptr);
}

void *lwip_heap_calloc(size_t num, size_t size) {
void *ptr = lwip_heap_malloc(num * size);
if (ptr != NULL) {
memset(ptr, 0, num * size);
}
return ptr;
}
25 changes: 16 additions & 9 deletions ports/raspberrypi/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

#include "tusb.h"
#include <cmsis_compiler.h>
#include "lib/tlsf/tlsf.h"

critical_section_t background_queue_lock;

Expand Down Expand Up @@ -87,20 +88,18 @@ extern uint32_t _ld_itcm_destination;
extern uint32_t _ld_itcm_size;
extern uint32_t _ld_itcm_flash_copy;

#ifdef CIRCUITPY_PSRAM_CHIP_SELECT
static tlsf_t _heap = NULL;
static pool_t _ram_pool = NULL;
static pool_t _psram_pool = NULL;
static size_t _psram_size = 0;

#include "lib/tlsf/tlsf.h"
#ifdef CIRCUITPY_PSRAM_CHIP_SELECT

#include "src/rp2350/hardware_regs/include/hardware/regs/qmi.h"
#include "src/rp2350/hardware_regs/include/hardware/regs/xip.h"
#include "src/rp2350/hardware_structs/include/hardware/structs/qmi.h"
#include "src/rp2350/hardware_structs/include/hardware/structs/xip_ctrl.h"

static tlsf_t _heap = NULL;
static pool_t _ram_pool = NULL;
static pool_t _psram_pool = NULL;
static size_t _psram_size = 0;

static void __no_inline_not_in_flash_func(setup_psram)(void) {
gpio_set_function(CIRCUITPY_PSRAM_CHIP_SELECT->number, GPIO_FUNC_XIP_CS1);
_psram_size = 0;
Expand Down Expand Up @@ -240,8 +239,9 @@ static void __no_inline_not_in_flash_func(setup_psram)(void) {
return;
}
}
#endif

void port_heap_init(void) {
static void _port_heap_init(void) {
uint32_t *heap_bottom = port_heap_get_bottom();
uint32_t *heap_top = port_heap_get_top();
size_t size = (heap_top - heap_bottom) * sizeof(uint32_t);
Expand All @@ -252,6 +252,10 @@ void port_heap_init(void) {
}
}

void port_heap_init(void) {
// We call _port_heap_init from port_init to initialize the heap early.
}

void *port_malloc(size_t size, bool dma_capable) {
void *block = tlsf_malloc(_heap, size);
return block;
Expand Down Expand Up @@ -282,7 +286,6 @@ size_t port_heap_get_largest_free_size(void) {
// IDF does this. Not sure why.
return tlsf_fit_size(_heap, max_size);
}
#endif

safe_mode_t port_init(void) {
_binary_info();
Expand Down Expand Up @@ -348,6 +351,9 @@ safe_mode_t port_init(void) {
setup_psram();
#endif

// Initialize heap early to allow for early allocation.
_port_heap_init();

// Check brownout.

#if CIRCUITPY_CYW43
Expand All @@ -356,6 +362,7 @@ safe_mode_t port_init(void) {
// are intended to meet the power on timing requirements, but apparently
// are inadequate. We'll back off this long delay based on future testing.
mp_hal_delay_ms(1000);

// Change this as a placeholder as to how to init with country code.
// Default country code is CYW43_COUNTRY_WORLDWIDE)
if (cyw43_arch_init_with_country(PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE)) {
Expand Down

0 comments on commit ed1a44d

Please sign in to comment.