/* * File : init.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2012 - 2015, RT-Thread Development Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Change Logs: * Date Author Notes * 2012-09-20 Bernard Change the name to components.c * And all components related header files. * 2012-12-23 Bernard fix the pthread initialization issue. * 2013-06-23 Bernard Add the init_call for components initialization. * 2013-07-05 Bernard Remove initialization feature for MS VC++ compiler * 2015-02-06 Bernard Remove the MS VC++ support and move to the kernel * 2015-05-04 Bernard Rename it to components.c because compiling issue * in some IDEs. * 2015-07-29 Arda.Fu Add support to use RT_USING_USER_MAIN with IAR */ #include #include #ifdef RT_USING_COMPONENTS_INIT /* * Components Initialization will initialize some driver and components as following * order: * rti_start --> 0 * BOARD_EXPORT --> 1 * rti_board_end --> 1.end * * DEVICE_EXPORT --> 2 * COMPONENT_EXPORT --> 3 * FS_EXPORT --> 4 * ENV_EXPORT --> 5 * APP_EXPORT --> 6 * * rti_end --> 6.end * * These automatically initializaiton, the driver or component initial function must * be defined with: * INIT_BOARD_EXPORT(fn); * INIT_DEVICE_EXPORT(fn); * ... * INIT_APP_EXPORT(fn); * etc. */ static int rti_start(void) { return 0; } INIT_EXPORT(rti_start, "0"); static int rti_board_end(void) { return 0; } INIT_EXPORT(rti_board_end, "1.end"); static int rti_end(void) { return 0; } INIT_EXPORT(rti_end, "6.end"); /** * RT-Thread Components Initialization for board */ void rt_components_board_init(void) { #if RT_DEBUG_INIT int result; const struct rt_init_desc *desc; for (desc = &__rt_init_desc_rti_start; desc < &__rt_init_desc_rti_board_end; desc ++) { rt_kprintf("initialize %s", desc->fn_name); result = desc->fn(); rt_kprintf(":%d done\n", result); } #else const init_fn_t *fn_ptr; for (fn_ptr = &__rt_init_rti_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++) { (*fn_ptr)(); } #endif } /** * RT-Thread Components Initialization */ void rt_components_init(void) { #if RT_DEBUG_INIT int result; const struct rt_init_desc *desc; rt_kprintf("do components intialization.\n"); for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++) { rt_kprintf("initialize %s", desc->fn_name); result = desc->fn(); rt_kprintf(":%d done\n", result); } #else const init_fn_t *fn_ptr; for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++) { (*fn_ptr)(); } #endif } #ifdef RT_USING_USER_MAIN void rt_application_init(void); void rt_hw_board_init(void); int rtthread_startup(void); #if defined (__CC_ARM) extern int $Super$$main(void); /* re-define main function */ int $Sub$$main(void) { rt_hw_interrupt_disable(); rtthread_startup(); return 0; } #elif defined(__ICCARM__) extern int main(void); /* __low_level_init will auto called by IAR cstartup */ extern void __iar_data_init3( void ); int __low_level_init(void) { // call IAR table copy function. __iar_data_init3(); rt_hw_interrupt_disable(); rtthread_startup(); return 0; } #elif defined(__GNUC__) extern int main(void); /* Add -eentry to arm-none-eabi-gcc argument */ int entry(void) { rt_hw_interrupt_disable(); rtthread_startup(); return 0; } #endif #ifndef RT_USING_HEAP /* if there is not enable heap, we should use static thread and stack. */ ALIGN(8) static rt_uint8_t main_stack[2048]; struct rt_thread main_thread; #endif /* the system main thread */ void main_thread_entry(void *parameter) { extern int main(void); extern int $Super$$main(void); /* RT-Thread components initialization */ rt_components_init(); /* invoke system main function */ #if defined (__CC_ARM) $Super$$main(); /* for ARMCC. */ #elif defined(__ICCARM__) || defined(__GNUC__) main(); #endif } void rt_application_init(void) { rt_thread_t tid; #ifdef RT_USING_HEAP tid = rt_thread_create("main", main_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX / 3, 20); RT_ASSERT(tid != RT_NULL); #else rt_err_t result; tid = &main_thread; result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX / 3, 20); RT_ASSERT(result != RT_EOK); #endif rt_thread_startup(tid); } int rtthread_startup(void) { rt_hw_interrupt_disable(); /* board level initalization * NOTE: please initialize heap inside board initialization. */ rt_hw_board_init(); /* show RT-Thread version */ rt_show_version(); /* timer system initialization */ rt_system_timer_init(); /* scheduler system initialization */ rt_system_scheduler_init(); /* create init_thread */ rt_application_init(); /* timer thread initialization */ rt_system_timer_thread_init(); /* idle thread initialization */ rt_thread_idle_init(); /* start scheduler */ rt_system_scheduler_start(); /* never reach here */ return 0; } #endif #endif