diff --git a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp index 91c1129cdb..e4c88a3c0f 100644 --- a/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/heap_and_stack/main.cpp @@ -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 @@ -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) @@ -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. * @@ -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); @@ -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); @@ -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 @@ -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 @@ -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"); } @@ -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) }; @@ -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 diff --git a/platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S b/platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S index 0da55009b3..3cfbeacd63 100644 --- a/platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S +++ b/platform/source/TARGET_CORTEX_M/TOOLCHAIN_IAR/cmain.S @@ -46,6 +46,7 @@ EXTERN exit EXTERN __iar_dynamic_initialization EXTERN mbed_sdk_init + EXTWEAK __mbed_init EXTERN mbed_main EXTERN SystemInit @@ -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 diff --git a/platform/source/mbed_retarget.cpp b/platform/source/mbed_retarget.cpp index cee0c57436..42d5c83c43 100644 --- a/platform/source/mbed_retarget.cpp +++ b/platform/source/mbed_retarget.cpp @@ -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; diff --git a/platform/source/mbed_sdk_boot.c b/platform/source/mbed_sdk_boot.c index b9f8922f91..9dc8141558 100644 --- a/platform/source/mbed_sdk_boot.c +++ b/platform/source/mbed_sdk_boot.c @@ -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 @@ -67,20 +75,7 @@ void mbed_copy_nvic(void) #endif /* !defined(__CORTEX_M0) && !defined(__CORTEX_A9) */ } -/* Toolchain specific main code */ - -#if defined (__ARMCC_VERSION) - -int $Super$$main(void); - -int $Sub$$main(void) -{ - mbed_main(); - mbed_error_initialize(); - return $Super$$main(); -} - -void _platform_post_stackheap_init(void) +void mbed_init(void) { mbed_copy_nvic(); mbed_sdk_init(); @@ -88,21 +83,78 @@ void _platform_post_stackheap_init(void) us_ticker_init(); #endif } + +/* Toolchain specific main code */ + +#if defined (__ARMCC_VERSION) + +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. + */ +} + +void mbed_toolchain_init() +{ + /* Run the C++ global object constructors */ + $Super$$__cpp_initialize__aeabi_(); +} + +void _platform_post_stackheap_init(void) +{ + 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(); } @@ -110,19 +162,24 @@ void software_init_hook(void) 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