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