本笔记结合图示和源码详细解析 RT-Thread 系统从上电启动到用户代码执行(main 函数)的全过程,帮助你全面掌握其底层初始化逻辑。
系统执行路径如下:
RT-Thread 支持多平台和多种编译器,启动文件 startup_xx.S
(例如 STM32F103 为 startup_stm32f103xe.s
)中定义了各平台的入口函数:
编译器 | 入口函数名 |
---|---|
MDK | $Sub$$main() |
IAR | _low_level_init() |
GCC | entry() |
其中,MDK 的 $Sub$$main()
是我们最常用的入口,它通过编译器扩展机制,在用户主函数 main()
执行前,插入对 rtthread_startup()
的调用。
/* MDK: 用户主函数被重定义为 Sub 版本 */
int $Sub$$main(void)
{
rtthread_startup(); // 初始化 RT-Thread 系统
return 0;
}
此函数在 MDK 下自动被调用,在其中完成了 RT-Thread 的系统初始化。初始化完毕后会跳转到 $Super$$main()
,即原始 main()
函数。
这样用户就不需要手动调用 RT-Thread 的初始化流程,可以专注于自己的应用逻辑。
int rtthread_startup(void)
{
rt_hw_interrupt_disable(); // 禁用中断
rt_hw_board_init(); // 板级初始化(时钟、外设、堆)
rt_show_version(); // 打印版本信息
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(); // 创建空闲线程
rt_system_scheduler_start(); // 启动调度器,系统开始运行
return 0; // 实际不会执行到这里
}
阶段 | 作用 |
---|---|
rt_hw_board_init() |
初始化系统时钟、串口、堆空间、SysTick,准备打印输出等 |
rt_system_timer_init() |
初始化软件定时器,配合系统调度使用 |
rt_system_scheduler_init() |
初始化调度器,准备调度线程 |
rt_system_signal_init() (可选) |
初始化 POSIX 信号(若启用) |
rt_application_init() |
创建用户主线程(main_thread),执行 main_thread_entry() 函数 |
rt_system_timer_thread_init() |
启动定时器线程,用于处理超时事件 |
rt_thread_idle_init() |
启动空闲线程,系统空闲时运行 |
rt_system_scheduler_start() |
启动调度器,系统正式调度线程运行 |
系统会调用 rt_application_init()
创建主线程:
rt_thread_init(&main_thread, "main", main_thread_entry, ...)
其中 main_thread_entry()
函数内部会调用 rt_components_init()
,执行所有通过宏注册的初始化函数(如设备驱动、文件系统、网络等),最后才调用用户真正的 main()
函数。
int main(void)
{
/* 用户代码入口 */
return 0;
}
rt_components_init()
会调用一系列通过宏注册的函数,这些函数在 INIT_COMPONENT_EXPORT()
宏定义的模块中注册,主要包括:
这一机制使得系统初始化高度模块化和可扩展。
步骤 | 内容 | 备注 |
---|---|---|
1 | 启动文件执行 | 进入 $Sub$$main() |
2 | 调用 rtthread_startup() |
开始 RT-Thread 初始化 |
3 | 依次初始化中断、时钟、调度器等 | 系统级准备 |
4 | 创建并启动内核必要线程 | 定时器、空闲线程 |
5 | 启动调度器 | 系统正式开始调度线程 |
6 | 执行 main_thread_entry() | 最终进入用户的 main() 函数 |
startup_xx.S
、components.c
、board.c
、main.c