Skip to content

Commit

Permalink
rp2: Allocate GC heap from unused RAM.
Browse files Browse the repository at this point in the history
Borrowing an idea from the mimxrt port (also stm32 port): in the loader
input file memmap_mp.ld calculate __GcHeapStart and __GcHeapEnd as the
unused RAM.  Then in main.c use these addresses as arguments to gc_init().

The benefits of this change are:

1) When libraries are added or removed in the future changing BSS usage,
   main.c's sizing of the GC heap does not need to be changed.

2) Currently these changes make the GC area about 30 KBytes larger, eg on
   PICO_W the GC heap increases from 166016 to 192448 bytes.  Without that
   change this RAM would never get used.

3) If someone wants to disable one or more SRAM blocks on the RP2040 to
   reduce power consumption it will be easy: just change the MEMORY section
   in memmap_mp.ld.  For instance to not use SRAM2 and SRAM3 change it to:

        MEMORY
        {
            FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
            RAM(rwx) : ORIGIN =  0x21000000, LENGTH = 128k
            SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
            SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
        }

   Then to turn off clocks for SRAM2 and SRAM3 from MicroPython, set the
   appropriate bits in WAKE_EN0 and SLEEP_EN0.

Tested by running the firmware.uf2 file on PICO_W and displaying
micropython.mem_info().  Confirmed GC total size approximately matched the
size calculated by the loader.

Signed-off-by: cpottle9 <[email protected]>
  • Loading branch information
cpottle9 authored and dpgeorge committed Mar 9, 2023
1 parent f80d040 commit c80e7c1
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 10 deletions.
12 changes: 2 additions & 10 deletions ports/rp2/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,8 @@
#include "lib/cyw43-driver/src/cyw43.h"
#endif

#ifndef MICROPY_GC_HEAP_SIZE
#if MICROPY_PY_LWIP
#define MICROPY_GC_HEAP_SIZE 166 * 1024
#else
#define MICROPY_GC_HEAP_SIZE 192 * 1024
#endif
#endif

extern uint8_t __StackTop, __StackBottom;
__attribute__((section(".uninitialized_bss"))) static char gc_heap[MICROPY_GC_HEAP_SIZE];
extern uint8_t __GcHeapStart, __GcHeapEnd;

// Embed version info in the binary in machine readable form
bi_decl(bi_program_version_string(MICROPY_GIT_TAG));
Expand Down Expand Up @@ -118,7 +110,7 @@ int main(int argc, char **argv) {
// Initialise stack extents and GC heap.
mp_stack_set_top(&__StackTop);
mp_stack_set_limit(&__StackTop - &__StackBottom - 256);
gc_init(&gc_heap[0], &gc_heap[MP_ARRAY_SIZE(gc_heap)]);
gc_init(&__GcHeapStart, &__GcHeapEnd);

#if MICROPY_PY_LWIP
// lwIP doesn't allow to reinitialise itself by subsequent calls to this function
Expand Down
7 changes: 7 additions & 0 deletions ports/rp2/memmap_mp.ld
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,18 @@ SECTIONS
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
/* Define start and end of GC heap */
__GcHeapStart = __bss_end__;
__GcHeapEnd = __StackLimit;
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")

/* Check GC heap is at least 128 KB */
/* On a RP2040 using all SRAM this should always be the case. */
ASSERT((__GcHeapEnd - __GcHeapStart) > 128*1024, "GcHeap is too small")

ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
/* todo assert on extra code */
}
Expand Down

0 comments on commit c80e7c1

Please sign in to comment.