Skip to content

Fix baremetal heap and stack initialisation #12225

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

Merged
merged 1 commit into from
Jan 21, 2020
Merged
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
41 changes: 34 additions & 7 deletions TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

#if defined(TARGET_CORTEX_A) || !DEVICE_USTICKER || !defined(MBED_CONF_RTOS_PRESENT)
#if defined(TARGET_CORTEX_A) || !DEVICE_USTICKER
#error [NOT_SUPPORTED] test not supported.
#else

Expand All @@ -39,9 +39,9 @@ static const int test_timeout = 30;
// Malloc fill pattern
#define MALLOC_FILL 0x55

extern uint32_t mbed_heap_start;
extern unsigned char *mbed_heap_start;
extern uint32_t mbed_heap_size;
extern uint32_t mbed_stack_isr_start;
extern unsigned char *mbed_stack_isr_start;
extern uint32_t mbed_stack_isr_size;

#if defined(TOOLCHAIN_GCC_ARM) && defined(MBED_SPLIT_HEAP)
Expand All @@ -57,6 +57,27 @@ struct linked_list {
};


// Global test variables
#define TEST_VALUE 789
static struct Test {
Test() : val(TEST_VALUE) {}
~Test() {}
int val;
} t;

int test_function()
{
return TEST_VALUE;
}
static int global_int = test_function();

/** Test global variables initialisation
*/
void test_global_variables_initialisation(void)
{
TEST_ASSERT_EQUAL(TEST_VALUE, global_int);
TEST_ASSERT_EQUAL(TEST_VALUE, t.val);
}

/* TODO: add memory layout test.
*
Expand Down Expand Up @@ -122,7 +143,7 @@ static void allocate_and_fill_heap(linked_list *&head)
if (NULL == temp) {
break;
}
bool result = rangeinrange((uint32_t) temp, sizeof(linked_list), mbed_heap_start, mbed_heap_size);
bool result = rangeinrange((uint32_t) temp, sizeof(linked_list), (uint32_t)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);
Expand Down Expand Up @@ -174,7 +195,8 @@ void test_heap_in_range(void)
initial_heap = (char *) malloc(1);
TEST_ASSERT_NOT_NULL(initial_heap);

bool result = inrange((uint32_t) initial_heap, mbed_heap_start, mbed_heap_size);
bool result = inrange((uint32_t) initial_heap, (uint32_t)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);
Expand All @@ -184,6 +206,7 @@ void test_heap_in_range(void)
free(initial_heap);
}

#if MBED_CONF_RTOS_PRESENT
/** Test for Main thread stack

Given a Main thread and its stack
Expand All @@ -203,6 +226,7 @@ void test_main_stack_in_range(void)

TEST_ASSERT_TRUE_MESSAGE(result, "Main stack in wrong location");
}
#endif // #if MBED_CONF_RTOS_PRESENT

/** Test for Scheduler/ISR thread stack

Expand All @@ -214,7 +238,7 @@ void test_isr_stack_in_range(void)
{
// MSP stack should be very near end (test using within 128 bytes)
uint32_t msp = __get_MSP();
bool result = inrange(msp, mbed_stack_isr_start + mbed_stack_isr_size - 0x400, 0x400);
bool result = inrange(msp, (uint32_t)mbed_stack_isr_start + mbed_stack_isr_size - 0x400, 0x400);

TEST_ASSERT_TRUE_MESSAGE(result, "Interrupt stack in wrong location");
}
Expand Down Expand Up @@ -244,8 +268,11 @@ void test_heap_allocation_free(void)

// Test cases
Case cases[] = {
Case("Test global variables initialisation", test_global_variables_initialisation),
Case("Test heap in range", test_heap_in_range),
#if MBED_CONF_RTOS_PRESENT
Case("Test main stack in range", test_main_stack_in_range),
#endif
Case("Test isr stack in range", test_isr_stack_in_range),
Case("Test heap allocation and free", test_heap_allocation_free)
};
Expand All @@ -263,4 +290,4 @@ int main()
return !utest::v1::Harness::run(specification);
}

#endif // defined(TARGET_CORTEX_A) || !DEVICE_USTICKER || !defined(MBED_CONF_RTOS_PRESENT)
#endif // defined(TARGET_CORTEX_A) || !DEVICE_USTICKER
4 changes: 4 additions & 0 deletions platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
EXTERN exit
EXTERN __iar_dynamic_initialization
EXTERN mbed_sdk_init
EXTWEAK __mbed_init
EXTERN mbed_main
EXTERN SystemInit

Expand All @@ -68,6 +69,9 @@ __cmain:
FUNCALL __cmain, mbed_sdk_init
BL mbed_sdk_init
MOVS r0,#0 ; No parameters
FUNCALL __cmain, __mbed_init
BL __mbed_init
MOVS r0,#0 ; No parameters
FUNCALL __cmain, __iar_dynamic_initialization
BL __iar_dynamic_initialization ; C++ dynamic initialization

Expand Down
17 changes: 0 additions & 17 deletions platform/source/mbed_retarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,23 +561,6 @@ std::FILE *fdopen(FileHandle *fh, const char *mode)
extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags)
{
#if defined(__MICROLIB) && (__ARMCC_VERSION>5030000)
#if !defined(MBED_CONF_RTOS_PRESENT)
// valid only for mbed 2
// for ulib, this is invoked after RAM init, prior c++
// used as hook, as post stack/heap is not active there
extern void mbed_copy_nvic(void);
extern void mbed_sdk_init(void);

static int mbed_sdk_inited = 0;
if (!mbed_sdk_inited) {
mbed_copy_nvic();
mbed_sdk_init();
#if DEVICE_USTICKER && MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
us_ticker_init();
#endif
mbed_sdk_inited = 1;
}
#endif
// Before version 5.03, we were using a patched version of microlib with proper names
// This is the workaround that the microlib author suggested us
static int n = 0;
Expand Down
105 changes: 81 additions & 24 deletions platform/source/mbed_sdk_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,20 @@
#include "cmsis.h"
#include "hal/us_ticker_api.h"

/* This startup is for mbed 2 baremetal. There is no config for RTOS for mbed 2,
* therefore we protect this file with MBED_CONF_RTOS_PRESENT
* Note: The new consolidated started for mbed OS is in rtos/mbed_boot code file.
/* This startup is for baremetal. There is no RTOS in baremetal,
* therefore we protect this file with MBED_CONF_RTOS_PRESENT.
* Note: The start-up code for mbed OS is in rtos/source/TARGET_CORTEX/mbed_boot code file.
*/
#if !defined(MBED_CONF_RTOS_PRESENT)

/* Heap limits - only used if set */
extern unsigned char *mbed_heap_start;
extern uint32_t mbed_heap_size;

/* Stack limits */
unsigned char *mbed_stack_isr_start = 0;
uint32_t mbed_stack_isr_size = 0;

/* mbed_main is a function that is called before main()
* mbed_sdk_init() is also a function that is called before main(), but unlike
* mbed_main(), it is not meant for user code, but for the SDK itself to perform
Expand Down Expand Up @@ -67,62 +75,111 @@ void mbed_copy_nvic(void)
#endif /* !defined(__CORTEX_M0) && !defined(__CORTEX_A9) */
}

void mbed_init(void)
{
mbed_copy_nvic();
mbed_sdk_init();
#if DEVICE_USTICKER && MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
us_ticker_init();
#endif
}

/* Toolchain specific main code */

#if defined (__ARMCC_VERSION)

int $Super$$main(void);
void $Sub$$__cpp_initialize__aeabi_(void);
void $Super$$__cpp_initialize__aeabi_(void);
void $Sub$$__cpp_initialize__aeabi_(void)
{
/* This should invoke C++ initializers but we keep
* this empty and invoke them in mbed_toolchain_init.
*/
}

int $Sub$$main(void)
void mbed_toolchain_init()
{
mbed_main();
mbed_error_initialize();
return $Super$$main();
/* Run the C++ global object constructors */
$Super$$__cpp_initialize__aeabi_();
}

void _platform_post_stackheap_init(void)
{
mbed_copy_nvic();
mbed_sdk_init();
#if DEVICE_USTICKER && MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
us_ticker_init();
mbed_init();
}

extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[];

int $Super$$main(void);
int $Sub$$main(void)
{
mbed_stack_isr_start = (unsigned char *) Image$$ARM_LIB_STACK$$ZI$$Base;
mbed_stack_isr_size = (uint32_t) Image$$ARM_LIB_STACK$$ZI$$Length;
mbed_heap_start = (unsigned char *) Image$$ARM_LIB_HEAP$$ZI$$Base;
mbed_heap_size = (uint32_t) Image$$ARM_LIB_HEAP$$ZI$$Length;

#if defined(__MICROLIB)
// post stack/heap is not active in microlib
// so call the function explicitly.
_platform_post_stackheap_init();
#endif
mbed_toolchain_init();
mbed_main();
return $Super$$main();
}




//Define an empty os_cb_sections to remove a RTX warning when building with no RTOS due
//to the --keep=os_cb_sections linker option
const uint32_t os_cb_sections[] __attribute__((section(".rodata"))) = {};

#elif defined (__GNUC__)

extern uint32_t __StackLimit;
extern uint32_t __StackTop;
extern uint32_t __end__;
extern uint32_t __HeapLimit;

extern int __real_main(void);

void software_init_hook(void)
{
mbed_copy_nvic();
mbed_sdk_init();
#if DEVICE_USTICKER && MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
us_ticker_init();
#endif
mbed_stack_isr_start = (unsigned char *) &__StackLimit;
mbed_stack_isr_size = (uint32_t) &__StackTop - (uint32_t) &__StackLimit;
mbed_heap_start = (unsigned char *) &__end__;
mbed_heap_size = (uint32_t) &__HeapLimit - (uint32_t) &__end__;

mbed_init();
software_init_hook_rtos();
}


int __wrap_main(void)
{
mbed_main();
mbed_error_initialize();
return __real_main();
}

#elif defined (__ICCARM__)

int __low_level_init(void)
/* Defined by linker script */
#pragma section="CSTACK"
#pragma section="HEAP"

void __mbed_init(void)
{
mbed_copy_nvic();
#if DEVICE_USTICKER && MBED_CONF_TARGET_INIT_US_TICKER_AT_BOOT
us_ticker_init();
#endif
return 1;
mbed_heap_start = (unsigned char *)__section_begin("HEAP");
mbed_heap_size = (uint32_t)__section_size("HEAP");

mbed_stack_isr_start = (unsigned char *)__section_begin("CSTACK");
mbed_stack_isr_size = (uint32_t)__section_size("CSTACK");

mbed_init();
}

#endif
Expand Down