RT-Thread-内核启动流程分析

本文详细解析了RT-Thread实时操作系统的启动流程,包括main函数作为程序入口、rtthread_startup函数的功能及调用过程、硬件初始化步骤以及系统内核对象的初始化。深入探讨了从硬件初始化到调度器启动的整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

流程入口-main函数

以 MDK-ARM 为例,MDK-ARM 的用户程序入口为 main() 函数,位于 main.c 文件中。系统启动后先从汇编代码开始运行,然后跳转到 C 代码,进行 RT-Thread 系统功能初始化,最后进入用户程序入口 main()。

/* re-define main function */
int $Sub$$main(void)
{
    rtthread_startup();
    return 0;
}

在这里 S u b Sub Sub$main 函数仅仅调用了 rtthread_startup() 函数。RT-Thread 支持多种平台和多种编
译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一入口点,所以 S u b Sub Sub$main 函数只需调用
rtthread_startup() 函数即可(例如采用 GNU GCC 编译器编译的 RT-Thread,就是直接从汇编启动代码
部分跳转到 rtthread_startup() 函数中,并开始第一个 C 代码的执行)。在 components.c 的代码中找到
rtthread_startup() 函数,我们看到 RT-Thread 的启动流程如下图所示:
在这里插入图片描述

启动函数:rtthread_startup

int rtthread_startup(void)
{
	rt_hw_interrupt_disable();
	/* 板 级 初 始 化: 需 在 该 函 数 内 部 进 行 系 统 堆 的 初 始 化 */
	rt_hw_board_init();
	/* 打 印 RT-Thread 版 本 信 息 */
	rt_show_version();
	/* 定 时 器 初 始 化 */
	rt_system_timer_init();
	/* 调 度 器 初 始 化 */
	rt_system_scheduler_init();
	#ifdef RT_USING_SIGNALS
	/* 信 号 初 始 化 */
	rt_system_signal_init();
	#endif
	/* 由 此 创 建 一 个 用 户 main() 线 程 */
	rt_application_init();
	/* 定 时 器 线 程 初 始 化 */
	rt_system_timer_thread_init();
	/* 空 闲 线 程 初 始 化 */
	rt_thread_idle_init();
	/* 启 动 调 度 器 */
	rt_system_scheduler_start();
	/* 不 会 执 行 至 此 */
	return 0;
}

这部分启动代码,大致可以分为四个部分:
(1)初始化与系统相关的硬件;
(2)初始化系统内核对象,例如定时器、调度器、信号;
(3)创建 main 线程,在 main 线程中对各类模块依次进行初始化;
(4)初始化定时器线程、空闲线程,并启动调度器。
rt_hw_board_init() 中完成系统时钟设置,为系统提供心跳、串口初始化,将系统输入输出终端绑定
到这个串口,后续系统运行信息就会从串口打印出来。main() 函数是 RT-Thread 的用户代码入口,用户可以在 main() 函数里添加自己的应用。

/* defined the LED0 pin: PB1 */
#define LED0_PIN    GET_PIN(B, 1)

int main(void)
{
    int count = 1;
    /* set LED0 pin mode to output */	
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);	
	
    while (count++)
    {
        rt_pin_write(LED0_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
        rt_pin_write(LED0_PIN, PIN_LOW);
        rt_thread_mdelay(500);
    }
    return RT_EOK;
}

硬件初始化:rt_hw_board_init

/**
 * This function will initial STM32 board.
 */
RT_WEAK void rt_hw_board_init()
{
#ifdef SCB_EnableICache
    /* Enable I-Cache---------------------------------------------------------*/
    SCB_EnableICache();
#endif

#ifdef SCB_EnableDCache
    /* Enable D-Cache---------------------------------------------------------*/
    SCB_EnableDCache();
#endif

    /* HAL_Init() function is called at the beginning of the program */
    HAL_Init();

    /* enable interrupt */
    __set_PRIMASK(0);
    /* System clock initialization */
    SystemClock_Config();
    /* disbale interrupt */
    __set_PRIMASK(1);

    rt_hw_systick_init();

    /* Heap initialization */
#if defined(RT_USING_HEAP)
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif

    /* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
    rt_hw_pin_init();
#endif

    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
    rt_hw_usart_init();
#endif

    /* Set the shell console output device */
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

    /* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif
}

rt_components_board_init

/**
 * 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_board_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_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
#endif

rt_components_board_init() 函数执行的比较早,主要初始化相关硬件环境,执行这个函数时将会遍
历通过 INIT_BOARD_EXPORT(fn) 申明的初始化函数表,并调用各个函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值