下面所有资料都是转载整理于:https://www.rt-thread.org/document/site/#/
RT-Thread 操作系统现在有三个版本,分别适应满足不同场合的需求。
从版本简介中可以看出,Nano 版本
是 标准版本
的极简内核版本,Smart 版本
是在 标准版本
上增加了用户态创造而来,所以学习 标准版本
是学习 RT-Thread 的基础。本篇文章以学习 RT-Thread 标准版本 为例,为初学者制定学习路线如下,分为入门学习、进阶学习、应用开发。
针对人群:有 C 语言、嵌入式基础,想系统学习 RT-Thread 操作系统
模拟运行
Keil MDK 模拟器 STM32F103 体验
快速上手
推荐使用 潘多拉开发板 配套使用 潘多拉开发板教程. pdf,或者以下主流的学习板进行学习,不建议没有任何基础就将 RT-Thread 移植到一块开发板上。
- RT-Thread 潘多拉 STM32L475 上手指南
- 野火霸道 STM32F103 上手指南
- 正点原子 nanoSTM32F103 上手指南
- 野火挑战者 STM32F429 上手指南
- 正点原子探索者 STM32F407 上手指南
- 正点原子阿波罗 STM32F429 上手指南
- 野火 I.MX RT1052 上手指南
- 正点原子 I.MX RT1052 号令者上手指南
- 其他…
内核学习
内核视频教程
《内核实验手册》
针对人群:学过 FreeRTOS 或 uC/OS, 想把 RT-Thread 使用起来
快速上手
准备一块板子,根据 RT-Thread 支持的板子 BSP 进行 快速上手,或者根据 STM32 系列 BSP 制作教程进行移植。
如果使用 Ubuntu 进行开发,可以参考:在 Ubuntu 下开发 RT-Thread。
编程指南
快速学习内核,参考:《RT-Thread 编程指南》。
API 手册
查看 在线 API 手册 或 下载 API 手册。
第三方 RTOS 兼容层
为方便之前有其他 RTOS 使用经验的用户快速上手 RT-Thread,以及将基于其他 RTOS 的 API 编写的应用层代码快速移植到 RT-Thread 上,RT-Thread 社区编写了第三方 RTOS 兼容层。目前支持以下第三方 RTOS 的 API 无感移植:
- uCOS-II操作系统兼容层
- uCOS-III操作系统兼容层
Env 工具
Env 工具:Env 工具用于对源码功能进行配置或裁减,可以生成 MDK/IAR/GCC 工程,需要配合 MDK/IAR/GCC 使用,详见 Env 用户手册。
RT-Thread IDE
RT-Thread Studio :可以在 Studio 中下载源码包并创建 rt-thread 工程,独立完成开发、编译、下载、调试等功能,并能进行功能裁剪,详见 RT-Thread Studio 用户手册。
IO 设备模型
PIN 设备
UART 设备
UART 设备V2版本
CAN 设备
HWTIMER 设备
I2C 设备
PWM 设备
RTC 设备
SPI 设备
WATCHDOG 设备
SENSOR 设备
更多…
FinSH 控制台
文件系统
netdev 网卡
SAL 套接字抽象层
AT 命令
ulog 日志
utest 测试框架
动态模块
POSIX 接口
电源管理
更多…
应用开发列表 | 应用开发列表 |
---|---|
使用 Eclipse 开发 RT-Thread | CmBacktrace应用 |
使用 VS Code 开发 RT-Thread | 在STM32 Nucleo 开发板上使用 RW007 WiFi 模块 |
使用 Env 创建 RT-Thread 项目工程 | 在 STM32L4 上应用 littlefs 文件系统 |
搭建RT-Thread项目框架 | 在潘多拉上使用 SFUD 操作 Flash |
在IoT Board上实现电源管理 | STM32 通用 Bootloader |
网络协议栈驱动移植 | wireshark 抓取 tls 数据包 |
在STM32F429上应用网络功能 | 在 STM32 上应用 C++ |
在STM32F429上应用文件系统 | STM32 上使用 PWM |
FreeModbus 应用笔记 | STM32 上使用 USB Host 读写 U 盘 |
应用AT组件连接ESP8266模块 | QEMU网络视频教程 |
多线程非阻塞网络编程 | 使用QEMU运行动态模块组件 |
应用设计参考…
Demo演示和教程[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBtUmYbL-1645022946719)()]Sample示例 |
---|
基于RT-Thread和i.MX RT1052的开源AutoQuad飞控 |
基于RT-Thread的开源飞控StarryPilot |
基于RT-Thread的人体健康监测系统 |
基于RT-Thread的激光雷达避障小车 |
基于RT-Thread的蓝牙遥控平衡小车 |
蜂鸣器播放器 |
分布式温度监控系统 |
智能车教程 |
开发指南[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rb6TCmF3-1645022946720)()]代码规范[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eFZcaflt-1645022946721)()]提交代码 | ||
软件包开发指南 | RT-Thread编程风格 | 向RT-Thread贡献代码 |
STM32系列BSP制作教程 | BSP开发规范 | |
传感器驱动开发指南 |
作为一名 RTOS 的初学者,也许你对 RT-Thread 还比较陌生。然而,随着你的深入接触,你会逐渐发现 RT-Thread 的魅力和它相较于其他同类型 RTOS 的种种优越之处。RT-Thread 是一款完全由国内团队开发维护的嵌入式实时操作系统(RTOS),具有完全的自主知识产权。经过近 15 个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。
RT-Thread,全称是 Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。事实上,一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短、任务与任务之间通过任务调度器进行非常快速地切换(调度器根据优先级决定此刻该执行的任务),给人造成多个任务在一个时刻同时运行的错觉。在 RT-Thread 系统中,任务通过线程实现的,RT-Thread 中的线程调度器也就是以上提到的任务调度器。
RT-Thread 主要采用 C 语言编写,浅显易懂,方便移植。它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好。针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 版本(NANO 是 RT-Thread 官方于 2017 年 7 月份发布的一个极简版内核);而对于资源丰富的物联网设备,RT-Thread 又能使用在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。
相较于 Linux 操作系统,RT-Thread 体积小,成本低,功耗低、启动快速,除此以外 RT-Thread 还具有实时性高、占用资源小等特点,非常适用于各种资源受限(如成本、功耗限制等)的场合。虽然 32 位 MCU 是它的主要运行平台,实际上很多带有 MMU、基于 ARM9、ARM11 甚至 Cortex-A 系列级别 CPU 的应用处理器在特定应用场合也适合使用 RT-Thread。
RT-Thread 系统完全开源,3.1.0 及以前的版本遵循 GPL V2 + 开源许可协议。从 3.1.0 以后的版本遵循 Apache License 2.0 开源许可协议,可以免费在商业产品中使用,并且不需要公开私有代码。
近年来,物联网(Internet Of Things,IoT)概念广为普及,物联网市场发展迅猛,嵌入式设备的联网已是大势所趋。终端联网使得软件复杂性大幅增加,传统的 RTOS 内核已经越来越难满足市场的需求,在这种情况下,物联网操作系统(IoT OS)的概念应运而生。**物联网操作系统是指以操作系统内核(可以是 RTOS、Linux 等)为基础,包括如文件系统、图形库等较为完整的中间件组件,具备低功耗、安全、通信协议支持和云端连接能力的软件平台,**RT-Thread 就是一个 IoT OS。
RT-Thread 与其他很多 RTOS 如 FreeRTOS、uC/OS 的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件,如下图所示。
它具体包括以下部分:
一般嵌入式操作系统因为它的特殊性,往往和硬件平台密切相关连,具体的嵌入式操作系统往往只能在特定的硬件上运行。对于刚接触 RT-Thread 操作系统的读者并不容易马上就获得一个和 RT-Thread 操作系统相配套的硬件模块,但随着计算机技术的发展,我们可以采用软件方式来模拟一个能够运行 RT-Thread 操作系统的硬件模块,这就是 ARM 公司的 MDK-ARM 仿真模拟环境。
MDK-ARM(MDK-ARM Microcontroller Development Kit)软件是一套完整的集成开发环境(IDE),它出自 ARM 公司,包括了针对 ARM 芯片(ARM7,ARM9,Cortex-M 系列,Cortex-R 系列等)的高效 C/C++ 编译器;针对各类 ARM 设备、评估板的工程向导,工程管理;用于软件模拟运行硬件平台的模拟器;以及与市面上常见的如 ST-Link,JLink 等在线仿真器相连接以配合调试目标板的调试器。MDK-ARM 软件中的软件仿真模拟器,采用完全软件模拟方式解释执行 ARM 的机器指令,并实现外围的一些外设逻辑,从而构成一套完整的虚拟硬件环境,使得用户能够不借助真实的硬件平台就能够在电脑上执行相应的目标程序。
MDK-ARM 集成开发环境因为其完全的 STM32F103 软件仿真环境,也让我们有机会在不使用真实硬件环境的情况下直接在电脑上运行目标代码。这套软件仿真模拟器能够完整地虚拟出 ARM Cortex-M3 的各种运行模式、外设,如中断异常,时钟定时器,串口等,这几乎和真实的硬件环境完全一致。实践也证明,本文使用到的这份 RT-Thread 入门例程,在编译成二进制代码后,不仅能够在模拟器上软件模拟运行,也能够不需要修改地在真实硬件平台上正常运行。
下面我们将选择 MDK-ARM 集成开发环境作为目标硬件平台来观察 RT-Thread 操作系统是如何运行的。
MDK 开发环境:需要安装 MDK-ARM 5.24 (正式版或评估版,5.14 版本及以上版本均可),这个版本也是当前比较新的版本,它能够提供相对比较完善的调试功能。安装方法可以参考 Keil MDK安装。
使用 STM32F103 软件仿真 ,还需要下载安装 STM32F103 pack 文件,如果在 MDK 中下载较慢,也可以点击此处下载,下载后双击安装即可。
作为一个操作系统,RT-Thread 的代码规模怎么样呢?在弄清楚这些之前,我们先要做的就是获得与本文相对应的 RT-Thread 的例子,这份例子可以从以下链接获得:
RT-Thread Simulator 例程
这个例子是一个压缩包文件,将它解压,我们这里解压到 D:/。解压完成后的目录结构如下图所示:
各个目录所包含的文件类型的描述如下表所示:
目录名 | 描述 |
---|---|
applications | RT-Thread 应用程序。 |
rt-thread | RT-Thread 的源文件。 |
- components | RT-Thread 的各个组件目录。 |
- include | RT-Thread 内核的头文件。 |
- libcpu | 各类芯片的移植代码,此处包含了 STM32 的移植文件。 |
- src | RT-Thread 内核的源文件。 |
- tools | RT-Thread 命令构建工具的脚本文件。 |
drivers | RT-Thread 的驱动,不同平台的底层驱动具体实现。 |
Libraries | ST 的 STM32 固件库文件。 |
kernel-sample-0.1.0 | RT-Thread 的内核例程。 |
在目录下,有一个 project.uvprojx 文件,它是本文内容所引述的例程中的一个 MDK5 工程文件,双击 “project.uvprojx” 图标,打开此工程文件:
在工程主窗口的左侧 Project
栏里可以看到该工程的文件列表,这些文件被分别存放到如下几个组内,分别是:
目录组 | 描述 |
---|---|
Applications | 对应的目录为 rtthread_simulator_v0.1.0/applications,它用于存放用户应用代码。 |
Drivers | 对应的目录为 rtthread_simulator_v0.1.0/drivers,它用于存放 RT-Thread 底层的驱动代码。 |
STM32_HAL | 对应的目录为 rtthread_simulator_v0.1.0/Libraries/CMSIS/Device/ST/STM32F1xx,它用于存放 STM32 的固件库文件。 |
kernel-sample | 对应的目录为 rtthread_simulator_v0.1.0/kernel-sample-0.1.0,它用于存放 RT-Thread 的内核例程。 |
Kernel | 对应的目录为 rtthread_simulator_v0.1.0/src,它用于存放 RT-Thread 内核核心代码。 |
CORTEX-M3 | 对应的目录为 rtthread_simulator_v0.1.0/rt-thread/libcpu,它用于存放 ARM Cortex-M3 移植代码。 |
DeviceDrivers | 对应的目录为 rtthread_simulator_v0.1.0/rt-thread/components/drivers,它用于存放 RT-Thread 驱动框架源码。 |
finsh | 对应的目录为 rtthread_simulator_v0.1.0/rt-thread/components/finsh,它用于存放 RT-Thread 命令行 finsh 命令行组件。 |
现在我们点击一下窗口上方工具栏中的按钮,对该工程进行编译,如图所示:
编译的结果显示在窗口下方的 “Build” 栏中,没什么意外的话,最后一行会显示“0 Error(s), * Warning(s).”,即无任何错误和警告。
注:由于工程中包含的内核例程代码较多,若使用的是 MDK 试用版本,则会有 16KB 限制,此时可以只保留某个目标例程的代码(例如内核例程只保留一个 thread_sample.c 参与编译),将其他不用的例程先从工程中移除,然后编译。
在编译完 RT-Thread/STM32 后,我们可以通过 MDK-ARM 的模拟器来仿真运行 RT-Thread。点击窗口右上方的按钮或直接按 “Ctrl+F5” 进入仿真界面,再按 F5 开始运行,然后点击该图工具栏中的按钮或者选择菜单栏中的 “View→Serial Windows→UART#1”,打开串口 1 窗口,可以看到串口的输出只显示了 RT-Thread 的 LOGO,这是因为用户代码是空的,其模拟运行的结果如图所示:
提示:我们可以通过输入Tab键或者
help + 回车
输出当前系统所支持的所有命令,如下图所示。
一般了解一份代码大多从启动部分开始,同样这里也采用这种方式,先寻找启动的源头。以 MDK-ARM 为例,MDK-ARM 的用户程序入口为 main() 函数,位于 main.c 文件中。系统启动后先从汇编代码 startup_stm32f103xe.s 开始运行,然后跳转到 C 代码,进行 RT-Thread 系统功能初始化,最后进入用户程序入口 main()。
下面我们来看看在 components.c 中定义的这段代码:
//components.c 中定义
/* re-define main function */
int $Sub$$main(void)
{
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}复制错误复制成功
在这里 $Sub$$main
函数仅仅调用了 rtthread_startup()
函数。RT-Thread 支持多种平台和多种编译器,而 rtthread_startup()
函数是 RT-Thread 规定的统一入口点,所以 $Sub$$main
函数只需调用 rtthread_startup()
函数即可。例如采用 GNU
GCC
编译器编译的 RT-Thread
,就是直接从汇编启动代码部分跳转到 rtthread_startup()
函数中,并开始第一个 C 代码的执行的。在 components.c
的代码中找到 rtthread_startup()
函数,我们将可以看到 RT-Thread 的启动流程:
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* board level initalization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
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();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}复制错误复制成功
这部分启动代码,大致可以分为四个部分:
上面的启动代码基本上可以说都是和 RT-Thread 系统相关的,那么用户如何加入自己的应用程序的初始化代码呢?RT-Thread 将 main 函数作为了用户代码入口,只需要在 main 函数里添加自己的代码即可。
int main(void)
{
/* user app entry */
return 0;
}复制错误复制成功
提示:
为了在进入 main 程序之前,完成系统功能初始化,可以使用 $sub$$
和 $super$$
函数标识符在进入主程序之前调用另外一个例程,这样可以让用户不用去管 main() 之前的系统初始化操作。详见ARM® Compiler v5.06 for µVision® armlink User Guide
对于从事电子方面开发的技术工程师来说,跑马灯大概是最简单的例子,就类似于每种编程语言中程序员接触的第一个程序 Hello World 一样,所以这个例子就从跑马灯开始。让它定时地对 LED 进行更新(亮或灭)。
我们 UART#1 中输入 msh 命令:led 然后回车就可以运行起来了,如图所示:
跑马灯例子
/*
* 程序清单:跑马灯例程
*
* 跑马灯大概是最简单的例子,就类似于每种编程语言中程序员接触的第一个程序
* Hello World 一样,所以这个例子就从跑马灯开始。创建一个线程,让它定时地对
* LED 进行更新(亮或灭)
*/
int led(void)
{
rt_uint8_t count;
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
for(count = 0 ; count < 10 ;count++)
{
rt_pin_write(LED_PIN, PIN_HIGH);
rt_kprintf("led on, count : %d\r\n", count);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_LOW);
rt_kprintf("led off\r\n");
rt_thread_mdelay(500);
}
return 0;
}
MSH_CMD_EXPORT(led, RT-Thread first led sample);复制错误复制成功
其他更多的内核示例可以从 kernel-sample-0.1.0 目录下找到。
rt-thread\src\kservice.c(823): error: #929: incorrect use of vaarg fieldwidth = aarg(args, int);
rt-thread\src\kservice.c(842): error: #929: incorrect use of vaarg precision = aarg(args, int);
………复制错误复制成功
原因:这类问题基本上都是因为安装了 ADS 导致,ADS 与 keil共存,va_start 所在的头文件指向了 ADS 的文件夹。
解决办法:
为方便之前有其他 RTOS 使用经验的用户快速上手 RT-Thread,以及将基于其他 RTOS 的 API 编写的应用层代码快速移植到 RT-Thread 上,RT-Thread 社区编写了第三方 RTOS 兼容层。目前支持以下第三方 RTOS 的 API 无感移植:
以上第三方 RTOS 兼容层均提供本章所述的STM32F103 Keil 软件模拟工程,以供入门者可以不依托开发板评估兼容层。
本文档将介绍潘多拉(即 IoT Board)开发板和 IoT Board SDK 的基本情况。使开发者熟悉 IoT Board SDK 的目录结构,并且可以将 SDK 提供的示例程序运行起来。
IoT Board 是正点原子、 RT-Thread 联合推出的一款基于 ARM Cortex-M4 内核的开发板,最高主频为 80Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32L475 的芯片性能。
开发板外观及资源如下图:
该开发板常用 板载资源 如下:
开发板更多详细信息请参考 正点原子官方品牌店宝贝介绍。
IoT Board SDK 获取方式:从 Github 获取 或 从 Gitee 获取。 SDK 的目录结构如下所示:
名称 | 说明 |
---|---|
docs | 说明文档 |
drivers | 开发板驱动文件 |
examples | 示例程序 |
libraries | 库文件 |
rt-thread | rt-thread 源代码 |
tools | 工具目录 |
为开发板提供的示例程序存放在 examples 文件夹中,后面将以第一个示例程序为例,介绍如何将 SDK 提供的示例程序运行起来。
IoT Board SDK 中的示例程序均提供 MDK 和 IAR 工程,并且支持 GCC 开发环境,下面以 MDK 开发环境为例,介绍如何将示例程序运行起来。运行示例程序前需要做如下准备工作:
MDK 开发环境
我们需要安装 MDK-ARM 5.24 (正式版或评估版,5.14 版本及以上版本均可),这个版本也是当前比较新的版本,它能够提供相对比较完善的调试功能。安装方法可以参考 Keil MDK安装。
连接开发板的 ST-Link USB 口到 PC 机
进入到 examples\01_basic_led_blink
文件夹中,双击 project.uvprojx 文件,打开 MDK5 工程,执行编译。编译完成后,点击下载按钮将固件下载至开发板,观察程序运行状况。
按下复位按键重启开发板,观察开发板上 RBG-LED 的实际效果。正常运行后,红色 LED 会周期性闪烁,如下图所示:
IoT Board SDK 中其余例程的使用方法也是相同的,了解了运行例程的方法之后,就可以进行后面例程的运行和学习了。
已完成 RT-Thread 快速上手!点击这里进行 内核学习 。
内核学习完成后,继续学习 IoT Board SDK 中的例程,教程参考 《IoT Board 开发手册》 。