Skip to content
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

Update to 2-region model for HEAP and Stack Memory #9571

Merged
merged 40 commits into from Feb 27, 2019
Merged
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a322327
Use 2-region memory model in ARM rtos-less builds.
mprse Jan 31, 2019
e60a0f4
Remove duplicated _mbed_user_setup_stackheap, __rt_lib_init definitions.
mprse Jan 31, 2019
9c11288
mbed_retarget.cpp: Fixed style
mprse Jan 31, 2019
26a6a9a
Add RAM memory model update document
deepikabhavnani Feb 1, 2019
a1fe750
Interrupt stack is always explicitly specified, hence other condition…
deepikabhavnani Feb 4, 2019
41eaefe
Update memory model for stack and heap memory
deepikabhavnani Feb 6, 2019
8b02a60
TARGET_ARM_FM: Set the heap size and limit
deepikabhavnani Feb 6, 2019
25bceda
TARGET_Atmel: Set the heap size and limit
deepikabhavnani Feb 6, 2019
5e4dcab
Target_Cypress: Set the heap limit
deepikabhavnani Feb 6, 2019
e03455a
Target_Freescale: Set the heap size and limit
deepikabhavnani Feb 6, 2019
25a127e
target_Gigadevice: Set the heap size and limit
deepikabhavnani Feb 6, 2019
8c63dbe
Target_Maxim: Setup heap limit and size
deepikabhavnani Feb 6, 2019
b2e189f
Target_Nuvoton: Remove target specific implementation of _sbrk
deepikabhavnani Feb 6, 2019
57b9ccc
Target_NXP: Setup heap limit and size
deepikabhavnani Feb 7, 2019
73f4a52
Target_ONSEMI: Setup heap limit and size
deepikabhavnani Feb 7, 2019
a814078
Target_UNO_91H: Remove custom _sbrk, update heap limits
deepikabhavnani Feb 7, 2019
c85ca4d
TARGET_RENESAS: _sbrk updated to use limits from linker files no need…
deepikabhavnani Feb 7, 2019
1f57568
TARGET_Silicon_Labs Setup heap limit and size
deepikabhavnani Feb 7, 2019
e522c46
Target_STM:_sbrk updated to use limits from linker files no need to s…
deepikabhavnani Feb 7, 2019
72ae546
TARGET_TOSHIBA :Setup heap limit and size
deepikabhavnani Feb 7, 2019
c6a72f2
TARGET_TT: Setup heap limit and size
deepikabhavnani Feb 7, 2019
462f339
TARGET_Wiznet: Setup heap limit and size
deepikabhavnani Feb 7, 2019
537b364
Resolve build/type cast errors
deepikabhavnani Feb 7, 2019
d0cc7ac
Target_Cypress: Update linker files to add heap limit
deepikabhavnani Feb 10, 2019
9ed7e4d
Remove unnecessary endif
deepikabhavnani Feb 10, 2019
9d1ce66
ISR_STACK_START/ HEAP_START defines not used by GCC_ARM toolchain
deepikabhavnani Feb 10, 2019
b36147f
ISR_Stack_start/size defines are not needed, use linker file defines
deepikabhavnani Feb 10, 2019
f13a3e3
Fix GCC _sbrk allocation
deepikabhavnani Feb 11, 2019
e7e9e07
Update K64F linker files for general solution of 2-ram regions
deepikabhavnani Feb 11, 2019
9231e26
Corrected main thread stack size, was accidently updated by removing …
deepikabhavnani Feb 12, 2019
2a1211a
Add heaplimit to NRF52 devices
deepikabhavnani Feb 12, 2019
1a1c74c
mbed_rtx.h not to include in platform
deepikabhavnani Feb 12, 2019
38e9314
Add missing space in linker script
deepikabhavnani Feb 12, 2019
c5ad5f6
Target_Freescale:Add heap section
deepikabhavnani Feb 12, 2019
60e7a7d
Add heap section to linker file
deepikabhavnani Feb 13, 2019
f518a69
Remove unused heap_size define
deepikabhavnani Feb 13, 2019
0d4d45e
Spell correction in design doc
deepikabhavnani Feb 18, 2019
dab2a30
Target_Freescale: Add heap section in linker files
deepikabhavnani Feb 20, 2019
387e4ca
New heap can be equal to heap limit for last chunk
deepikabhavnani Feb 21, 2019
49266c1
Remove TOOLCHAIN_GCC_CW_NEWLIB files
deepikabhavnani Feb 22, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Update memory model for stack and heap memory

Memory model for RTOS and No RTOS was initially single stack and heap,
only few targets implemented 2-region RAM model.

2-region RAM model is applied for all toolchains and targets.

GCC: __wrap__sbrk was implemented for 2-region ram model, with switch to 2-region
for all targets, we do not need target specific implementation of this API
Also _sbrk is WEAK function, hence can be over written in target folder for
special cases
  • Loading branch information...
deepikabhavnani committed Feb 6, 2019
commit 41eaefeeb42a8a50080b3aaebcaa2c53c99884c5
@@ -42,6 +42,7 @@
#include <stdio.h>
#include <errno.h>
#include "platform/mbed_retarget.h"
#include "mbed_rtx.h"

static SingletonPtr<PlatformMutex> _mutex;

@@ -905,75 +906,53 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
return size;
}


// Do not compile this code for TFM secure target
#if !defined(COMPONENT_SPE) || !defined(TARGET_TFM)

#if defined(TARGET_NUVOTON) || defined(TARGET_RZ_A1XX)
extern char Image$$ARM_LIB_HEAP$$ZI$$Base[];
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
#define HEAP_BASE (Image$$ARM_LIB_HEAP$$ZI$$Base)
#define HEAP_LIMIT (Image$$ARM_LIB_HEAP$$ZI$$Limit)
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
__asm(".global __use_two_region_memory\n\t");
__asm(".global __use_no_semihosting\n\t");

#else
extern char Image$$RW_IRAM1$$ZI$$Limit[];
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
#define HEAP_BASE (Image$$RW_IRAM1$$ZI$$Limit)
#define HEAP_LIMIT (Image$$ARM_LIB_STACK$$ZI$$Base)
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
#pragma import(__use_two_region_memory)
#endif

#if !defined(ISR_STACK_START)
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
#define ISR_STACK_START Image$$ARM_LIB_STACK$$ZI$$Base
#define ISR_STACK_SIZE Image$$ARM_LIB_STACK$$ZI$$Length
#endif

#if !defined(HEAP_START)
// Heap here is considered starting after ZI ends to Stack start
extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
#define HEAP_START Image$$RW_IRAM1$$ZI$$Limit
#define HEAP_SIZE ((uint32_t)(ISR_STACK_START - HEAP_START))
#endif

#define HEAP_LIMIT (HEAP_START + HEAP_SIZE)

extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
{
uint32_t heap_base = (uint32_t)HEAP_START;
struct __initial_stackheap r;
r.heap_base = (uint32_t)HEAP_BASE;

// Ensure heap_base is 8-byte aligned
heap_base = (heap_base + 7) & ~0x7;
r.heap_base = (uint32_t)heap_base;
r.heap_limit = (uint32_t)HEAP_LIMIT;

return r;
}

#ifndef MBED_CONF_RTOS_PRESENT

/* The single region memory model would check stack collision at run time, verifying that
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
__asm(".global __use_two_region_memory\n\t");
__asm(".global __use_no_semihosting\n\t");
#else
#pragma import(__use_two_region_memory)
#endif

/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
*
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
* __rt_entry has the following call sequence:
* 1. _platform_pre_stackheap_init
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
* 3. _platform_post_stackheap_init
* 4. __rt_lib_init
* 5. _platform_post_lib_init
* 6. main()
* 7. exit()
*
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
* ARM_LIB_HEAP region is defined in scatter file.
*
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
* overridden and the overriding __rt_lib_init here gets meaningless.
*/
extern "C" extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);

extern "C" __value_in_regs struct __argc_argv $Sub$$__rt_lib_init(unsigned heapbase, unsigned heaptop)
{
return $Super$$__rt_lib_init((unsigned)HEAP_BASE, (unsigned)HEAP_LIMIT);
return $Super$$__rt_lib_init((unsigned)HEAP_START, (unsigned)HEAP_LIMIT);
}

#endif

extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
{
return _mbed_user_setup_stackheap(R0, R1, R2, R3);
@@ -1262,46 +1241,29 @@ 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(TARGET_CORTEX_A) || (defined(TARGET_TFM) && defined(COMPONENT_SPE))
extern "C" uint32_t __HeapLimit;
#if !defined(HEAP_START)
/* Defined by linker script */
extern uint32_t __end__;
extern uint32_t __HeapLimit;
#define HEAP_START (__end__)
#define HEAP_LIMIT (__HeapLimit)
#else
#define HEAP_LIMIT ((uint32_t)(HEAP_START + HEAP_SIZE))
#endif

// Turn off the errno macro and use actual global variable instead.
#undef errno
extern "C" int errno;

// Dynamic memory allocation related syscall.
#if defined(TWO_RAM_REGIONS)

// Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
// __wrap__sbrk() is implemented in:
// TARGET_STM32L4 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4/l4_retarget.c
extern "C" void *__wrap__sbrk(int incr);
extern "C" caddr_t _sbrk(int incr)
{
return (caddr_t) __wrap__sbrk(incr);
}
#else
// Linker defined symbol used by _sbrk to indicate where heap should start.
extern "C" uint32_t __end__;
// Weak attribute allows user to override, e.g. to use external RAM for dynamic memory.
extern "C" WEAK caddr_t _sbrk(int incr)
{
static unsigned char *heap = (unsigned char *)&__end__;
unsigned char *prev_heap = heap;
unsigned char *new_heap = heap + incr;
static uint32_t heap = (uint32_t) &HEAP_START;
uint32_t prev_heap = heap;
uint32_t new_heap = heap + incr;

#if defined(TARGET_CORTEX_A) || (defined(TARGET_TFM) && defined(COMPONENT_SPE))
if (new_heap >= (unsigned char *)&__HeapLimit) { /* __HeapLimit is end of heap section */
#else
if (new_heap >= (unsigned char *)__get_MSP()) {
#endif
errno = ENOMEM;
return (caddr_t) -1;
}

// Additional heap checking if set
if (mbed_heap_size && (new_heap >= mbed_heap_start + mbed_heap_size)) {
/* __HeapLimit is end of heap section */
if (new_heap >= (uint32_t) &HEAP_LIMIT) {
errno = ENOMEM;
return (caddr_t) -1;
}
@@ -1310,7 +1272,6 @@ 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)
@@ -68,7 +68,7 @@ void mbed_copy_nvic(void)

/* Toolchain specific main code */

#if defined (__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5010060))
#if defined (__ARMCC_VERSION)

int $Super$$main(void);

@@ -27,18 +27,18 @@
__value_in_regs struct __argc_argv __rt_lib_init(unsigned heapbase, unsigned heaptop);
void _platform_post_stackheap_init(void);

#if !defined(ISR_STACK_SIZE)
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
#define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base)
#define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length)
#if !defined(ISR_STACK_START)
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
#define ISR_STACK_START Image$$ARM_LIB_STACK$$ZI$$Base
#define ISR_STACK_SIZE Image$$ARM_LIB_STACK$$ZI$$Length
#endif

#if !defined(HEAP_START)
/* Defined by linker script */
// Heap here is considered starting after ZI ends to Stack start
extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
#define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
#define HEAP_SIZE ((uint32_t)((uint32_t)ISR_STACK_START - (uint32_t)HEAP_START))
#define HEAP_START Image$$RW_IRAM1$$ZI$$Limit
#define HEAP_SIZE ((uint32_t)(ISR_STACK_START - HEAP_START))
#endif

/*
@@ -58,11 +58,11 @@ extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
*/
void __rt_entry(void)
{
mbed_stack_isr_size = (unsigned char *)ISR_STACK_SIZE;
mbed_stack_isr_start = ISR_STACK_START;

mbed_heap_size = (uint32_t)HEAP_SIZE;
mbed_stack_isr_start = (unsigned char *)ISR_STACK_START;
mbed_stack_isr_size = (uint32_t)ISR_STACK_SIZE;
mbed_heap_start = (unsigned char *)HEAP_START;
mbed_heap_size = (uint32_t)HEAP_SIZE;

mbed_init();

_platform_post_stackheap_init();
@@ -32,15 +32,17 @@ static osMutexAttr_t env_mutex_attr;
#if !defined(ISR_STACK_SIZE)
extern uint32_t __StackLimit;
extern uint32_t __StackTop;
#define ISR_STACK_START ((unsigned char*)&__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)&__StackTop - (uint32_t)&__StackLimit))
#define ISR_STACK_START (__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)(__StackTop - __StackLimit))
#endif

#if !defined(HEAP_START)
/* Defined by linker script */
extern uint32_t __end__[];
#define HEAP_START ((unsigned char*)__end__)
#define HEAP_SIZE ((uint32_t)((uint32_t)ISR_STACK_START - (uint32_t)HEAP_START))
extern uint32_t __end__;
extern uint32_t __HeapLimit;
#define HEAP_START (__end__)
#define HEAP_LIMIT (__HeapLimit)
#define HEAP_SIZE ((uint32_t)(HEAP_LIMIT - HEAP_START))
#endif

extern void __libc_init_array(void);
@@ -52,13 +54,10 @@ extern void __libc_init_array(void);
*/
void software_init_hook(void)
{
/* Interrupt stack explicitly specified */
mbed_stack_isr_size = (unsigned char *)ISR_STACK_SIZE;
mbed_stack_isr_start = (uint32_t)ISR_STACK_START;

/* Heap - everything else */
mbed_heap_size = (uint32_t)HEAP_SIZE;
mbed_heap_start = (unsigned char *)HEAP_START;
mbed_stack_isr_start = (unsigned char *) &ISR_STACK_START;
mbed_stack_isr_size = (uint32_t) ISR_STACK_SIZE;
mbed_heap_start = (unsigned char *) &HEAP_START;
mbed_heap_size = (uint32_t) HEAP_SIZE;

mbed_init();
mbed_rtos_start();
@@ -3281,8 +3281,7 @@
"detect_code": ["0765"],
"macros_add": [
"MBED_TICKLESS",
"USBHOST_OTHER",
"TWO_RAM_REGIONS"
"USBHOST_OTHER"
],
"device_has_add": [
"ANALOGOUT",
@@ -3310,7 +3309,7 @@
}
},
"detect_code": ["0766"],
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
"macros_add": ["USBHOST_OTHER"],
"device_has_add": [
"ANALOGOUT",
"CAN",
@@ -3344,8 +3343,7 @@
"macros_add": [
"MBED_TICKLESS",
"USBHOST_OTHER",
"MBEDTLS_CONFIG_HW_SUPPORT",
"TWO_RAM_REGIONS"
"MBEDTLS_CONFIG_HW_SUPPORT"
],
"device_has_add": [
"ANALOGOUT",
@@ -3380,8 +3378,7 @@
"detect_code": ["0460"],
"macros_add": [
"MBEDTLS_CONFIG_HW_SUPPORT",
"WISE_1570",
"TWO_RAM_REGIONS"
"WISE_1570"
],
"device_has_add": [
"ANALOGOUT",
@@ -3907,8 +3904,7 @@
"detect_code": ["0764"],
"macros_add": [
"MBED_TICKLESS",
"USBHOST_OTHER",
"TWO_RAM_REGIONS"
"USBHOST_OTHER"
],
"device_has_add": [
"ANALOGOUT",
@@ -3942,8 +3938,7 @@
"detect_code": ["0820"],
"macros_add": [
"MBED_TICKLESS",
"USBHOST_OTHER",
"TWO_RAM_REGIONS"
"USBHOST_OTHER"
],
"device_has_add": [
"ANALOGOUT",
@@ -4043,7 +4038,6 @@
"macro_name": "MODEM_ON_BOARD_UART"
}
},
"macros_add": ["TWO_RAM_REGIONS"],
"detect_code": ["0312"],
"device_has_add": [
"ANALOGOUT",
@@ -8067,7 +8061,7 @@
"public": true,
"extra_labels": ["RDA", "UNO_91H", "FLASH_CMSIS_ALGO", "RDA_EMAC"],
"supported_toolchains": ["ARM", "GCC_ARM", "IAR"],
"macros": ["TWO_RAM_REGIONS", "CMSIS_NVIC_VIRTUAL", "CMSIS_NVIC_VIRTUAL_HEADER_FILE=\"RDA5981_nvic_virtual.h\""],
"macros": ["CMSIS_NVIC_VIRTUAL", "CMSIS_NVIC_VIRTUAL_HEADER_FILE=\"RDA5981_nvic_virtual.h\""],
"device_has": [
"USTICKER",
"PORTIN",
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.