Skip to content

Commit 2a15f72

Browse files
committed
bricks/media/pb_type_image: Use umm_malloc for image data.
Add support for a new memory allocator (umm_malloc) that is better for allocating large blocks of memory. Since MicroPython's garbage collector has to scan every single byte of memory it manages, to check for pointers, it is not efficient for large blocks of memory that are not expected to contain pointers. This is especially true for image data. So to avoid slow garbage collection/allocation times and filling up the MicroPython heap, we can use a separate allocator with a separate heap for image data.
1 parent 4484552 commit 2a15f72

File tree

11 files changed

+102
-14
lines changed

11 files changed

+102
-14
lines changed

.github/build-each-commit.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
pybricks.git.submodule(
7878
"update", "--init", "--checkout", "lib/STM32_USB_Device_Library"
7979
)
80+
if args.hub == "ev3":
81+
pybricks.git.submodule("update", "--init", "--checkout", "lib/umm_malloc")
8082

8183
# build the firmware
8284
subprocess.check_call(

.github/build-missing-commits.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
pybricks.git.submodule(
101101
"update", "--init", "--checkout", "lib/STM32_USB_Device_Library"
102102
)
103+
pybricks.git.submodule("update", "--init", "--checkout", "lib/umm_malloc")
103104

104105
# Make mpy-cross once
105106
print("Building mpy-cross")

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@
1010
path = lib/STM32_USB_Device_Library
1111
url = https://github.com/STMicroelectronics/stm32_mw_usb_device.git
1212
update = none
13+
[submodule "lib/umm_malloc"]
14+
path = lib/umm_malloc
15+
url = https://github.com/rhempel/umm_malloc.git
16+
update = none

.vscode/c_cpp_properties.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"${workspaceFolder}/lib/tiam1808/tiam1808/armv5",
7474
"${workspaceFolder}/lib/tiam1808/tiam1808/armv5/am1808",
7575
"${workspaceFolder}/lib/tiam1808/tiam1808/usblib",
76+
"${workspaceFolder}/lib/umm_malloc/src"
7677
],
7778
"defines": [
7879
"am1808",

bricks/_common/arm_none_eabi.mk

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ $(error failed)
7070
endif
7171
endif
7272
endif
73+
ifeq ($(PB_LIB_UMM_MALLOC),1)
74+
ifeq ("$(wildcard $(PBTOP)/lib/umm_malloc/README.md)","")
75+
$(info GIT cloning umm_malloc submodule)
76+
$(info $(shell cd $(PBTOP) && git submodule update --checkout --init lib/umm_malloc))
77+
ifeq ("$(wildcard $(PBTOP)/lib/umm_malloc/README.md)","")
78+
$(error failed)
79+
endif
80+
endif
81+
endif
7382

7483
# lets micropython make files work with external files
7584
USER_C_MODULES = $(PBTOP)
@@ -479,6 +488,16 @@ SRC_STM32_USB_DEV += $(addprefix lib/pbio/drv/usb/stm32_usbd/,\
479488
usbd_pybricks.c \
480489
)
481490

491+
# umm_malloc library
492+
493+
SRC_UMM_MALLOC = lib/umm_malloc/src/umm_malloc.c
494+
495+
ifeq ($(PB_LIB_UMM_MALLOC),1)
496+
CFLAGS += -I$(PBTOP)/lib/umm_malloc/src
497+
endif
498+
499+
# NXT OS
500+
482501
NXOS_SRC_C = $(addprefix lib/pbio/platform/nxt/nxos/,\
483502
_abort.c \
484503
assert.c \
@@ -553,6 +572,10 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_STM32_USB_DEV:.c=.o))
553572
$(BUILD)/lib/STM32_USB_Device_Library/%.o: CFLAGS += -Wno-sign-compare
554573
endif
555574

575+
ifeq ($(PB_LIB_UMM_MALLOC),1)
576+
OBJ += $(addprefix $(BUILD)/, $(SRC_UMM_MALLOC:.c=.o))
577+
endif
578+
556579
ifeq ($(PBIO_PLATFORM),nxt)
557580
OBJ += $(addprefix $(BUILD)/, $(NXOS_SRC_C:.c=.o))
558581
OBJ += $(addprefix $(BUILD)/, $(NXOS_SRC_S:.s=.o))

bricks/ev3/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
PBIO_PLATFORM = ev3
22
PB_MCU_FAMILY = TIAM1808
33

4+
PB_LIB_UMM_MALLOC = 1
5+
46
include ../_common/arm_none_eabi.mk

lib/pbio/platform/ev3/platform.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
#include <tiam1808/psc.h>
5252
#include <tiam1808/uart.h>
5353

54+
#include <umm_malloc.h>
55+
5456
#include <pbdrv/ioport.h>
5557
#include <pbio/port_interface.h>
5658

@@ -720,6 +722,11 @@ void SystemInit(void) {
720722
} else {
721723
memcpy(pbdrv_ev3_bluetooth_mac_address, &i2c_buf[0], 6);
722724
}
725+
726+
// Separate heap for large allocations - defined in linker script.
727+
extern char pb_umm_heap_start;
728+
extern char pb_umm_heap_end;
729+
umm_init_heap(&pb_umm_heap_start, &pb_umm_heap_end - &pb_umm_heap_start);
723730
}
724731

725732

lib/pbio/platform/ev3/platform.ld

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ MEMORY
1414

1515
_minimal_stack_size = 4M;
1616
pbdrv_stack_end = ORIGIN(DDR) + LENGTH(DDR) - 4;
17+
/* Extra heap for large allocations (images, etc). */
18+
pb_umm_heap_size = 2M;
1719

1820
SECTIONS
1921
{
@@ -68,6 +70,11 @@ SECTIONS
6870
{
6971
. = ALIGN(4);
7072
*(.noinit)
73+
74+
. = ALIGN(4);
75+
pb_umm_heap_start = .;
76+
. = . + pb_umm_heap_size;
77+
pb_umm_heap_end = .;
7178
} > DDR
7279

7380
/* Exception vector table */
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright (c) 2025 The Pybricks Authors
3+
//
4+
// Configuration for umm_malloc memory allocator for EV3 platform.
5+
// See lib/umm_malloc/src/umm_malloc_cfg.h for details.
6+
7+
// We only use this for large allocations, like images and we have a lot of RAM
8+
// on the EV3, so we can use a larger block size to reduce overhead.
9+
#define UMM_BLOCK_BODY_SIZE 256

lib/umm_malloc

Submodule umm_malloc added at ed68d0b

0 commit comments

Comments
 (0)