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 */ 56 static int rti_start(void) 57 { 58 return 0; 59 } 60 INIT_EXPORT(rti_start, "0"); 61 62 static int rti_board_start(void) 63 { 64 return 0; 65 } 66 INIT_EXPORT(rti_board_start, "0.end"); 67 68 static int rti_board_end(void) 69 { 70 return 0; 71 } 72 INIT_EXPORT(rti_board_end, "1.end"); 73 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 */ 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 */ 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 */ 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); 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 */ 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 */ 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 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 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