【RT-Thread】启动流程

RT-Thread 启动流程详解(以 STM32 + MDK 为例)

本笔记结合图示和源码详细解析 RT-Thread 系统从上电启动到用户代码执行(main 函数)的全过程,帮助你全面掌握其底层初始化逻辑。


启动概览流程图

系统执行路径如下:

【RT-Thread】启动流程_第1张图片


启动文件入口

RT-Thread 支持多平台和多种编译器,启动文件 startup_xx.S(例如 STM32F103 为 startup_stm32f103xe.s)中定义了各平台的入口函数:

编译器 入口函数名
MDK $Sub$$main()
IAR _low_level_init()
GCC entry()

其中,MDK$Sub$$main() 是我们最常用的入口,它通过编译器扩展机制,在用户主函数 main() 执行前,插入对 rtthread_startup() 的调用。


S u b Sub Sub$main 与 S u p e r Super Super$main

/* MDK: 用户主函数被重定义为 Sub 版本 */
int $Sub$$main(void)
{
    rtthread_startup();       // 初始化 RT-Thread 系统
    return 0;
}

此函数在 MDK 下自动被调用,在其中完成了 RT-Thread 的系统初始化。初始化完毕后会跳转到 $Super$$main(),即原始 main() 函数。

这样用户就不需要手动调用 RT-Thread 的初始化流程,可以专注于自己的应用逻辑。


rtthread_startup() 流程解析

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() 启动调度器,系统正式调度线程运行

main 线程与用户入口

系统会调用 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() 作用

rt_components_init() 会调用一系列通过宏注册的函数,这些函数在 INIT_COMPONENT_EXPORT() 宏定义的模块中注册,主要包括:

  • pre-initialization functions
  • device init functions
  • components init functions
  • environment init functions
  • applications init functions

这一机制使得系统初始化高度模块化和可扩展。


✅ 启动流程总结

步骤 内容 备注
1 启动文件执行 进入 $Sub$$main()
2 调用 rtthread_startup() 开始 RT-Thread 初始化
3 依次初始化中断、时钟、调度器等 系统级准备
4 创建并启动内核必要线程 定时器、空闲线程
5 启动调度器 系统正式开始调度线程
6 执行 main_thread_entry() 最终进入用户的 main() 函数

推荐阅读

  • RT-Thread 官方文档
  • 《RT-Thread 开发实战指南》
  • 启动源码:startup_xx.Scomponents.cboard.cmain.c

你可能感兴趣的:(RT-Thread学习笔记,rt_thread)