Skip to content

Commit d6624c0

Browse files
committed
RTX - init sequence (C++ array init) for Cortex-A version
This is an update to RTX kernel for Cortex-A version to allow c++ libc array init to be called after kernel start. Ref: #1730
1 parent 703aee4 commit d6624c0

File tree

2 files changed

+107
-35
lines changed

2 files changed

+107
-35
lines changed

hal/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_IAR/startup_RZA1H.s

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

3030
SECTION .intvec:CODE:NOROOT(2)
3131

32-
PUBLIC __vector
33-
PUBLIC __iar_program_start
32+
PUBLIC __vector_core_a9
33+
PUBLIC __RST_Handler
3434
PUBLIC Undefined_Handler
3535
EXTERN SWI_Handler
3636
PUBLIC Prefetch_Handler
@@ -52,7 +52,7 @@
5252
__iar_init$$done: ; The vector table is not needed
5353
; until after copy initialization is done
5454

55-
__vector: ; Make this a DATA label, so that stack usage
55+
__vector_core_a9: ; Make this a DATA label, so that stack usage
5656
; analysis doesn't consider it an uncalled fun
5757

5858
ARM
@@ -71,7 +71,7 @@ __vector: ; Make this a DATA label, so that stack usage
7171

7272
DATA
7373

74-
Reset_Addr: DCD __iar_program_start
74+
Reset_Addr: DCD __RST_Handler
7575
Undefined_Addr: DCD Undefined_Handler
7676
SWI_Addr: DCD SWI_Handler
7777
Prefetch_Addr: DCD Prefetch_Handler
@@ -94,15 +94,15 @@ FIQ_Addr: DCD FIQ_Handler
9494
EXTERN create_translation_table
9595
EXTERN SystemInit
9696
EXTERN InitMemorySubsystem
97-
EXTERN __cmain
98-
REQUIRE __vector
97+
EXTERN __iar_program_start
98+
REQUIRE __vector_core_a9
9999
EXTWEAK __iar_init_core
100100
EXTWEAK __iar_init_vfp
101101

102102

103103
ARM
104104

105-
__iar_program_start:
105+
__RST_Handler:
106106
?cstartup:
107107

108108

@@ -138,7 +138,7 @@ goToSleep:
138138
139139
140140
;; Set Vector Base Address Register (VBAR) to point to this application's vector table
141-
ldr r0, =__vector
141+
ldr r0, =__vector_core_a9
142142
mcr p15, 0, r0, c12, c0, 0
143143
144144
@@ -256,8 +256,8 @@ goToSleep:
256256

257257
;;; Continue to __cmain for C-level initialization.
258258

259-
FUNCALL __iar_program_start, __cmain
260-
B __cmain
259+
FUNCALL __RST_Handler, __iar_program_start
260+
B __iar_program_start
261261

262262

263263
ldr r0, sf_boot ;@ dummy to keep boot loader area

rtos/rtx/TARGET_CORTEX_A/RTX_CM_lib.h

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -395,18 +395,22 @@ void __iar_system_Mtxunlock(__iar_Rmtx *mutex)
395395
*---------------------------------------------------------------------------*/
396396

397397
/* Main Thread definition */
398-
extern int main (void);
398+
extern void pre_main (void);
399399
#ifdef __MBED_CMSIS_RTOS_CA9
400400
uint32_t os_thread_def_stack_main [(4 * OS_MAINSTKSIZE) / sizeof(uint32_t)];
401-
osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE, os_thread_def_stack_main };
401+
osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE, os_thread_def_stack_main };
402402
#else
403-
osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
403+
osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
404404
#endif
405405

406406
#if defined (__CC_ARM)
407407

408408
#ifdef __MICROLIB
409+
410+
int main(void);
409411
void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
412+
void $Super$$__cpp_initialize__aeabi_(void);
413+
410414
#if __TARGET_ARCH_ARM
411415
#pragma push
412416
#pragma arm
@@ -420,66 +424,134 @@ void _main_init (void) {
420424
#if __TARGET_ARCH_ARM
421425
#pragma pop
422426
#endif
427+
428+
void $Sub$$__cpp_initialize__aeabi_(void)
429+
{
430+
// this should invoke C++ initializers prior _main_init, we keep this empty and
431+
// invoke them after _main_init (=starts RTX kernel)
432+
}
433+
434+
void pre_main()
435+
{
436+
$Super$$__cpp_initialize__aeabi_();
437+
main();
438+
}
439+
423440
#else
441+
442+
void * armcc_heap_base;
443+
void * armcc_heap_top;
444+
445+
__asm void pre_main (void)
446+
{
447+
IMPORT __rt_lib_init
448+
IMPORT main
449+
IMPORT armcc_heap_base
450+
IMPORT armcc_heap_top
451+
452+
LDR R0,=armcc_heap_base
453+
LDR R1,=armcc_heap_top
454+
LDR R0,[R0]
455+
LDR R1,[R1]
456+
/* Save link register (keep 8 byte alignment with dummy R4) */
457+
PUSH {R4, LR}
458+
BL __rt_lib_init
459+
BL main
460+
/* Return to the thread destroy function.
461+
*/
462+
POP {R4, PC}
463+
ALIGN
464+
}
465+
424466
__asm void __rt_entry (void) {
425467

426468
IMPORT __user_setup_stackheap
427-
IMPORT __rt_lib_init
428469
IMPORT os_thread_def_main
470+
IMPORT armcc_heap_base
471+
IMPORT armcc_heap_top
429472
IMPORT osKernelInitialize
430473
IMPORT osKernelStart
431474
IMPORT osThreadCreate
432-
IMPORT exit
433475

434476
BL __user_setup_stackheap
435-
MOV R1,R2
436-
BL __rt_lib_init
477+
LDR R3,=armcc_heap_base
478+
LDR R4,=armcc_heap_top
479+
STR R0,[R3]
480+
STR R2,[R4]
437481
BL osKernelInitialize
438482
LDR R0,=os_thread_def_main
439483
MOVS R1,#0
440484
BL osThreadCreate
441485
BL osKernelStart
442-
BL exit
486+
/* osKernelStart should not return */
487+
B .
443488

444489
ALIGN
445490
}
446491
#endif
447492

448493
#elif defined (__GNUC__)
494+
extern void __libc_fini_array(void);
495+
extern void __libc_init_array (void);
496+
extern int main(int argc, char **argv);
497+
498+
void pre_main(void) {
499+
atexit(__libc_fini_array);
500+
__libc_init_array();
501+
main(0, NULL);
502+
}
449503

450504
__attribute__((naked)) void software_init_hook_rtos (void) {
451505
__asm (
452506
".syntax unified\n"
453507
".arm\n"
454-
"movs r0,#0\n"
455-
"movs r1,#0\n"
456-
"mov r4,r0\n"
457-
"mov r5,r1\n"
458-
"ldr r0,= __libc_fini_array\n"
459-
"bl atexit\n"
460-
"bl __libc_init_array\n"
461-
"mov r0,r4\n"
462-
"mov r1,r5\n"
463508
"bl osKernelInitialize\n"
464509
"ldr r0,=os_thread_def_main\n"
465510
"movs r1,#0\n"
466511
"bl osThreadCreate\n"
467512
"bl osKernelStart\n"
468-
"bl exit\n"
513+
/* osKernelStart should not return */
514+
"B .\n"
469515
);
470516
}
471517

472518
#elif defined (__ICCARM__)
519+
extern void* __vector_core_a9;
520+
extern int __low_level_init(void);
521+
extern void __iar_data_init3(void);
522+
extern __weak void __iar_init_core( void );
523+
extern __weak void __iar_init_vfp( void );
524+
extern void __iar_dynamic_initialization(void);
525+
extern void mbed_sdk_init(void);
526+
static uint8_t low_level_init_needed;
527+
528+
void pre_main(void) {
529+
if (low_level_init_needed) {
530+
__iar_dynamic_initialization();
531+
}
532+
main();
533+
}
473534

474-
extern void exit(int arg);
475-
476-
void mbed_main(void) {
477-
int a;
478-
535+
#pragma required=__vector_core_a9
536+
void __iar_program_start( void )
537+
{
538+
__iar_init_core();
539+
__iar_init_vfp();
540+
541+
uint8_t low_level_init_needed_local;
542+
543+
low_level_init_needed_local = __low_level_init();
544+
if (low_level_init_needed_local) {
545+
__iar_data_init3();
546+
mbed_sdk_init();
547+
}
548+
/* Store in a global variable after RAM has been initialized */
549+
low_level_init_needed = low_level_init_needed_local;
479550
osKernelInitialize();
480551
osThreadCreate(&os_thread_def_main, NULL);
481-
a = osKernelStart();
482-
exit(a);
552+
osKernelStart();
553+
/* osKernelStart should not return */
554+
while (1);
483555
}
484556

485557
#endif

0 commit comments

Comments
 (0)