目录
1、RT-Thead目录结构
以RT-Thread Nano的源码结构为例子:
主要涉及3个目录
- bsp
- bsp目录下是各单板的板级支持包(Board support package),即针对某个特定单板兼容适配的工程。比如ST官方公板:stm32f407-st-duscovery
- 移植时,需要针对特定单板适配串口端口、GPIO等
- libcpu
- 为了在不同CPU架构芯片上运行,RT-Thread提供libcpu抽象层对内核提供统一接口,包括全局中断开关、线程初始化等。
- 移植时,需要针对特地CPU架构实现全局中断开关、线程上下文切换等,
- src
- RT-Thread的核心文件
1.2 核心文件
以理解使用RT-Thread为目标的话,最核心的文件只有5个:
src\thread.c
src\timer.c
src\scheduler.c
src\ipc.c
include\rtservice.h
这些文件的作用列表如下:
重要的文件 | 作用 |
src\thread.c | 线程相关的文件,比如创建线程、启动线程 |
src\timer.c | 定时器相关的文件 |
src\scheduler.c | 调度器:维护线程的就绪链表、提供临界区的进出函数 |
src\ipc.c | 实现了线程间通信的各类对象:消息队列、信号量、互斥量、事件等 |
include\rtservice.h | 提供链表操作 |
1.3 移植时涉及的文件
移植RT-Thread,包含CPU部分移植和BSP部分移植
1.3.1 CPU部分
CPU部分移植就是移植libcpu目录,主要涉及cpuport.c和context.xx.S
比如:libcpu\arm\contex-m3\cpuport.c和context_rvds.S,这表示Context-M3架构在RVDS或Keil工具上的移植文件
- cpuport.c:主要用类初始化线程的栈
- context_rvds,S:主要线程切换、全局中断开关
如果,RT-Thread还没支持你使用的CPU,你才需要实现这两个文件。
一般来说,对于大部分的CPU,RT-Thread都已经支持,不需要我们移植
1.3.2 BSP部分、
BSP就是Board Support Package,板级支持包,就是开发板的相关文件
BSP部分主要涉及main.c board.c和rtconfig.h
比如:bsp\stm32\stm32f103-simulator目录下,包含applications\main.c、board\board.c、和rtconfig.h
- main.c:工程的主函数入口
- board.c:该单板的系统时钟相关配置
- rtconfig.h:内核配置文件,配置裁剪系统功能
1.4 内存管理
RT-Thread操作系统在内存管理上,根据上层应用及系统资源的不同,有针对性地提出了不同的内存分配管理算法
总体上可以分为3类:内存堆管理和内存池管理,而内存对管理又根据具体内存设备划分为三种情况
总结起来就是:
内存堆管理:它可以分为3种,三种只能选择一种
针对小内存块的分配管理算法(小内存管理算法):src\mem.c
针对大内存块的分配管理算法:(slab管理算法):src\slab.c
针对多内存堆的分配情况(memheap管理算法):src\memheap.c
内存池管理:先从内存堆里申请空间、然后进行二次管理,对应文件src\memppool.c
注意:
src\mem.c、src\slab.c、src\memheap.c这三个文件只能选择一个文件
src\mempool.c:先从堆里分配的到一块内存,把这块内存当作内存池
1.5 启动流程及main函数
1.5.1 启动流程
RT-Thread启动流程如下所示,在图中标出颜色的部分需要用户特别注意(黄色表示libcpu移植相关的内容,绿色部分表示板级移植相关的内容)
RT-Thread启动代码统一入口为rtthread_startup(),芯片启动文件在完成必要工作(初始化时钟、配置中断向量表、初始化堆栈、初始化PC指针、调用C库函数-main最终去到C的世界)后,最终会在程序跳转市,跳转至RT-Thread的启动入口中,RT-Thread的启动流程如下;
1、全局关中断,初始化与系统相关的硬件、
2、打印系统版本信息、初始化系统内核对象(如定时器、调度器)
3、初始化用户 main线程,同时会初始化线程栈,在main线程中对各类模块依次进行初始化、
4、初始化软件定时器线程、初始化空闲线程、
5、启动调度器,系统切换到第一个线程开始执行(如mian)线程,并打开全局中断
我们习惯从main函数开始阅读源码,但是RT-Thread的主要启动流程反而不在main函数里
可以分析看到,在stm32的启动代码中,先调用SystemInit:系统初始化、比如初始化时钟,调用__main函数:重定位,比如把代码段从Flash复制到内存,然后执行$Sub$$main
第二个文件:src\components.c:执行一系列的 初始化,调用rt_application_init(初始化RTT组件包括创建SHEEL线程:因为有SHEEL线程,所以即使main函数为空,也是可以操作开发板的),调用main函数:可以写为空函数;启动调度器:rt_system_scheduler_start
整体启动流程详细可以见上图
1.5.2 移植目录结构
这里不详细展开,RT-Thread的官方文档中有详细的说明
1.6 RT-Thread编程规范
官方的代码风格和编程风格文档如下:
documentation/contribution_guide/coding_style_cn.md · RT-Thread/rt-thread - Gitee.com
1.7 手把手教你移植RT-Thread到STM32
最后在添加一个个人认为比较详细的将RT-Thread移植到STM32上的博客,本人亲测有效