发新帖

RT-Thread学习笔记-2、RT-Thread启动过程分析

[复制链接]
464 0

本文包含源代码、原理图、PCB、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在一些不使用操作系统的单片机软件工程里面,除了汇编启动文件之外,普遍认为程序入口就是main函数,很多程序代码都是从main函数开始进行分析的。

而对于RT-Thread实时操作系统,程序在跑到main函数之前,其实是进行了一系列的启动流程初始化工作,而这些初始化操作是针对RT-Thread内核和具体的板卡进行的,用户不需要干预这个启动流程。

在进入main函数之前,RT-Thread进行了如图所示的启动操作。

a27dd30fa50f02b4fb6781d8b2f20073.png

不带操作系统的单片机程序,一般都会从启动文件startup_xx.s直接跳转到main函数开始执行,而带RT-Thread操作系统的程序,在进入main函数之前,还进行了如上图所示的一系列操作。以上的操作看似复杂繁多,但其实主要是在调用main函数之前,调用了rtthread_startup函数。关于如何在调用main函数之前,调用rtthread_startup函数,不同的编译器有不同的操作。

对于MDK编译器,主要是使用了MDK的扩展功能 $Sub$$ 和 $Super$$ ,而对于IAR编译器,则是通过__low_level_init()函数,对于GCC编译器,则是通过entry函数,这些函数都是会在调用main函数之前被调用的。

以MDK编译器为例,给main函数添加一个 $Sub$$ 前缀,就形成了一个新的功能函数,这个功能函数会在调用main函数之前被调用,这是MDK编译器所规定的,如下图所示。

273ee107f1b4eb6286f965a3aee95a32.png

关于程序从启动文件跳转到main函数入口的关系,总结概括如下图所示。

778359700f5a5bedc529535160ef537b.png

在$Sub$$main函数里面,主要是调用了rtthread_startup()函数,这个函数是RT-Thread规定的统一启动入口,这个函数主要进行了如图所示的一系列初始化工作。

ae25720444f52d201df3458b6b87c8b3.png

以下是关于rtthread_startup()函数里面各个函数的具体说明

1、关于rt_hw_board_init()函数,主要是初始化了中断向量表,完成了系统时钟的初始化,如果有使用到系统组件的话,同时初始化系统组件,并且设置打印信息的输出控制台,同时初始化系统堆内存,程序代码如下图所示。

ed1925e45892e48ed6ccf4426788170f.png

2、关于rt_show_version()函数,主要是在信息控制台初始化成功后,打印RT-Thread内核的系统版本信息,这个函数的具体实现,如下图所示。

6da7404e92e0225e0bf4eb9a5fa8b8ab.png

3、关于rt_system_timer_init()和rt_system_scheduler_init()函数,主要是初始化了系统定时器链表和RT-Thread系统调度器,由于调度器的实现原理略为复杂,此处暂不展开论述。

4、关于rt_application_init()函数,主要是创建了一个名为main的主线程,这个线程的函数入口是main_thread_entry,这里有两种创建方式,二选一,如果使用了系统堆内存,则使用动态创建的方式,线程使用的内存资源可以动态进行申请或释放,如果没有使用系统堆内存,则使用静态创建的方式,线程使用的内存资源是固定好的,不能被释放,函数实现如下图所示。

a60764328916d5ffbc325949ae3d67c7.png

5、关于rt_system_timer_thread_init()函数,主要是初始化软件定时器的列表,并且采用静态方式创建一个名为timer的软件定时器,并且把软件定时器线程放入调度器里面,函数实现如下图所示。

e0e976b65c324c3f3bfa64c0d7fe1ddd.png

6、关于rt_thread_idle_init()函数,主要是根据芯片CPU的数量,使用静态方式创建空闲线程,实际上,空闲线程并不空闲,这个线程在系统没有任何用户线程调度的时候,就会被调度起来,这个空闲线程主要是检查系统有没有已经消亡的线程,如果有,则把消亡线程的资源进行回收,如果系统使能了电源管理,则会让系统进行低功耗模式,函数的具体实现,如下图所示。

f88613314024f5b5fe2466b6c1bda485.png

7、关于rt_system_scheduler_start()函数,主要是开始使能操作系统调度器,调度器启动后,会根据系统的调度规则,从线程就绪列表里面,选择优先级最高的线程进行启动。

8、从以上分析可知,RT-Thread系统在启动的时候,至少会启动一个main主线程和一个idle空闲线程,如果系统配置有使能软件定时器,还会启动一个timer定时器线程,也就是说,系统一旦启动后,就会有两个(或三个)线程在进行调度,如下图所示。

b353bf472207e37a4e9fa8027a75c038.png


感谢阅读!

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

更多

客服中心

微信扫描二维码 服务时间:周一至周日 8:30-22:00
快速回复 返回顶部 返回列表