RT-Thread 启动过程分析
RTT RTThread 启动 RT1052 野火
Angel_YY
发布时间: 2019-03-02
阅读: 203
在野火的i.MX RT 1052 MINI开发板的资料中,对于RT-Thread的支持无疑是其RT1052开发板的最大亮点,接下来我们一起结合野火的RT-Thread例程分析一下RT-Thread的启动过程。
在野火的资料文档中"0-野火【i.MX RT1052 MINI 开发板】资料\3-程序源码\2-RT-Thread-Fire-RT1052\RT-Thread-Fire-RT1052"目录是RT-Thread相关代码。
0001.png
在该文件夹中除了三个说明文档,有四个文件夹,分别对应了RT-Thread的文件系统,图形,网络例程和基本的内核例程。
0002.png
首先从最简单的基本内核例程开始,例程的Keil工程。
0003.png
打开工程后,找到startup_MINXRT1052.s,这个汇编文件是1052的启动文件,系统一般都是从复位开始的,这里找到复位处理代码,在L325设置断点,然后进入调试状态。
0004.png
点击复位按钮,使系统复位,此时系统在startup_MINXRT1052.s的L325设置的断点处停止了,这样就可以通过单步调试的方式跟踪系统执行的过程了。
接下来简单分析一下这里的汇编代码:
Reset_Handler   PROC ;子程序开始
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main

                CPSID   I                         ; 关闭中断
                LDR     R0, =0xE000ED08 ;将中断向量表偏移寄存器的地址值加载到R0寄存器
                LDR     R1, =__Vectors     ;将中断向量地址加载到R1寄存器
                STR     R1, [R0]                ;将R1的值存储到R0所指向的地址中。至此设置中断向量偏移地址完成。
                LDR     R2, [R1]                ;将R1地址中的值存储到R2中
                MSR     MSP, R2              ;把R2寄存器的数据写入到状态寄存器
                LDR     R0, =SystemInit    ;把系统初始化函数SystemInit的地址加载到R0寄存器
                BLX     R0                        ;跳转到R0寄存器所在地址,也就是执行SystemInit函数。
                CPSIE   i                          ;开中断
                LDR     R0, =__main         ;把__main函数的地址加载到R0寄存器
                BX      R0                         ;跳转到R0寄存器所在地址,也就是执行__main函数
                ENDP;子程序结束
这段汇编代码实现了在复位后,首先调用SystemInit初始化系统,然后条用__main函数。
接下来我们看看SystemInit函数。这个函数是在system_MIMXRT1052.c中的。
0005.png
在SystemInit函数中,首先设置了FPU相关寄存器,然后禁用了看门狗,禁用SysTick,使能数据缓存和指令缓存。
函数最后调用了rt_lowlevel_init()函数,着就正式进入了RTT的初始化。
0006.png
rt_lowlevel_init()函数在board.c中实现,这个文件就是RT-Thread针对特定硬件环境的配置文件了。
函数中首先配置了MPU,然后初始化了sdram。
接下来分析一下__main函数,__main函数是C/C++运行时库的一个函数,嵌入式系统在进入应用主程序之前必须有一个初始化的过程,使用__main标号引导系统时必须将应用程序的入口定义为main()。
0007.png
在调试状态,鼠标移动到__main函数上时,提示函数所在地址为0x60002400。
0008.png
在汇编窗口右击,菜单中选择show Disassembly at Address。
0009.png
窗口中输入0x60002400后点击Go To,就可以跳转到该地址了。
0010.png
在__main函数中会调用__rt_entry函数。
0011.png
调用__rt_entry_man。最终调用$Sub$$main函数。
0012.png
此函数在文件components.c中。
$Sub$$是Keil所使用的_CC_ARM编译器的特有模式,用于有一个已经存在且不能被改变的函数的情况。使用这个模式可以帮原函数打补丁。
在$Sub$$main函数中调用了rtthread_startup()。
0013.png
此函数是RT_Thread的入口函数,在这里实现了RT-Thread的几乎所有启动过程。
首先调用了rt_hw_board_init()函数进行板级初始化。
0014.png
主要实现了设置时钟,配置滴答定时器,各个组件和控制台设置。
0015.png
在rt_show_version()函数中,打印了RT-Thread的Logo和版本信息。
0016.png
在rt_system_timer_init()函数中初始化了定时器。
0017.png
在rt_system_scheduler_init()函数中初始化任务调度器。
0018.png
在rt_application_init()函数中创建了main_thread_entry任务,任务中调用了$Super$$main()。
0019.png
$Super$$main()将直接调用用户的main函数。
0020.png
在rt_system_timer_thread_init()函数中初始化软件定时器;
0021.png
在rt_thread_idle_init()函数中初始化并创建空闲任务。
0022.png
在rt_system_scheduler_start()函数中开启任务调度器,开启任务调度器之后,main函数会参与调度。
至此,RT-Thread的启动过程分析完成。

总结:RT-Thread作为国产的RTOS,发展的越来越成熟,也是笔者用到的除了FreeRTOS外另一个优秀的嵌入式操作系统,再配合NXP的跨界处理器i.MX RT1052,甚至可以胜任之前部分入门级MPU所做的工作。再配合I.MX超高的性价比,一定会在更多的领域一展拳脚。



原创作品,未经权利人授权禁止转载。详情见转载须知 举报文章

展开查看更多
点赞 (0)
打赏
当前打赏4人    
Angel_YY 擅长:BMS电池管理系统,用户行为分析系统
评论(0)

登录后可评论,请 登录注册

相关文章推荐
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回

我要举报该内容理由

×
请输入您举报的理由(50字以内)