1*10465441SEvalZero /*
2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero *
4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero *
6*10465441SEvalZero * Change Logs:
7*10465441SEvalZero * Date Author Notes
8*10465441SEvalZero * 2012-09-20 Bernard Change the name to components.c
9*10465441SEvalZero * And all components related header files.
10*10465441SEvalZero * 2012-12-23 Bernard fix the pthread initialization issue.
11*10465441SEvalZero * 2013-06-23 Bernard Add the init_call for components initialization.
12*10465441SEvalZero * 2013-07-05 Bernard Remove initialization feature for MS VC++ compiler
13*10465441SEvalZero * 2015-02-06 Bernard Remove the MS VC++ support and move to the kernel
14*10465441SEvalZero * 2015-05-04 Bernard Rename it to components.c because compiling issue
15*10465441SEvalZero * in some IDEs.
16*10465441SEvalZero * 2015-07-29 Arda.Fu Add support to use RT_USING_USER_MAIN with IAR
17*10465441SEvalZero * 2018-11-22 Jesven Add secondary cpu boot up
18*10465441SEvalZero */
19*10465441SEvalZero
20*10465441SEvalZero #include <rthw.h>
21*10465441SEvalZero #include <rtthread.h>
22*10465441SEvalZero
23*10465441SEvalZero #ifdef RT_USING_USER_MAIN
24*10465441SEvalZero #ifndef RT_MAIN_THREAD_STACK_SIZE
25*10465441SEvalZero #define RT_MAIN_THREAD_STACK_SIZE 2048
26*10465441SEvalZero #endif
27*10465441SEvalZero #ifndef RT_MAIN_THREAD_PRIORITY
28*10465441SEvalZero #define RT_MAIN_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 3)
29*10465441SEvalZero #endif
30*10465441SEvalZero #endif
31*10465441SEvalZero
32*10465441SEvalZero #ifdef RT_USING_COMPONENTS_INIT
33*10465441SEvalZero /*
34*10465441SEvalZero * Components Initialization will initialize some driver and components as following
35*10465441SEvalZero * order:
36*10465441SEvalZero * rti_start --> 0
37*10465441SEvalZero * BOARD_EXPORT --> 1
38*10465441SEvalZero * rti_board_end --> 1.end
39*10465441SEvalZero *
40*10465441SEvalZero * DEVICE_EXPORT --> 2
41*10465441SEvalZero * COMPONENT_EXPORT --> 3
42*10465441SEvalZero * FS_EXPORT --> 4
43*10465441SEvalZero * ENV_EXPORT --> 5
44*10465441SEvalZero * APP_EXPORT --> 6
45*10465441SEvalZero *
46*10465441SEvalZero * rti_end --> 6.end
47*10465441SEvalZero *
48*10465441SEvalZero * These automatically initialization, the driver or component initial function must
49*10465441SEvalZero * be defined with:
50*10465441SEvalZero * INIT_BOARD_EXPORT(fn);
51*10465441SEvalZero * INIT_DEVICE_EXPORT(fn);
52*10465441SEvalZero * ...
53*10465441SEvalZero * INIT_APP_EXPORT(fn);
54*10465441SEvalZero * etc.
55*10465441SEvalZero */
rti_start(void)56*10465441SEvalZero static int rti_start(void)
57*10465441SEvalZero {
58*10465441SEvalZero return 0;
59*10465441SEvalZero }
60*10465441SEvalZero INIT_EXPORT(rti_start, "0");
61*10465441SEvalZero
rti_board_start(void)62*10465441SEvalZero static int rti_board_start(void)
63*10465441SEvalZero {
64*10465441SEvalZero return 0;
65*10465441SEvalZero }
66*10465441SEvalZero INIT_EXPORT(rti_board_start, "0.end");
67*10465441SEvalZero
rti_board_end(void)68*10465441SEvalZero static int rti_board_end(void)
69*10465441SEvalZero {
70*10465441SEvalZero return 0;
71*10465441SEvalZero }
72*10465441SEvalZero INIT_EXPORT(rti_board_end, "1.end");
73*10465441SEvalZero
rti_end(void)74*10465441SEvalZero static int rti_end(void)
75*10465441SEvalZero {
76*10465441SEvalZero return 0;
77*10465441SEvalZero }
78*10465441SEvalZero INIT_EXPORT(rti_end, "6.end");
79*10465441SEvalZero
80*10465441SEvalZero /**
81*10465441SEvalZero * RT-Thread Components Initialization for board
82*10465441SEvalZero */
rt_components_board_init(void)83*10465441SEvalZero void rt_components_board_init(void)
84*10465441SEvalZero {
85*10465441SEvalZero #if RT_DEBUG_INIT
86*10465441SEvalZero int result;
87*10465441SEvalZero const struct rt_init_desc *desc;
88*10465441SEvalZero for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
89*10465441SEvalZero {
90*10465441SEvalZero rt_kprintf("initialize %s", desc->fn_name);
91*10465441SEvalZero result = desc->fn();
92*10465441SEvalZero rt_kprintf(":%d done\n", result);
93*10465441SEvalZero }
94*10465441SEvalZero #else
95*10465441SEvalZero const init_fn_t *fn_ptr;
96*10465441SEvalZero
97*10465441SEvalZero for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
98*10465441SEvalZero {
99*10465441SEvalZero (*fn_ptr)();
100*10465441SEvalZero }
101*10465441SEvalZero #endif
102*10465441SEvalZero }
103*10465441SEvalZero
104*10465441SEvalZero /**
105*10465441SEvalZero * RT-Thread Components Initialization
106*10465441SEvalZero */
rt_components_init(void)107*10465441SEvalZero void rt_components_init(void)
108*10465441SEvalZero {
109*10465441SEvalZero #if RT_DEBUG_INIT
110*10465441SEvalZero int result;
111*10465441SEvalZero const struct rt_init_desc *desc;
112*10465441SEvalZero
113*10465441SEvalZero rt_kprintf("do components initialization.\n");
114*10465441SEvalZero for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++)
115*10465441SEvalZero {
116*10465441SEvalZero rt_kprintf("initialize %s", desc->fn_name);
117*10465441SEvalZero result = desc->fn();
118*10465441SEvalZero rt_kprintf(":%d done\n", result);
119*10465441SEvalZero }
120*10465441SEvalZero #else
121*10465441SEvalZero const init_fn_t *fn_ptr;
122*10465441SEvalZero
123*10465441SEvalZero for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
124*10465441SEvalZero {
125*10465441SEvalZero (*fn_ptr)();
126*10465441SEvalZero }
127*10465441SEvalZero #endif
128*10465441SEvalZero }
129*10465441SEvalZero
130*10465441SEvalZero #ifdef RT_USING_USER_MAIN
131*10465441SEvalZero
132*10465441SEvalZero void rt_application_init(void);
133*10465441SEvalZero void rt_hw_board_init(void);
134*10465441SEvalZero int rtthread_startup(void);
135*10465441SEvalZero
136*10465441SEvalZero #if defined(__CC_ARM) || defined(__CLANG_ARM)
137*10465441SEvalZero extern int $Super$$main(void);
138*10465441SEvalZero /* re-define main function */
$Sub$$main(void)139*10465441SEvalZero int $Sub$$main(void)
140*10465441SEvalZero {
141*10465441SEvalZero rt_hw_interrupt_disable();
142*10465441SEvalZero rtthread_startup();
143*10465441SEvalZero return 0;
144*10465441SEvalZero }
145*10465441SEvalZero #elif defined(__ICCARM__)
146*10465441SEvalZero extern int main(void);
147*10465441SEvalZero /* __low_level_init will auto called by IAR cstartup */
148*10465441SEvalZero extern void __iar_data_init3(void);
__low_level_init(void)149*10465441SEvalZero int __low_level_init(void)
150*10465441SEvalZero {
151*10465441SEvalZero // call IAR table copy function.
152*10465441SEvalZero __iar_data_init3();
153*10465441SEvalZero rt_hw_interrupt_disable();
154*10465441SEvalZero rtthread_startup();
155*10465441SEvalZero return 0;
156*10465441SEvalZero }
157*10465441SEvalZero #elif defined(__GNUC__)
158*10465441SEvalZero extern int main(void);
159*10465441SEvalZero /* Add -eentry to arm-none-eabi-gcc argument */
entry(void)160*10465441SEvalZero int entry(void)
161*10465441SEvalZero {
162*10465441SEvalZero rt_hw_interrupt_disable();
163*10465441SEvalZero rtthread_startup();
164*10465441SEvalZero return 0;
165*10465441SEvalZero }
166*10465441SEvalZero #endif
167*10465441SEvalZero
168*10465441SEvalZero #ifndef RT_USING_HEAP
169*10465441SEvalZero /* if there is not enable heap, we should use static thread and stack. */
170*10465441SEvalZero ALIGN(8)
171*10465441SEvalZero static rt_uint8_t main_stack[RT_MAIN_THREAD_STACK_SIZE];
172*10465441SEvalZero struct rt_thread main_thread;
173*10465441SEvalZero #endif
174*10465441SEvalZero
175*10465441SEvalZero /* the system main thread */
main_thread_entry(void * parameter)176*10465441SEvalZero void main_thread_entry(void *parameter)
177*10465441SEvalZero {
178*10465441SEvalZero extern int main(void);
179*10465441SEvalZero extern int $Super$$main(void);
180*10465441SEvalZero
181*10465441SEvalZero /* RT-Thread components initialization */
182*10465441SEvalZero rt_components_init();
183*10465441SEvalZero
184*10465441SEvalZero #ifdef RT_USING_SMP
185*10465441SEvalZero rt_hw_secondary_cpu_up();
186*10465441SEvalZero #endif
187*10465441SEvalZero /* invoke system main function */
188*10465441SEvalZero #if defined(__CC_ARM) || defined(__CLANG_ARM)
189*10465441SEvalZero $Super$$main(); /* for ARMCC. */
190*10465441SEvalZero #elif defined(__ICCARM__) || defined(__GNUC__)
191*10465441SEvalZero main();
192*10465441SEvalZero #endif
193*10465441SEvalZero }
194*10465441SEvalZero
rt_application_init(void)195*10465441SEvalZero void rt_application_init(void)
196*10465441SEvalZero {
197*10465441SEvalZero rt_thread_t tid;
198*10465441SEvalZero
199*10465441SEvalZero #ifdef RT_USING_HEAP
200*10465441SEvalZero tid = rt_thread_create("main", main_thread_entry, RT_NULL,
201*10465441SEvalZero RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
202*10465441SEvalZero RT_ASSERT(tid != RT_NULL);
203*10465441SEvalZero #else
204*10465441SEvalZero rt_err_t result;
205*10465441SEvalZero
206*10465441SEvalZero tid = &main_thread;
207*10465441SEvalZero result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
208*10465441SEvalZero main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
209*10465441SEvalZero RT_ASSERT(result == RT_EOK);
210*10465441SEvalZero
211*10465441SEvalZero /* if not define RT_USING_HEAP, using to eliminate the warning */
212*10465441SEvalZero (void)result;
213*10465441SEvalZero #endif
214*10465441SEvalZero
215*10465441SEvalZero rt_thread_startup(tid);
216*10465441SEvalZero }
217*10465441SEvalZero
rtthread_startup(void)218*10465441SEvalZero int rtthread_startup(void)
219*10465441SEvalZero {
220*10465441SEvalZero rt_hw_interrupt_disable();
221*10465441SEvalZero
222*10465441SEvalZero /* board level initialization
223*10465441SEvalZero * NOTE: please initialize heap inside board initialization.
224*10465441SEvalZero */
225*10465441SEvalZero rt_hw_board_init();
226*10465441SEvalZero
227*10465441SEvalZero /* show RT-Thread version */
228*10465441SEvalZero rt_show_version();
229*10465441SEvalZero
230*10465441SEvalZero /* timer system initialization */
231*10465441SEvalZero rt_system_timer_init();
232*10465441SEvalZero
233*10465441SEvalZero /* scheduler system initialization */
234*10465441SEvalZero rt_system_scheduler_init();
235*10465441SEvalZero
236*10465441SEvalZero #ifdef RT_USING_SIGNALS
237*10465441SEvalZero /* signal system initialization */
238*10465441SEvalZero rt_system_signal_init();
239*10465441SEvalZero #endif
240*10465441SEvalZero
241*10465441SEvalZero /* create init_thread */
242*10465441SEvalZero rt_application_init();
243*10465441SEvalZero
244*10465441SEvalZero /* timer thread initialization */
245*10465441SEvalZero rt_system_timer_thread_init();
246*10465441SEvalZero
247*10465441SEvalZero /* idle thread initialization */
248*10465441SEvalZero rt_thread_idle_init();
249*10465441SEvalZero
250*10465441SEvalZero #ifdef RT_USING_SMP
251*10465441SEvalZero rt_hw_spin_lock(&_cpus_lock);
252*10465441SEvalZero #endif /*RT_USING_SMP*/
253*10465441SEvalZero
254*10465441SEvalZero /* start scheduler */
255*10465441SEvalZero rt_system_scheduler_start();
256*10465441SEvalZero
257*10465441SEvalZero /* never reach here */
258*10465441SEvalZero return 0;
259*10465441SEvalZero }
260*10465441SEvalZero #endif
261*10465441SEvalZero #endif
262