RT-Thread学习之路(二)RT-Thread启动流程

前言

本章以MDK-ARM为例,通常我们编写裸机程序,程序会先执行一段汇编代码(启动文件),然后由启动文件跳转到我们所熟知的main()函数,也就是说在裸机系统中,main()函数,是我们程序执行的第一个C函数,但是带rtthread的程序,执行的第一个C函数却不是main()函数。


一、__mian函数

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP


在裸机系统中,程序执行完__main函数会跳转到C中的main函数

在rtthread工程中,程序执行完__main函数并不是跳转到C中的main函数,而是跳转到conmponent.c中的$Sub$$main
函数,这是为什么?因为 RT-Thread 使用编译器(这里指的是 KEIL)自带的  $Sub$$  和 $Super$$这两个符号来扩展
了main 函数,使用 $Sub$$main 可以在执行 main 之前先执行 $Sub$$main,在$Sub$$main 函数中我们可以先执行一
 些预操作,当做完这些预操作之后最终还是要执行 main 函数,这个就通过调用 $Super$$main 来实现。

二、$ Sub$$main函数

int $Sub$$main(void)
{
    rtthread_startup();
    return 0;
}

三、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
    /* 如果define了RT_USING_SIGNALS,执行信号的初始化 */
    rt_system_signal_init();
#endif /* RT_USING_SIGNALS */

    /* 创建一个线程,这个线程最终会执行C中的main函数 */
    rt_application_init();

    /* 定时器线程的初始化 */
    rt_system_timer_thread_init();

    /* 空闲线程的初始化 */
    rt_thread_idle_init();

/* 如果define 了RT_USING_SMP,关中断 */
#ifdef RT_USING_SMP
	/* 关中断 */
    rt_hw_spin_lock(&_cpus_lock);
#endif /* RT_USING_SMP */

    /* 启动系统调度器 */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}

四、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_USING_HEAP */

    rt_thread_startup(tid);
}

这个函数创建了一个main_thread_entry线程,执行完这个线程,程序会跳转到C中的main函数

总结

rtthread工程启动流程,启动文件—》__main函数—》$ Sub$$main函数—》rtthread_startup函数—》启动调度器—》跳转到C中main函数

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值