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