Skip to content

Commit f2accfd

Browse files
committed
Use 2-region memory model in ARM rtos-less builds.
The following commits: #8039, #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 cc94690 commit f2accfd

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

platform/mbed_retarget.cpp

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -904,21 +904,70 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
904904
return size;
905905
}
906906

907-
extern "C" char Image$$RW_IRAM1$$ZI$$Limit[];
908-
909-
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)
910-
{
911-
uint32_t zi_limit = (uint32_t)Image$$RW_IRAM1$$ZI$$Limit;
912-
uint32_t sp_limit = __current_sp();
913-
914-
zi_limit = (zi_limit + 7) & ~0x7; // ensure zi_limit is 8-byte aligned
907+
#if defined(TARGET_NUVOTON) || defined(TARGET_RZ_A1XX)
908+
extern char Image$$ARM_LIB_HEAP$$ZI$$Base[];
909+
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
910+
extern char Image$$ARM_LIB_HEAP$$ZI$$Limit[];
911+
#define HEAP_BASE (Image$$ARM_LIB_HEAP$$ZI$$Base)
912+
#define HEAP_LIMIT (Image$$ARM_LIB_HEAP$$ZI$$Limit)
913+
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
914+
#else
915+
extern char Image$$RW_IRAM1$$ZI$$Limit[];
916+
extern char Image$$ARM_LIB_STACK$$ZI$$Base[];
917+
#define HEAP_BASE (Image$$RW_IRAM1$$ZI$$Limit)
918+
#define HEAP_LIMIT (Image$$ARM_LIB_STACK$$ZI$$Base)
919+
#define STACK_BASE (Image$$ARM_LIB_STACK$$ZI$$Base)
920+
#endif
915921

922+
extern __value_in_regs struct __initial_stackheap _mbed_user_setup_stackheap(uint32_t R0, uint32_t R1, uint32_t R2, uint32_t R3) {
916923
struct __initial_stackheap r;
917-
r.heap_base = zi_limit;
918-
r.heap_limit = sp_limit;
924+
r.heap_base = (uint32_t)HEAP_BASE;
925+
r.heap_limit = (uint32_t)HEAP_LIMIT;
919926
return r;
920927
}
921928

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

0 commit comments

Comments
 (0)