Skip to content

Commit a322327

Browse files
mprsedeepikabhavnani
authored andcommitted
Use 2-region memory model in ARM rtos-less builds.
The following commits: ARMmbed#8039, ARMmbed#9092 added Boot/ISR stack definition to all scatter files (ARM_LIB_STACK). This has changed memory model for RTOS-less builds to 2-region memory model and caused failure in case of rtos less builds. This PR defines valid heap/stack regions for rtos-less builds.
1 parent f4e6db2 commit a322327

File tree

1 file changed

+60
-10
lines changed

1 file changed

+60
-10
lines changed

platform/mbed_retarget.cpp

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -905,24 +905,74 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
905905
return size;
906906
}
907907

908+
908909
// Do not compile this code for TFM secure target
909910
#if !defined(COMPONENT_SPE) || !defined(TARGET_TFM)
910911

911-
extern "C" char Image$$RW_IRAM1$$ZI$$Limit[];
912-
913-
extern "C" MBED_WEAK __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
914-
{
915-
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
916-
uint32_t sp_limit = __current_sp();
917-
918-
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
912+
#if defined(TARGET_NUVOTON) || defined(TARGET_RZ_A1XX)
913+
extern char Image$$ARM_LIB_HEAP$$ZI$$Base[];
914+
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
915+
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
916+
#define HEAP_BASE (Image$$ARM_LIB_HEAP$$ZI$$Base)
917+
#define HEAP_LIMIT (Image$$ARM_LIB_HEAP$$ZI$$Limit)
918+
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
919+
#else
920+
extern char Image$$RW_IRAM1$$ZI$$Limit[];
921+
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
922+
#define HEAP_BASE (Image$$RW_IRAM1$$ZI$$Limit)
923+
#define HEAP_LIMIT (Image$$ARM_LIB_STACK$$ZI$$Base)
924+
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
925+
#endif
919926

927+
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
920928
struct __initial_stackheap r;
921-
r.heap_base = zi_limit;
922-
r.heap_limit = sp_limit;
929+
r.heap_base = (uint32_t)HEAP_BASE;
930+
r.heap_limit = (uint32_t)HEAP_LIMIT;
923931
return r;
924932
}
925933

934+
#ifndef MBED_CONF_RTOS_PRESENT
935+
936+
/* The single region memory model would check stack collision at run time, verifying that
937+
* the heap pointer is underneath the stack pointer. With two-region memory model/RTOS-less or
938+
* multiple threads(stacks)/RTOS, the check gets meaningless and we must disable it. */
939+
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
940+
__asm(".global __use_two_region_memory\n\t");
941+
__asm(".global __use_no_semihosting\n\t");
942+
#else
943+
#pragma import(__use_two_region_memory)
944+
#endif
945+
946+
/* Fix __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP cannot co-exist in RTOS-less build
947+
*
948+
* According AN241 (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0241b/index.html),
949+
* __rt_entry has the following call sequence:
950+
* 1. _platform_pre_stackheap_init
951+
* 2. __user_setup_stackheap or setup the Stack Pointer (SP) by another method
952+
* 3. _platform_post_stackheap_init
953+
* 4. __rt_lib_init
954+
* 5. _platform_post_lib_init
955+
* 6. main()
956+
* 7. exit()
957+
*
958+
* Per our check, when __user_setup_stackheap and ARM_LIB_STACK/ARM_LIB_HEAP co-exist, neither
959+
* does __user_setup_stackheap get called and nor is ARM_LIB_HEAP used to get heap base/limit,
960+
* which are required to pass to __rt_lib_init later. To fix the issue, by subclass'ing
961+
* __rt_lib_init, heap base/limit are replaced with Image$$ARM_LIB_HEAP$$ZI$$Base/Limit if
962+
* ARM_LIB_HEAP region is defined in scatter file.
963+
*
964+
* The overriding __rt_lib_init is needed only for rtos-less code. For rtos code, __rt_entry is
965+
* overridden and the overriding __rt_lib_init here gets meaningless.
966+
*/
967+
extern "C" extern __value_in_regs struct __argc_argv $Super$$__rt_lib_init(unsigned heapbase, unsigned heaptop);
968+
969+
extern "C" __value_in_regs struct __argc_argv $Sub$$__rt_lib_init (unsigned heapbase, unsigned heaptop)
970+
{
971+
return $Super$$__rt_lib_init((unsigned)HEAP_BASE, (unsigned)HEAP_LIMIT);
972+
}
973+
974+
#endif
975+
926976
extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3)
927977
{
928978
return _mbed_user_setup_stackheap(R0, R1, R2, R3);

0 commit comments

Comments
 (0)