Skip to content

Commit caf06e8

Browse files
committed
[Nuvoton] Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
1 parent d6ae30a commit caf06e8

File tree

1 file changed

+42
-0
lines changed
  • targets/TARGET_NUVOTON/TOOLCHAIN_ARM

1 file changed

+42
-0
lines changed

targets/TARGET_NUVOTON/TOOLCHAIN_ARM/sys.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,48 @@ extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uin
2727
return r;
2828
}
2929

30+
#if !defined(MBED_CONF_RTOS_PRESENT) || !MBED_CONF_RTOS_PRESENT
31+
32+
/* The single region memory model would check stack collision at run time, verifying that
33+
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
34+
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
35+
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
36+
__asm(".global __use_two_region_memory\n\t");
37+
__asm(".global __use_no_semihosting\n\t");
38+
#else
39+
#pragma import(__use_two_region_memory)
40+
#endif
41+
42+
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
43+
*
44+
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
45+
* __rt_entry has the following call sequence:
46+
* 1. _platform_pre_stackheap_init
47+
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
48+
* 3. _platform_post_stackheap_init
49+
* 4. __rt_lib_init
50+
* 5. _platform_post_lib_init
51+
* 6. main()
52+
* 7. exit()
53+
*
54+
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
55+
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
56+
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
57+
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
58+
* ARM_LIB_HEAP region is defined in scatter file.
59+
*
60+
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
61+
* overridden and the overriding __rt_lib_init here gets meaningless.
62+
*/
63+
extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
64+
65+
__value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
66+
{
67+
return $Super$$__rt_lib_init((unsigned) Image$$ARM_LIB_HEAP$$Base, (unsigned) Image$$ARM_LIB_HEAP$$ZI$$Limit);
68+
}
69+
70+
#endif
71+
3072
#ifdef __cplusplus
3173
}
3274
#endif

0 commit comments

Comments
 (0)