RT-Thread架构
RT-Thread诞生于2006年,是一款以开源、中立、社区化发展起来的物联网操作系统。 RT-Thread主要采用 C 语言编写,浅显易懂,且具有方便移植的特性(可快速移植到多种主流 MCU 及模组芯片上)。RT-Thread把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。
RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 内核版本;而相对资源丰富的物联网设备,可使用RT-Thread完整版,通过在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,并且可以无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。
RT-Thread是一个集实时操作系统(RTOS)内核、中间件组件的物联网操作系统,架构如下:
APP:
业务层代码库,主要代码为业务逻辑。例如LCD控制板业务,超声波板业务,拖地机业务,扫地机业务,吹风机业务,等。
Board:
项目配置;每一个项目,都会根据需求,针对bsp,app,components进行组件选择,然后生成统一的rtconfig.h,以及board_xxx_config.h;
Bsp:
不同的芯片平台,例如GD32F103,STM32F407等;
Components:
硬件无关的纯软代码;设备抽象的纯软代码;
Include:
Src:rtthread操作系统源代码(不需要阅读);
名称 | 描述 |
---|---|
BSP | Board Support Package(板级支持包)基于各种开发板的移植 |
components | RT-Thread 的各个组件代码,例如 finsh,gui 等。 |
documentation | 相关文档,如编码规范等 |
examples | 相关示例代码 |
include | RT-Thread 内核的头文件。 |
libcpu | 各类芯片的移植代码。 |
src | RT-Thread 内核的源文件。 |
tools | RT-Thread 命令构建工具的脚本文件。 |
系统编译
首先,安装env,下载源代码,进入board的项目目录下:
menuconfig //选择组件,配置参数
scons --target=mdk5 //生成keil5的工程
scons //使用scons工具链编译
Menuconfig
menuconfig
用于配置模块是否编译进系统,以及选择模块参数
主菜单:
选择BSP:
if RT_USING_BSP_STM32
choice
prompt "choice chip name"
default y
default RT_USING_CHIP_STM32F103RC
config RT_USING_CHIP_STM32F103RC
bool "STM32F103RC"
default "STM32F103RC"
config RT_USING_CHIP_STM32F103VC
bool "STM32F103VC"
default "STM32F103VC"
config RT_USING_CHIP_STM32F103VE
bool "STM32F103VE"
default "STM32F103VE"
config RT_USING_CHIP_STM32F407ZG
bool "STM32F407ZG"
default "STM32F407ZG"
endchoice
endif
配置参数:
Scons
scons
用于建立构建关系,并进行构建的一套环境,scons
环境也是采用python
语言编写。
根据rtconfig.h文件的解析,SConscript
对所有的系统文件建立构建关系,和makefile
类似,根据所有的SConscript
,将所有的工程文件组织在一起,与makefile
不同的是,sconscript
的包含关系,是需要手动在父目录包含字目录的。
每个模块都是单独编译自己的c文件,包含自己需要的h文件,编译成独立的o文件。
SconsStruct 编译过程
import os
import sys
print("#########Sconstruct##########")
#设置工程名称
PROJECT_NAME = os.path.basename(os.getcwd())
PROJECT_INC_DIR = os.path.normpath(os.getcwd() + '/board_config')
print("Project name is", PROJECT_NAME)
print("Project include dir is", PROJECT_INC_DIR)
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
#设置使用的BSP目录
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
sys.path = sys.path + [os.path.join(RTT_ROOT, 'bsp/stm32f10x')]
# 导入全局配置文件
import rtconfig
try:
from building import *
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
exit(-1)
#配置target文件名词
TARGET = 'bin/' + 'rtthread.' + rtconfig.TARGET_EXT
# 配置编译工具链,Keil,iar,gcc
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.
('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM == 'iar':
env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = env["LINKCOM"] + ' --map project.map')
Export('RTT_ROOT')
Export('rtconfig')
Export('PROJECT_NAME')
Export('PROJECT_INC_DIR')
# 根据 rtconfig.h ,生成构建依赖关系
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# 编译和链接,生成target文件
# make a building
DoBuilding(TARGET, objs)
目标文件:
rtthread.axf
:调试文件,包含bin,map,以及所有调试需要的信息,使用axf文件可以直接进行调试
rtthread.bin
:烧录使用的二进制文件
rtthread.map
:map文件,用于分析Flash和内存分布
Total RO Size (Code + RO Data) 104364 ( 101.92kB)
Total RW Size (RW Data + ZI Data) 19624 ( 19.16kB)
Total ROM Size (Code + RO Data + RW Data) 104832 ( 102.38kB)
RO
:Const段
RW
:初始化的全局变量
ZI
:未初始化或初始化为0的全局变量;
RAM
:RW + ZI
ROM
:Code + RO + RW
设备驱动框架
IO设备注册流程:
IO设备操作流程:
//电机MOS控制
p_robot_ctrl->h_mos_gpio = rt_pin_get("PA.13");
rt_pin_mode(p_robot_ctrl->h_mos_gpio, PIN_MODE_OUTPUT);
rt_pin_write(p_robot_ctrl->h_mos_gpio, PIN_LOW);