diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct index 72a6efafe2..76653b8e6f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct @@ -126,11 +126,13 @@ LR_IROM1 m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; lo RW_m_data m_data_start m_data_size { ; RW data .ANY (+RW +ZI) } - RW_m_data_2 m_data_2_start m_data_2_size-Stack_Size-Heap_Size { ; RW data + RW_m_data_2 m_data_2_start m_data_2_size { ; RW data .ANY (+RW +ZI) } RW_IRAM1 ImageLimit(RW_m_data_2) { ; Heap region growing up } + ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (m_data_2_start + m_data_2_size - Stack_Size - AlignExpr(ImageLimit(RW_IRAM1), 16)) { + } ARM_LIB_STACK m_data_2_start+m_data_2_size EMPTY -Stack_Size { ; Stack region growing down } } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/sys.cpp b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/sys.cpp new file mode 100644 index 0000000000..604ba18369 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/sys.cpp @@ -0,0 +1,86 @@ + /* + * Copyright (c) 2019-2019 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Setup a fixed single stack/heap memory model, + * between the top of the RW/ZI region and the stackpointer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#include +#endif + +#include +#include + +extern char Image$$ARM_LIB_STACK$$ZI$$Limit[]; +extern char Image$$ARM_LIB_HEAP$$Base[]; +extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[]; +extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) { + + struct __initial_stackheap r; + r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base; + r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit; + return r; +} + +#if !defined(MBED_CONF_RTOS_PRESENT) || !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 __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop); + +__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop) +{ + return $Super$$__rt_lib_init((unsigned) Image$$ARM_LIB_HEAP$$Base, (unsigned) Image$$ARM_LIB_HEAP$$ZI$$Limit); +} + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/targets/TARGET_Freescale/mbed_rtx.h b/targets/TARGET_Freescale/mbed_rtx.h index 507c042e2e..172dce07a6 100644 --- a/targets/TARGET_Freescale/mbed_rtx.h +++ b/targets/TARGET_Freescale/mbed_rtx.h @@ -17,6 +17,8 @@ #ifndef MBED_MBED_RTX_H #define MBED_MBED_RTX_H +#include + #if defined(TARGET_K20D50M) #ifndef INITIAL_SP @@ -87,6 +89,16 @@ #ifndef INITIAL_SP #define INITIAL_SP (0x20030000UL) +#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) +extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[]; +extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[]; +extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; +extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[]; +#define HEAP_START ((unsigned char*) Image$$ARM_LIB_HEAP$$ZI$$Base) +#define HEAP_SIZE ((uint32_t) Image$$ARM_LIB_HEAP$$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) +#endif #endif #elif defined(TARGET_SDT64B)