Skip to content

Request for comments: Expand sbrk to allocate memory from two regions #9441

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ M_CRASH_DATA_RAM_SIZE = 0x100;

/* Linker script to configure memory regions. */
MEMORY
{
{
FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
SRAM2 (rwx) : ORIGIN = 0x10000188, LENGTH = 32k - 0x188
SRAM1 (rwx) : ORIGIN = 0x20000000, LENGTH = 96k
Expand All @@ -26,7 +26,7 @@ MEMORY
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
Expand Down Expand Up @@ -93,7 +93,7 @@ SECTIONS

__etext = .;
_sidata = .;

.crash_data_ram :
{
. = ALIGN(8);
Expand Down Expand Up @@ -173,6 +173,10 @@ SECTIONS
.stack_dummy (COPY):
{
*(.stack*)
. += (ORIGIN(SRAM2) + STACK_SIZE - .);
__mbed_sbrk_start_0 = .;
. += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .);
__mbed_krbs_start_0 = .;
} > SRAM2

/* Set stack top to end of RAM, and stack limit move down by
Expand Down
24 changes: 19 additions & 5 deletions targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,39 @@
******************************************************************************
*/
#if (defined(TWO_RAM_REGIONS) && defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION))
#include <stdbool.h>
#include <errno.h>
#include "stm32l4xx.h"
extern uint32_t __mbed_sbrk_start;
extern uint32_t __mbed_krbs_start;
extern uint32_t __mbed_sbrk_start_0;
extern uint32_t __mbed_krbs_start_0;

/**
* The default implementation of _sbrk() (in platform/mbed_retarget.cpp) for GCC_ARM requires one-region model (heap and
* stack share one region), which doesn't fit two-region model (heap and stack are two distinct regions), for example,
* STM32L475xG locates heap on SRAM1 and stack on SRAM2.
* The default implementation of _sbrk() (in platform/mbed_retarget.cpp) for GCC_ARM only supports one region.
* This implementation supports two regions by continuing the allocation to the second region after the first
* one is full.
* Define __wrap__sbrk() to override the default _sbrk(). It is expected to get called through gcc
* hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk().
*/
void *__wrap__sbrk(int incr)
{
static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start;
static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start_0;
static bool once = true;
uint32_t heap_ind_old = heap_ind;
uint32_t heap_ind_new = heap_ind_old + incr;

if (heap_ind_new > (uint32_t)&__mbed_krbs_start) {
/**
* If the new address is outside the first region, start allocating from the second region.
*/
if (once && (heap_ind_new >= (uint32_t)&__mbed_krbs_start_0)) {
once = false;
heap_ind_old = (uint32_t)&__mbed_sbrk_start;
heap_ind_new = heap_ind_old + incr;
/**
* If the new address is outside the second region, return out-of-memory.
*/
} else if (heap_ind_new >= (uint32_t)&__mbed_krbs_start) {
errno = ENOMEM;
return (void *) - 1;
}
Expand Down