components.c 6.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * 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
28
 * 2015-05-04     Bernard      Rename it to components.c because compiling issue
29
 *                             in some IDEs.
30
 * 2015-07-29     Arda.Fu      Add support to use RT_USING_USER_MAIN with IAR
31 32
 */

33
#include <rthw.h>
34 35
#include <rtthread.h>

36 37
#ifdef RT_USING_USER_MAIN
#ifndef RT_MAIN_THREAD_STACK_SIZE
B
Bernard Xiong 已提交
38
#define RT_MAIN_THREAD_STACK_SIZE     2048
39 40 41
#endif
#endif

42 43
#ifdef RT_USING_COMPONENTS_INIT
/*
44
 * Components Initialization will initialize some driver and components as following
45 46 47 48 49 50 51 52 53
 * order:
 * rti_start         --> 0
 * BOARD_EXPORT      --> 1
 * rti_board_end     --> 1.end
 *
 * DEVICE_EXPORT     --> 2
 * COMPONENT_EXPORT  --> 3
 * FS_EXPORT         --> 4
 * ENV_EXPORT        --> 5
54 55
 * APP_EXPORT        --> 6
 *
56 57
 * rti_end           --> 6.end
 *
58
 * These automatically initializaiton, the driver or component initial function must
59 60 61 62 63
 * be defined with:
 * INIT_BOARD_EXPORT(fn);
 * INIT_DEVICE_EXPORT(fn);
 * ...
 * INIT_APP_EXPORT(fn);
64
 * etc.
65 66 67 68 69 70 71
 */
static int rti_start(void)
{
    return 0;
}
INIT_EXPORT(rti_start, "0");

72 73 74 75 76 77
static int rti_board_start(void)
{
    return 0;
}
INIT_EXPORT(rti_board_start, "0.end");

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
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;
98
    for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
99 100 101 102 103 104 105 106
    {
        rt_kprintf("initialize %s", desc->fn_name);
        result = desc->fn();
        rt_kprintf(":%d done\n", result);
    }
#else
    const init_fn_t *fn_ptr;

107
    for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    {
        (*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
141

142 143
void rt_application_init(void);
void rt_hw_board_init(void);
144 145
int rtthread_startup(void);

146 147
#if defined (__CC_ARM)
extern int $Super$$main(void);
148 149 150 151 152
/* re-define main function */
int $Sub$$main(void)
{
    rt_hw_interrupt_disable();
    rtthread_startup();
153 154 155 156 157
    return 0;
}
#elif defined(__ICCARM__)
extern int main(void);
/* __low_level_init will auto called by IAR cstartup */
158
extern void __iar_data_init3(void);
159 160
int __low_level_init(void)
{
161 162
    // call IAR table copy function.
    __iar_data_init3();
163 164 165 166 167 168 169 170 171 172 173
    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();
174 175 176 177
    return 0;
}
#endif

178
#ifndef RT_USING_HEAP
179
/* if there is not enable heap, we should use static thread and stack. */
180
ALIGN(8)
181
static rt_uint8_t main_stack[RT_MAIN_THREAD_STACK_SIZE];
182 183 184 185 186 187 188
struct rt_thread main_thread;
#endif

/* the system main thread */
void main_thread_entry(void *parameter)
{
    extern int main(void);
189
    extern int $Super$$main(void);
190 191 192 193 194

    /* RT-Thread components initialization */
    rt_components_init();

    /* invoke system main function */
195
#if defined (__CC_ARM)
196
    $Super$$main(); /* for ARMCC. */
197
#elif defined(__ICCARM__) || defined(__GNUC__)
198
    main();
199
#endif
200 201 202 203 204 205 206 207
}

void rt_application_init(void)
{
    rt_thread_t tid;

#ifdef RT_USING_HEAP
    tid = rt_thread_create("main", main_thread_entry, RT_NULL,
208
                           RT_MAIN_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 3, 20);
209 210 211 212 213 214
    RT_ASSERT(tid != RT_NULL);
#else
    rt_err_t result;

    tid = &main_thread;
    result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
B
Bluebear233 已提交
215
                            main_stack, sizeof(main_stack), RT_THREAD_PRIORITY_MAX / 3, 20);
B
Bluebear233 已提交
216
    RT_ASSERT(result == RT_EOK);
217 218 219 220 221 222 223
#endif

    rt_thread_startup(tid);
}

int rtthread_startup(void)
{
224
    rt_hw_interrupt_disable();
225

226 227 228 229 230 231 232 233 234 235 236 237 238 239
    /* 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();

B
bernard 已提交
240 241 242 243 244
#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

245 246 247 248 249 250 251 252 253 254 255 256 257
    /* 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 */
258
    return 0;
259 260 261
}
#endif
#endif