From 7c0714132c653796f1139d59b82b1ad678833e4c Mon Sep 17 00:00:00 2001 From: Marcus Chang Date: Sat, 19 Jan 2019 21:42:16 -0800 Subject: [PATCH 1/7] Expand sbrk to allocate memory from two regions --- .../device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld | 10 ++- .../TARGET_STM/TARGET_STM32L4/l4_retarget.c | 78 +++++++++++++++++++ 2 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld index 2ffa1c3a085..d8d3fb408a9 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld @@ -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 @@ -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 @@ -93,7 +93,7 @@ SECTIONS __etext = .; _sidata = .; - + .crash_data_ram : { . = ALIGN(8); @@ -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 diff --git a/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c b/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c new file mode 100644 index 00000000000..ff52c34c5af --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * @file l4_retarget.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Source File for STM32L475xG + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2018 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +#if (defined(TWO_RAM_REGIONS) && defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION)) +#include +#include +#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 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_0; + static bool once = true; + uint32_t heap_ind_old = heap_ind; + uint32_t heap_ind_new = heap_ind_old + incr; + + /** + * 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; + } + + heap_ind = heap_ind_new; + + return (void *) heap_ind_old; +} +#endif /* GCC_ARM toolchain && TWO_RAM_REGIONS*/ + From 719d0fb94eecfb6bf478ab416799db883d57175b Mon Sep 17 00:00:00 2001 From: Deepika Date: Tue, 5 Mar 2019 13:44:48 -0600 Subject: [PATCH 2/7] Update linker script for split heap support To have the flexibilty in application; to use any of the section (data/bss/heap) without updating linker script in every use case, following decisions are made: 1. Fixed size and small sections moved to SRAM2 (32K) Vectors Crash data Stack Remaining section - Heap memory 2. Large memory space should be used for variable sections Data BSS Heap - Remaining section Heap is moved to the end of both sections as GCC allocates till 4K boundary, if end of heap is not aligned to 4K, that chunk of memory will go unutilized --- .../device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld index d8d3fb408a9..5de43e4deef 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld @@ -104,7 +104,25 @@ SECTIONS . += M_CRASH_DATA_RAM_SIZE; . = ALIGN(8); __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ - } > SRAM1 + } > SRAM2 + + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the isr stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += STACK_SIZE - (. - __StackLimit); + } > SRAM2 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + _estack = __StackTop; + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); .data : AT (__etext) { @@ -126,7 +144,6 @@ SECTIONS KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); - . = ALIGN(8); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); @@ -139,9 +156,11 @@ SECTIONS /* All data end */ __data_end__ = .; _edata = .; - } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1") + .bss : { . = ALIGN(8); @@ -152,41 +171,22 @@ SECTIONS . = ALIGN(8); __bss_end__ = .; _ebss = .; - } > SRAM2 + } > SRAM1 + + /* Check if bss exceeds SRAM1 */ + ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") .heap (COPY): { __end__ = .; + __mbed_sbrk_start_0 = .; end = __end__; *(.heap*) - . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); - __HeapLimit = .; - } > SRAM1 - PROVIDE(__heap_size = SIZEOF(.heap)); - PROVIDE(__mbed_sbrk_start = ADDR(.heap)); - PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); - /* Check if data + heap exceeds RAM1 limit */ - ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow") - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - . += (ORIGIN(SRAM2) + STACK_SIZE - .); - __mbed_sbrk_start_0 = .; - . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + . = (ORIGIN(SRAM2) + LENGTH(SRAM2)); __mbed_krbs_start_0 = .; + __mbed_sbrk_start = __bss_end__; + . = (ORIGIN(SRAM1) + LENGTH(SRAM1)); + __mbed_krbs_start = .; + __HeapLimit = .; } > SRAM2 - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2); - _estack = __StackTop; - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - /* Check if stack exceeds RAM2 limit */ - ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow") - /* Check if bss exceeds __StackLimit */ - ASSERT(__bss_end__ <= __StackLimit, "BSS is too big for RAM2") } From 3593444e937387c7aa4b2908e013b08bf3a5c56d Mon Sep 17 00:00:00 2001 From: Deepika Date: Tue, 5 Mar 2019 14:12:41 -0600 Subject: [PATCH 3/7] Add support of heap memory split between 2-RAM banks. Please note the heap address of the both the banks must not be contigious else GCC considers it to be single memory bank and does allocation across the banks, which might result into hard-fault --- platform/mbed_retarget.cpp | 36 +++++++++ .../TARGET_STM/TARGET_STM32L4/l4_retarget.c | 78 ------------------- targets/targets.json | 5 +- 3 files changed, 39 insertions(+), 80 deletions(-) delete mode 100644 targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 36836469940..3fbf8c19ad8 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -1240,6 +1240,41 @@ extern "C" WEAK void __cxa_pure_virtual(void) // SP. This make it compatible with RTX RTOS thread stacks. #if defined(TOOLCHAIN_GCC_ARM) +#if defined(MBED_SPLIT_HEAP) + +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; + +extern "C" WEAK caddr_t _sbrk(int incr) +{ + static uint32_t heap = (uint32_t) &__mbed_sbrk_start_0; + static bool once = true; + uint32_t prev_heap = heap; + uint32_t new_heap = heap + incr; + + /** + * If the new address is outside the first region, start allocating from the second region. + */ + if (once && (new_heap > (uint32_t) &__mbed_krbs_start_0)) { + once = false; + prev_heap = (uint32_t) &__mbed_sbrk_start; + new_heap = prev_heap + incr; + } else if (new_heap > (uint32_t) &__mbed_krbs_start) { + /** + * If the new address is outside the second region, return out-of-memory. + */ + errno = ENOMEM; + return (caddr_t) - 1; + } + + heap = new_heap; + return (caddr_t) prev_heap; +} + +#else + extern "C" uint32_t __end__; extern "C" uint32_t __HeapLimit; @@ -1264,6 +1299,7 @@ extern "C" WEAK caddr_t _sbrk(int incr) return (caddr_t) prev_heap; } #endif +#endif #if defined(TOOLCHAIN_GCC_ARM) extern "C" void _exit(int return_code) diff --git a/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c b/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c deleted file mode 100644 index ff52c34c5af..00000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/l4_retarget.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - ****************************************************************************** - * @file l4_retarget.c - * @author MCD Application Team - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Source File for STM32L475xG - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2018 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ -#if (defined(TWO_RAM_REGIONS) && defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION)) -#include -#include -#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 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_0; - static bool once = true; - uint32_t heap_ind_old = heap_ind; - uint32_t heap_ind_new = heap_ind_old + incr; - - /** - * 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; - } - - heap_ind = heap_ind_new; - - return (void *) heap_ind_old; -} -#endif /* GCC_ARM toolchain && TWO_RAM_REGIONS*/ - diff --git a/targets/targets.json b/targets/targets.json index bb9ba496184..982ff630d89 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -4147,7 +4147,8 @@ "detect_code": ["0764"], "macros_add": [ "MBED_TICKLESS", - "USBHOST_OTHER" + "USBHOST_OTHER", + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -4178,7 +4179,7 @@ } }, "detect_code": ["0468"], - "macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"], + "macros_add": ["USBHOST_OTHER", "MBED_SPLIT_HEAP"], "device_has_add": [ "ANALOGOUT", "CAN", From 1a52587c2d0691eaf17771f4287ff7c8d3aa4341 Mon Sep 17 00:00:00 2001 From: Deepika Date: Wed, 6 Mar 2019 13:28:22 -0600 Subject: [PATCH 4/7] Update the linker file to support single and multiple heap banks --- .../device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld index 5de43e4deef..e7bccd34acb 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld @@ -6,14 +6,14 @@ #define MBED_APP_SIZE 1024k #endif +M_CRASH_DATA_RAM_SIZE = 0x100; + #if !defined(MBED_BOOT_STACK_SIZE) #define MBED_BOOT_STACK_SIZE 0x400 #endif STACK_SIZE = MBED_BOOT_STACK_SIZE; -M_CRASH_DATA_RAM_SIZE = 0x100; - /* Linker script to configure memory regions. */ MEMORY { @@ -106,7 +106,7 @@ SECTIONS __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ } > SRAM2 - /* .stack section doesn't contains any symbols. It is only + /* .stack section doesn't contains any symbols. It is only * used for linker to reserve space for the isr stack section * WARNING: .stack should come immediately after the last secure memory * section. This provides stack overflow detection. */ @@ -124,6 +124,17 @@ SECTIONS __StackLimit = ADDR(.stack); PROVIDE(__stack = __StackTop); + /* Place holder for additional heap */ + .heap_0 (COPY): + { + __mbed_sbrk_start_0 = .; + . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + __mbed_krbs_start_0 = .; + } > SRAM2 + + /* Check if heap exceeds SRAM2 */ + ASSERT(__mbed_krbs_start_0 <= (ORIGIN(SRAM2)+LENGTH(SRAM2)), "Heap is too big for SRAM2") + .data : AT (__etext) { __data_start__ = .; @@ -144,6 +155,7 @@ SECTIONS KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); @@ -156,6 +168,7 @@ SECTIONS /* All data end */ __data_end__ = .; _edata = .; + } > SRAM1 /* Check if bss exceeds SRAM1 */ @@ -176,17 +189,18 @@ SECTIONS /* Check if bss exceeds SRAM1 */ ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") + /* Placeholder for default single heap */ .heap (COPY): { __end__ = .; - __mbed_sbrk_start_0 = .; end = __end__; + __mbed_sbrk_start = .; *(.heap*) - . = (ORIGIN(SRAM2) + LENGTH(SRAM2)); - __mbed_krbs_start_0 = .; - __mbed_sbrk_start = __bss_end__; - . = (ORIGIN(SRAM1) + LENGTH(SRAM1)); + . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); __mbed_krbs_start = .; __HeapLimit = .; - } > SRAM2 + } > SRAM1 + + /* Check if heap exceeds SRAM1 */ + ASSERT(__HeapLimit <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "Heap is too big for SRAM1") } From 1576fb0aaabbf1471bb35641faaba654a6bb020b Mon Sep 17 00:00:00 2001 From: Deepika Date: Wed, 6 Mar 2019 15:43:34 -0600 Subject: [PATCH 5/7] Add support for split heap in ST devices --- .../device/TOOLCHAIN_GCC_ARM/STM32L471XX.ld | 79 ++++++++++++------- .../device/TOOLCHAIN_GCC_ARM/STM32L443XX.ld | 59 +++++++++----- .../device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld | 64 +++++++++------ .../device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld | 64 +++++++++------ targets/targets.json | 21 +++-- 5 files changed, 186 insertions(+), 101 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_MTS_DRAGONFLY_L471QG/device/TOOLCHAIN_GCC_ARM/STM32L471XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_MTS_DRAGONFLY_L471QG/device/TOOLCHAIN_GCC_ARM/STM32L471XX.ld index b98d61b39c1..bf4e69ae82f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_MTS_DRAGONFLY_L471QG/device/TOOLCHAIN_GCC_ARM/STM32L471XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_MTS_DRAGONFLY_L471QG/device/TOOLCHAIN_GCC_ARM/STM32L471XX.ld @@ -14,7 +14,7 @@ STACK_SIZE = MBED_BOOT_STACK_SIZE; /* 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 @@ -24,7 +24,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 @@ -92,6 +92,35 @@ SECTIONS __etext = .; _sidata = .; + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the isr stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += STACK_SIZE - (. - __StackLimit); + } > SRAM2 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + _estack = __StackTop; + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); + + /* Place holder for additional heap */ + .heap_0 (COPY): + { + __mbed_sbrk_start_0 = .; + . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + __mbed_krbs_start_0 = .; + } > SRAM2 + + /* Check if heap exceeds SRAM2 */ + ASSERT(__mbed_krbs_start_0 <= (ORIGIN(SRAM2)+LENGTH(SRAM2)), "Heap is too big for SRAM2") + .data : AT (__etext) { __data_start__ = .; @@ -99,21 +128,20 @@ SECTIONS *(vtable) *(.data*) - . = ALIGN(4); + . = ALIGN(8); /* preinit data */ PROVIDE_HIDDEN (__preinit_array_start = .); KEEP(*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); - . = ALIGN(4); + . = ALIGN(8); /* init data */ PROVIDE_HIDDEN (__init_array_start = .); KEEP(*(SORT(.init_array.*))) KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); + . = ALIGN(8); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); KEEP(*(SORT(.fini_array.*))) @@ -121,52 +149,43 @@ SECTIONS PROVIDE_HIDDEN (__fini_array_end = .); KEEP(*(.jcr*)) - . = ALIGN(4); + . = ALIGN(8); /* All data end */ __data_end__ = .; _edata = .; } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1") + .bss : { - . = ALIGN(4); + . = ALIGN(8); __bss_start__ = .; _sbss = .; *(.bss*) *(COMMON) - . = ALIGN(4); + . = ALIGN(8); __bss_end__ = .; _ebss = .; } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") + + /* Placeholder for default single heap */ .heap (COPY): { __end__ = .; end = __end__; + __mbed_sbrk_start = .; *(.heap*) . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); + __mbed_krbs_start = .; __HeapLimit = .; } > SRAM1 - PROVIDE(__heap_size = SIZEOF(.heap)); - PROVIDE(__mbed_sbrk_start = ADDR(.heap)); - PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); - /* Check if data + heap exceeds RAM1 limit */ - ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow") - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > SRAM2 - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2); - _estack = __StackTop; - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - /* Check if stack exceeds RAM2 limit */ - ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow") -} + /* Check if heap exceeds SRAM1 */ + ASSERT(__HeapLimit <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "Heap is too big for SRAM1") +} \ No newline at end of file diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/device/TOOLCHAIN_GCC_ARM/STM32L443XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/device/TOOLCHAIN_GCC_ARM/STM32L443XX.ld index c57cb94fdda..c4899c932af 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/device/TOOLCHAIN_GCC_ARM/STM32L443XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L443xC/device/TOOLCHAIN_GCC_ARM/STM32L443XX.ld @@ -93,6 +93,35 @@ SECTIONS __etext = .; _sidata = .; + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the isr stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += STACK_SIZE - (. - __StackLimit); + } > SRAM2 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + _estack = __StackTop; + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); + + /* Place holder for additional heap */ + .heap_0 (COPY): + { + __mbed_sbrk_start_0 = .; + . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + __mbed_krbs_start_0 = .; + } > SRAM2 + + /* Check if heap exceeds SRAM2 */ + ASSERT(__mbed_krbs_start_0 <= (ORIGIN(SRAM2)+LENGTH(SRAM2)), "Heap is too big for SRAM2") + .data : AT (__etext) { __data_start__ = .; @@ -129,6 +158,9 @@ SECTIONS } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1") + .bss : { . = ALIGN(8); @@ -141,30 +173,21 @@ SECTIONS _ebss = .; } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") + + /* Placeholder for default single heap */ .heap (COPY): { __end__ = .; end = __end__; + __mbed_sbrk_start = .; *(.heap*) - . = ORIGIN(SRAM1) + LENGTH(SRAM1) - STACK_SIZE; + . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); + __mbed_krbs_start = .; __HeapLimit = .; } > SRAM1 - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > SRAM1 - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1); - _estack = __StackTop; - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + /* Check if heap exceeds SRAM1 */ + ASSERT(__HeapLimit <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "Heap is too big for SRAM1") } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld index 71f28a5c25a..00ace2cd76b 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld @@ -104,7 +104,36 @@ SECTIONS . += M_CRASH_DATA_RAM_SIZE; . = ALIGN(8); __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ - } > SRAM1 + } > SRAM2 + + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the isr stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += STACK_SIZE - (. - __StackLimit); + } > SRAM2 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + _estack = __StackTop; + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); + + /* Place holder for additional heap */ + .heap_0 (COPY): + { + __mbed_sbrk_start_0 = .; + . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + __mbed_krbs_start_0 = .; + } > SRAM2 + + /* Check if heap exceeds SRAM2 */ + ASSERT(__mbed_krbs_start_0 <= (ORIGIN(SRAM2)+LENGTH(SRAM2)), "Heap is too big for SRAM2") .data : AT (__etext) { @@ -126,7 +155,6 @@ SECTIONS KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); - . = ALIGN(8); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); @@ -142,6 +170,9 @@ SECTIONS } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1") + .bss : { . = ALIGN(8); @@ -154,34 +185,21 @@ SECTIONS _ebss = .; } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") + + /* Placeholder for default single heap */ .heap (COPY): { __end__ = .; end = __end__; + __mbed_sbrk_start = .; *(.heap*) . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); + __mbed_krbs_start = .; __HeapLimit = .; } > SRAM1 - PROVIDE(__heap_size = SIZEOF(.heap)); - PROVIDE(__mbed_sbrk_start = ADDR(.heap)); - PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); - /* Check if data + heap exceeds RAM1 limit */ - ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow") - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > SRAM2 - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2); - _estack = __StackTop; - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - /* Check if stack exceeds RAM2 limit */ - ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow") + /* Check if heap exceeds SRAM1 */ + ASSERT(__HeapLimit <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "Heap is too big for SRAM1") } diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld index 71f28a5c25a..00ace2cd76b 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld @@ -104,7 +104,36 @@ SECTIONS . += M_CRASH_DATA_RAM_SIZE; . = ALIGN(8); __CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */ - } > SRAM1 + } > SRAM2 + + /* .stack section doesn't contains any symbols. It is only + * used for linker to reserve space for the isr stack section + * WARNING: .stack should come immediately after the last secure memory + * section. This provides stack overflow detection. */ + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*); + . += STACK_SIZE - (. - __StackLimit); + } > SRAM2 + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ADDR(.stack) + SIZEOF(.stack); + _estack = __StackTop; + __StackLimit = ADDR(.stack); + PROVIDE(__stack = __StackTop); + + /* Place holder for additional heap */ + .heap_0 (COPY): + { + __mbed_sbrk_start_0 = .; + . += (ORIGIN(SRAM2) + LENGTH(SRAM2) - .); + __mbed_krbs_start_0 = .; + } > SRAM2 + + /* Check if heap exceeds SRAM2 */ + ASSERT(__mbed_krbs_start_0 <= (ORIGIN(SRAM2)+LENGTH(SRAM2)), "Heap is too big for SRAM2") .data : AT (__etext) { @@ -126,7 +155,6 @@ SECTIONS KEEP(*(.init_array)) PROVIDE_HIDDEN (__init_array_end = .); - . = ALIGN(8); /* finit data */ PROVIDE_HIDDEN (__fini_array_start = .); @@ -142,6 +170,9 @@ SECTIONS } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__data_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), ".data is too big for SRAM1") + .bss : { . = ALIGN(8); @@ -154,34 +185,21 @@ SECTIONS _ebss = .; } > SRAM1 + /* Check if bss exceeds SRAM1 */ + ASSERT(__bss_end__ <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "BSS is too big for SRAM1") + + /* Placeholder for default single heap */ .heap (COPY): { __end__ = .; end = __end__; + __mbed_sbrk_start = .; *(.heap*) . += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .); + __mbed_krbs_start = .; __HeapLimit = .; } > SRAM1 - PROVIDE(__heap_size = SIZEOF(.heap)); - PROVIDE(__mbed_sbrk_start = ADDR(.heap)); - PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); - /* Check if data + heap exceeds RAM1 limit */ - ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow") - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > SRAM2 - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2); - _estack = __StackTop; - __StackLimit = __StackTop - STACK_SIZE; - PROVIDE(__stack = __StackTop); - /* Check if stack exceeds RAM2 limit */ - ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow") + /* Check if heap exceeds SRAM1 */ + ASSERT(__HeapLimit <= (ORIGIN(SRAM1)+LENGTH(SRAM1)), "Heap is too big for SRAM1") } diff --git a/targets/targets.json b/targets/targets.json index 982ff630d89..9f86a470345 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -3465,7 +3465,7 @@ "MPU" ], "device_has_remove": ["LPTICKER"], - "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"], + "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT", "MBED_SPLIT_HEAP"], "device_name": "STM32L443RC", "detect_code": ["0458"], "bootloader_supported": true @@ -3490,7 +3490,8 @@ "detect_code": ["0765"], "macros_add": [ "MBED_TICKLESS", - "USBHOST_OTHER" + "USBHOST_OTHER", + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -3552,7 +3553,8 @@ "macros_add": [ "MBED_TICKLESS", "USBHOST_OTHER", - "MBEDTLS_CONFIG_HW_SUPPORT" + "MBEDTLS_CONFIG_HW_SUPPORT", + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -3587,7 +3589,8 @@ "detect_code": ["0460"], "macros_add": [ "MBEDTLS_CONFIG_HW_SUPPORT", - "WISE_1570" + "WISE_1570", + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -4212,7 +4215,8 @@ "detect_code": ["0820"], "macros_add": [ "MBED_TICKLESS", - "USBHOST_OTHER" + "USBHOST_OTHER", + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -4227,7 +4231,7 @@ "device_name": "STM32L476VG", "bootloader_supported": true }, - "RHOMBIO_L476DMW1K": { + "RHOMBIO_L476DMW1K": { "components_add": ["FLASHIAP"], "inherits": ["FAMILY_STM32"], "core": "Cortex-M4F", @@ -4248,7 +4252,7 @@ "macros_add": [ "MBED_TICKLESS", "USBHOST_OTHER", - "TWO_RAM_REGIONS" + "MBED_SPLIT_HEAP" ], "device_has_add": [ "ANALOGOUT", @@ -4357,6 +4361,9 @@ "FLASH", "MPU" ], + "macros_add": [ + "MBED_SPLIT_HEAP" + ], "release_versions": ["2", "5"], "device_name": "STM32L471QG", "bootloader_supported": true From 56154c096d1f5483019c3982cc557e6153a790f1 Mon Sep 17 00:00:00 2001 From: Deepika Date: Wed, 6 Mar 2019 13:29:00 -0600 Subject: [PATCH 6/7] Update the test case to check multiple bank heap regions --- .../heap_and_stack/main.cpp | 18 +++++++- TESTS/mbedmicro-rtos-mbed/malloc/main.cpp | 41 ++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp index 4d6c8f86749..c0f6f4cf351 100644 --- a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp @@ -48,6 +48,12 @@ extern uint32_t mbed_heap_size; extern uint32_t mbed_stack_isr_start; extern uint32_t mbed_stack_isr_size; +#if defined(TOOLCHAIN_GCC_ARM) && defined(MBED_SPLIT_HEAP) +extern uint32_t __mbed_sbrk_start_0; +extern uint32_t __mbed_krbs_start_0; +unsigned char *mbed_heap_start_0 = (unsigned char *) &__mbed_sbrk_start_0;; +uint32_t mbed_heap_size_0 = (uint32_t) &__mbed_krbs_start_0 - (uint32_t) &__mbed_sbrk_start_0; +#endif struct linked_list { linked_list *next; @@ -121,7 +127,11 @@ static void allocate_and_fill_heap(linked_list *&head) break; } bool result = rangeinrange((uint32_t) temp, sizeof(linked_list), mbed_heap_start, mbed_heap_size); - +#if defined(TOOLCHAIN_GCC_ARM) && defined(MBED_SPLIT_HEAP) + if (false == result) { + result = rangeinrange((uint32_t) temp, sizeof(linked_list), (uint32_t)mbed_heap_start_0, mbed_heap_size_0); + } +#endif TEST_ASSERT_TRUE_MESSAGE(result, "Memory allocation out of range"); // Init @@ -169,7 +179,11 @@ void test_heap_in_range(void) TEST_ASSERT_NOT_NULL(initial_heap); bool result = inrange((uint32_t) initial_heap, mbed_heap_start, mbed_heap_size); - +#if defined(TOOLCHAIN_GCC_ARM) && defined(MBED_SPLIT_HEAP) + if (false == result) { + result = inrange((uint32_t) initial_heap, (uint32_t)mbed_heap_start_0, mbed_heap_size_0); + } +#endif TEST_ASSERT_TRUE_MESSAGE(result, "Heap in wrong location"); free(initial_heap); } diff --git a/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp b/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp index 004aa4a9223..ef126bda8a3 100644 --- a/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/malloc/main.cpp @@ -107,6 +107,44 @@ void test_multithread_allocation(void) TEST_ASSERT_FALSE(thread_alloc_failure); } +/** Test for multiple heap alloc and free calls */ +#define ALLOC_ARRAY_SIZE 100 +#define ALLOC_LOOP 20 +#define SIZE_INCREMENTS 1023 +#define SIZE_MODULO 31 + +void test_alloc_and_free(void) +{ + void *array[ALLOC_ARRAY_SIZE]; + void *data = NULL; + long total_allocated = 0; + int count = 0; + int size = SIZE_INCREMENTS; + int loop = ALLOC_LOOP; + while (loop) { + data = malloc(size); + if (NULL != data) { + array[count++] = data; + memset((void *)data, 0xdeadbeef, size); + total_allocated += size; + size += SIZE_INCREMENTS; + if (size > 10000) { + size %= SIZE_MODULO; + } + } else { + for (int i = 0; i < count; i++) { + free(array[i]); + array[i] = NULL; + } + loop--; + printf("Total size dynamically allocated: %luB\n", total_allocated); + total_allocated = 0; + count = 0; + continue; + } + } +} + /** Test for large heap allocation Given a heap of size mbed_heap_size @@ -167,7 +205,8 @@ Case cases[] = { Case("Test 0 size allocation", test_zero_allocation), Case("Test NULL pointer free", test_null_free), Case("Test multithreaded allocations", test_multithread_allocation), - Case("Test large allocation", test_big_allocation) + Case("Test large allocation", test_big_allocation), + Case("Test multiple alloc and free calls", test_alloc_and_free) }; utest::v1::status_t greentea_test_setup(const size_t number_of_cases) From 20a341d55fea17008e9cad30a19c6d206b931cbf Mon Sep 17 00:00:00 2001 From: Deepika Date: Mon, 15 Apr 2019 12:00:19 -0500 Subject: [PATCH 7/7] Add more information and comments --- platform/mbed_retarget.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 3fbf8c19ad8..ad235cfeb60 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -1242,8 +1242,12 @@ extern "C" WEAK void __cxa_pure_virtual(void) #if defined(MBED_SPLIT_HEAP) +// Default RAM memory used for heap extern uint32_t __mbed_sbrk_start; extern uint32_t __mbed_krbs_start; +/* Additional RAM memory used for heap - please note this + * address should be lower address then the previous default address + */ extern uint32_t __mbed_sbrk_start_0; extern uint32_t __mbed_krbs_start_0; @@ -1256,6 +1260,7 @@ extern "C" WEAK caddr_t _sbrk(int incr) /** * If the new address is outside the first region, start allocating from the second region. + * Jump to second region is done just once, and `static bool once` is used to keep track of that. */ if (once && (new_heap > (uint32_t) &__mbed_krbs_start_0)) { once = false;