Skip to content

Commit 292f1a1

Browse files
committed
K64/ARM: Update to 2-region model for HEAP and Stack Memory
1 parent cc94690 commit 292f1a1

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/device/TOOLCHAIN_ARM_STD/MK64FN1M0xxx12.sct

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,13 @@ LR_IROM1 m_interrupts_start m_text_start+m_text_size-m_interrupts_start { ; lo
126126
RW_m_data m_data_start m_data_size { ; RW data
127127
.ANY (+RW +ZI)
128128
}
129-
RW_m_data_2 m_data_2_start m_data_2_size-Stack_Size-Heap_Size { ; RW data
129+
RW_m_data_2 m_data_2_start m_data_2_size { ; RW data
130130
.ANY (+RW +ZI)
131131
}
132132
RW_IRAM1 ImageLimit(RW_m_data_2) { ; Heap region growing up
133133
}
134+
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (m_data_2_start + m_data_2_size - Stack_Size - AlignExpr(ImageLimit(RW_IRAM1), 16)) {
135+
}
134136
ARM_LIB_STACK m_data_2_start+m_data_2_size EMPTY -Stack_Size { ; Stack region growing down
135137
}
136138
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2019-2019 ARM Limited. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
* Licensed under the Apache License, Version 2.0 (the License); you may
5+
* not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* Setup a fixed single stack/heap memory model,
17+
* between the top of the RW/ZI region and the stackpointer
18+
*/
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
25+
#include <arm_compat.h>
26+
#endif
27+
28+
#include <rt_misc.h>
29+
#include <stdint.h>
30+
31+
extern char Image$$ARM_LIB_STACK$$ZI$$Limit[];
32+
extern char Image$$ARM_LIB_HEAP$$Base[];
33+
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
34+
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
35+
36+
struct __initial_stackheap r;
37+
r.heap_base = (uint32_t)Image$$ARM_LIB_HEAP$$Base;
38+
r.heap_limit = (uint32_t)Image$$ARM_LIB_HEAP$$ZI$$Limit;
39+
return r;
40+
}
41+
42+
#if !defined(MBED_CONF_RTOS_PRESENT) || !MBED_CONF_RTOS_PRESENT
43+
44+
/* The single region memory model would check stack collision at run time, verifying that
45+
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
46+
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
47+
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
48+
__asm(".global __use_two_region_memory\n\t");
49+
__asm(".global __use_no_semihosting\n\t");
50+
#else
51+
#pragma import(__use_two_region_memory)
52+
#endif
53+
54+
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
55+
*
56+
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
57+
* __rt_entry has the following call sequence:
58+
* 1. _platform_pre_stackheap_init
59+
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
60+
* 3. _platform_post_stackheap_init
61+
* 4. __rt_lib_init
62+
* 5. _platform_post_lib_init
63+
* 6. main()
64+
* 7. exit()
65+
*
66+
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
67+
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
68+
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
69+
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
70+
* ARM_LIB_HEAP region is defined in scatter file.
71+
*
72+
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
73+
* overridden and the overriding __rt_lib_init here gets meaningless.
74+
*/
75+
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
76+
77+
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
78+
{
79+
return $Super$$__rt_lib_init((unsigned) Image$$ARM_LIB_HEAP$$Base, (unsigned) Image$$ARM_LIB_HEAP$$ZI$$Limit);
80+
}
81+
82+
#endif
83+
84+
#ifdef __cplusplus
85+
}
86+
#endif

targets/TARGET_Freescale/mbed_rtx.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef MBED_MBED_RTX_H
1818
#define MBED_MBED_RTX_H
1919

20+
#include <stdint.h>
21+
2022
#if defined(TARGET_K20D50M)
2123

2224
#ifndef INITIAL_SP
@@ -87,6 +89,16 @@
8789

8890
#ifndef INITIAL_SP
8991
#define INITIAL_SP (0x20030000UL)
92+
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
93+
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Base[];
94+
extern uint32_t Image$$ARM_LIB_HEAP$$ZI$$Length[];
95+
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
96+
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[];
97+
#define HEAP_START ((unsigned char*) Image$$ARM_LIB_HEAP$$ZI$$Base)
98+
#define HEAP_SIZE ((uint32_t) Image$$ARM_LIB_HEAP$$ZI$$Length)
99+
#define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base)
100+
#define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length)
101+
#endif
90102
#endif
91103

92104
#elif defined(TARGET_SDT64B)

0 commit comments

Comments
 (0)