xref: /nrf52832-nimble/rt-thread/src/components.c (revision 104654410c56c573564690304ae786df310c91fc)
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