启动流程:
1:执行$sub$$main
函数,此函数为main扩展函数,就相当于是在main函数里面进行操作,只是他是在执行main函数之前执行。
在components.c文件中有定义:
/* $Sub$$main 函 数 */
int $Sub$$main(void) {
rtthread_startup();
return 0;
}
在这里 $Sub$$main
函数调用了 rtthread_startup() 函数,其中rtthread_startup() 函数的代码如下所示:
int rtthread_startup(void)
{
rt_hw_interrupt_disable(); //关闭中断
/* 板 级 初 始 化: 需 在 该 函 数 内 部 进 行 系 统 堆 的 初 始 化 */
rt_hw_board_init();
rt_show_version(); /* 打 印 RT-Thread 版 本 信 息 */
rt_system_timer_init();/* 定 时 器 初 始 化 */
rt_system_scheduler_init();/* 调 度 器 初 始 化 */
#ifdef RT_USING_SIGNALS
rt_system_signal_init();/* 信 号 初 始 化 */
#endif
rt_application_init(); /*由用户创建的main线程*/
rt_system_timer_thread_init();/* 定 时 器 线 程 初 始 化 */
rt_thread_idle_init();/* 空 闲 线 程 初 始 化 */
#ifdef RT_USING_SMP
rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/
rt_system_scheduler_start();/* 启 动 调 度 器 */
return 0;
}
2:执行完$Sub$$main
函数后,调用$super$$
函数跳转到main函数里面,前面执行一些列初始化的时候,有一个函数rt_application_init()
,这个函数的定义如下:
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 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,
main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif
rt_thread_startup(tid);
}
里面调用了函数rt_thread_create()
,这个函数的第二个参数,为线程入口函数main_thread_entry()
。
main_thread_entry的函数定义如下:
void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
#ifdef RT_USING_COMPONENTS_INIT
/* RT-Thread components initialization */
rt_components_init();
#endif
#ifdef RT_USING_SMP
rt_hw_secondary_cpu_up();
#endif
/* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
$Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
main();
#endif
}
在这个函数中执行跳转函数$Super$$main()
。
RT-Thread支持多种平台和多种编译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺序是:系统先从启动文件开始运行,然后进入 RT-Thread 的启动 rtthread_startup() ,最后进入用户入口main(),如下图所示: