RT-Thread工程代码框架分析——(1)启动流程

前言

学的东西多了难免有些记不住,通过博客形式记录下来虽然耗费些时间,但总算是留下了一些东西,回头想起来也有迹可循不用完全依赖记忆,顺便也许能对一些同仁提供些许帮助。

本文章主要记录RT-Thread系统的一些简述。
这里还是要为RT-Thread打call,毕竟是我们的国产开源操作系统,支持国产,希望在众多开发者维护下会越来越好。
我用的开发板是正点原子的潘多拉STM32L4开发板,是原子和RT-Thread联合打造的,原子的资料中有两套源码,一套是原子给的HAL库使用例程,另一套是用RT-Thread上的相关外设使用例程。下面我的一些源码展示来自RT-Thread外设使用例程,注意与RT-Thread的最新源码会有一定出入

学习RT-Thread系统主要的获取资料和信息的通道当然还是官网:RT-Thread 官网
同时还提供了社区:RT-Thread 开源社区

官网有一篇文档《RT-Thread编程指南》非常适合初次接触RT-Thread的同学阅读。

内核源码下载:官网下载 (官网给了多个方式提供下载,非常贴心)
github 地址

启动流程

RT-Thread的启动流程有点特殊,在xxx.s启动文件之后没有直接到用户的main函数,而是利用MDK的特殊符号$ Super $ $ and $ Sub $ $ 在用户的main函数前还插入了一段程序用于一些硬件初始化以及系统初始化。
components.c文件中:
在这里插入图片描述
关于 S u p e r Super Super$ and S u b Sub Sub$的用法,见ARM官网描述

S u p e r Super Super$foo
Identifies the original unpatched function foo(). Use this to call the original function directly.

S u b Sub Sub$foo
Identifies the new function that is called instead of the original function foo(). Use this to add processing before or after the original function.

对这两个符号有兴趣可参考这位大佬的博客进一步了解:$ Super$ $ and $Sub $ $的用法

针对这个符号我也另起了一篇$ Super$ $ and $Sub $ $的用法

注意:$ Super $ $ and $ Sub $ $要成对使用,且只在MDK中使用。

主要看rtthread_startup()函数:

int rtthread_startup(void)
{
    
    
    rt_hw_interrupt_disable();

    /* 板级硬件初始化  使用的硬件初始化,包括串口初始化,系统时钟配置等  HAL库的HAL_Init()也在这里
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();

    /* 显示 RT-Thread 的版本号 */
    rt_show_version();

    /* timer system initialization */
    rt_system_timer_init();

    /* scheduler system initialization */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* create init_thread */
    rt_application_init();//这里面很有意思,把main函数当成一个进程来运行了

    /* timer thread initialization */
    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();

    /* never reach here */
    return 0;
}

官方的启动流程图:
在这里插入图片描述
其中有一个应用初始化的函数里面创建了一个main进程,这里面的处理很有意思,main进程里把main函数当成一个进程的一部分代码去运行了(相当于main()函数变成了一个进程,这跟我们用ucos,freeRTOS的思路不太一样)。
在这里插入图片描述
在这里插入图片描述

真正的main函数就比较简单了。

int main(void)
{
    
    
    unsigned int count = 1;
    /* set LED pin mode to output */
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);

    while (count > 0)
    {
    
    
        /* led on */
        rt_pin_write(LED_PIN, PIN_LOW);
        rt_kprintf("led on, count: %d\n", count);
        rt_thread_mdelay(500);

        /* led off */
        rt_pin_write(LED_PIN, PIN_HIGH);
        rt_kprintf("led off\n");
        rt_thread_mdelay(500);

        count++;
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44788542/article/details/113189214
今日推荐