@@ -195,8 +195,8 @@ __attribute__((used)) void _mutex_release (OS_ID *mutex) {
195195 *---------------------------------------------------------------------------*/
196196
197197/* Main Thread definition */
198- extern int main (void );
199- osThreadDef_t os_thread_def_main = {(os_pthread )main , osPriorityNormal , 0 , NULL };
198+ extern void pre_main (void );
199+ osThreadDef_t os_thread_def_main = {(os_pthread )pre_main , osPriorityNormal , 0 , NULL };
200200
201201// This define should be probably moved to the CMSIS layer
202202
@@ -230,16 +230,57 @@ void set_main_stack(void) {
230230
231231#if defined (__CC_ARM )
232232#ifdef __MICROLIB
233+
234+ int main (void );
233235void _main_init (void ) __attribute__((section (".ARM.Collect$$$$000000FF" )));
236+ void $Super$$__cpp_initialize__aeabi_ (void );
237+
234238void _main_init (void ) {
235239 osKernelInitialize ();
236240 set_main_stack ();
237241 osThreadCreate (& os_thread_def_main , NULL );
238242 osKernelStart ();
239243 for (;;);
240244}
245+
246+ void $Sub$$__cpp_initialize__aeabi_ (void )
247+ {
248+ // this should invoke C++ initializers prior _main_init, we keep this empty and
249+ // invoke them after _main_init (=starts RTX kernel)
250+ }
251+
252+ void pre_main ()
253+ {
254+ $Super$$__cpp_initialize__aeabi_ ();
255+ main ();
256+ }
257+
241258#else
242259
260+ void * armcc_heap_base ;
261+ void * armcc_heap_top ;
262+
263+ __asm void pre_main (void )
264+ {
265+ IMPORT __rt_lib_init
266+ IMPORT main
267+ IMPORT armcc_heap_base
268+ IMPORT armcc_heap_top
269+
270+ LDR R0 ,= armcc_heap_base
271+ LDR R1 ,= armcc_heap_top
272+ LDR R0 , [R0 ]
273+ LDR R1 , [R1 ]
274+ /* Save link register (keep 8 byte alignment with dummy R4) */
275+ PUSH {R4 , LR }
276+ BL __rt_lib_init
277+ BL main
278+ /* Return to the thread destroy function.
279+ */
280+ POP {R4 , PC }
281+ ALIGN
282+ }
283+
243284/* The single memory model is checking for stack collision at run time, verifing
244285 that the heap pointer is underneath the stack pointer.
245286
@@ -251,71 +292,109 @@ void _main_init (void) {
251292__asm void __rt_entry (void ) {
252293
253294 IMPORT __user_setup_stackheap
254- IMPORT __rt_lib_init
295+ IMPORT armcc_heap_base
296+ IMPORT armcc_heap_top
255297 IMPORT os_thread_def_main
256298 IMPORT osKernelInitialize
257299 IMPORT set_main_stack
258300 IMPORT osKernelStart
259301 IMPORT osThreadCreate
260- IMPORT exit
261302
303+ /* __user_setup_stackheap returns:
304+ * - Heap base in r0 (if the program uses the heap).
305+ * - Stack base in sp.
306+ * - Heap limit in r2 (if the program uses the heap and uses two-region memory).
307+ *
308+ * More info can be found in:
309+ * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide
310+ */
262311 BL __user_setup_stackheap
263- MOV R1 ,R2
264- BL __rt_lib_init
312+ LDR R3 ,= armcc_heap_base
313+ LDR R4 ,= armcc_heap_top
314+ STR R0 , [R3 ]
315+ STR R2 , [R4 ]
265316 BL osKernelInitialize
266317 BL set_main_stack
267318 LDR R0 ,= os_thread_def_main
268319 MOVS R1 ,#0
269320 BL osThreadCreate
270321 BL osKernelStart
271- BL exit
322+ /* osKernelStart should not return */
323+ B .
272324
273325 ALIGN
274326}
327+
275328#endif
276329
277330#elif defined (__GNUC__ )
278331
332+ extern void __libc_fini_array (void );
333+ extern void __libc_init_array (void );
334+ extern int main (int argc , char * * argv );
335+
336+ void pre_main (void ) {
337+ atexit (__libc_fini_array );
338+ __libc_init_array ();
339+ main (0 , NULL );
340+ }
341+
279342__attribute__((naked )) void software_init_hook (void ) {
280343 __asm (
281344 ".syntax unified\n"
282345 ".thumb\n"
283- "movs r0,#0\n"
284- "movs r1,#0\n"
285- "mov r8,r0\n"
286- "mov r9,r1\n"
287- "ldr r0,= __libc_fini_array\n"
288- "bl atexit\n"
289- "bl __libc_init_array\n"
290- "mov r0,r8\n"
291- "mov r1,r9\n"
292346 "bl osKernelInitialize\n"
293347 "bl set_main_stack\n"
294348 "ldr r0,=os_thread_def_main\n"
295349 "movs r1,#0\n"
296350 "bl osThreadCreate\n"
297351 "bl osKernelStart\n"
298- "bl exit\n"
352+ /* osKernelStart should not return */
353+ "B .\n"
299354 );
300355}
301356
302357#elif defined (__ICCARM__)
303358
359+ extern void * __vector_table ;
304360extern int __low_level_init (void );
305361extern void __iar_data_init3 (void );
362+ extern __weak void __iar_init_core ( void );
363+ extern __weak void __iar_init_vfp ( void );
364+ extern void __iar_dynamic_initialization (void );
365+ extern void mbed_sdk_init (void );
306366extern void exit (int arg );
307367
308- __noreturn __stackless void __cmain (void ) {
309- int a ;
368+ static uint8_t low_level_init_needed ;
369+
370+ void pre_main (void ) {
371+ if (low_level_init_needed ) {
372+ __iar_dynamic_initialization ();
373+ }
374+ main ();
375+ }
376+
377+ #pragma required=__vector_table
378+ void __iar_program_start ( void )
379+ {
380+ __iar_init_core ();
381+ __iar_init_vfp ();
382+
383+ uint8_t low_level_init_needed_local ;
310384
311- if (__low_level_init () != 0 ) {
385+ low_level_init_needed_local = __low_level_init ();
386+ if (low_level_init_needed_local ) {
312387 __iar_data_init3 ();
388+ mbed_sdk_init ();
313389 }
390+ /* Store in a global variable after RAM has been initialized */
391+ low_level_init_needed = low_level_init_needed_local ;
314392 osKernelInitialize ();
315393 set_main_stack ();
316394 osThreadCreate (& os_thread_def_main , NULL );
317- a = osKernelStart ();
318- exit (a );
395+ osKernelStart ();
396+ /* osKernelStart should not return */
397+ while (1 );
319398}
320399
321400#endif
0 commit comments