RT-THREAD-NANO

  • RT-THREAD内核系列文章
  • 前言
  • 一、为什么选择Rt-thread?
  • 二、进行移植
  • 1.下载最新的软件组件
  • 2.STM32Cubemx配置
  • 1.Cubemx简要配置
  • 配置简要解释
  • 3.MDK进行最后的配置
  • 1.宏定义配置
  • 2.串口修改
  • 三、测试


 


前言

本文将简要介绍使用STM32Cubemx移植国产操作系统rt-thread和对rt-thread的简介,以及简单的使用。想要了解RTT内核怎么使用欢迎观看我写的RTT系列的文章。


一、为什么选择Rt-thread?

那有这么多实时操作系统,不选为什么不选FreeRTOS,uCos-II/III或者鸿蒙os。我就简单表达表达我为什么选择rt-trhead不选其他。

rt-thread优势:

时代趋势:

未来趋势就是物联网,边缘计算,居家需求上升等等现在也正在稳步发展。而rt-thread的定位主打物联网,这个和时代趋势一拍即合。它有丰富的组件,以及不断壮大的社区(虽然现在还比不上freertos就是了)。RT-Thread 与其他很多 RTOS 如 FreeRTOS、uC/OS 的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件。有丰富的软件包。物联网相关的软件包,脚本语言相关的软件包,系统相关的软件包等等。在安全型方面,最近也通过了军用嵌入式操作系统测评,rt-thread-space适合在航天航空,军工等领域使用。

国产情怀:

国产情怀嘛,毕竟是自家的操作系统,支持。命名规则更接近linux,比freertos的匈牙利命名法看着更舒服,更好读懂。

相关资料:

rt-thread官网本身提供提供的相关文档,比如<RT-Thread API参考手册>,<RT-thread的文档中心>,在b站也有一些视频,对于入门肯定是够了,我就是看着文档和视频学习rt-thread的内核的,中间组件部分我没有学,因为目前使用stm32cubemx和网上的一些开源资料就已经够用了。想要更快速的实现自己想要的系统,减少更改接口的麻烦事,建议使用rt-thread自家的软件包。

废话少说,进入正题,进行STM32cubemx配置边说需要注意的细节


二、进行移植

1.下载最新的软件组件

获取软件安装包:
输入以下链接:
https://www.rt-thread.org/download/cube/RealThread.RT-Thread.pdsccubemx配置添加自己的代码_stm32

3.1.5版本,3.1.3版本(不建议下,移植需要操作的步骤比较多),这里以3.1.5为例

cubemx配置添加自己的代码_单片机_02

2.STM32Cubemx配置

1.Cubemx简要配置

选择自己当前开发板的芯片

这里以STM32F407ZG为例

选择组件,选前两个,不需要使用到RTOS device,因为使用cubemx配置设备就已经很方便了。第一个是内核,第二个是shell使用 FinSH Shell 组件,方便调试。

cubemx配置添加自己的代码_cubemx配置添加自己的代码_03

使用软件包,启动调试相关的功能,其他的保持默认配置,以后可以根据自己的要求选择相应配置。

cubemx配置添加自己的代码_rtos_04

到了最需要注意的的的两步了,第一步配置Stm32的系统时钟,由默认的SysTick改为任意一个时钟,个人建议改为普通的定时器。

cubemx配置添加自己的代码_串口_05

第二步是对中断进行配置,取消勾选所选中的三个,进行完这两部配置后说明原因。RT-Thread 操作系统重定义 HardFault_Handler、PendSV_Handler、SysTick_Handler 中断函数,为了避免重复定义的问题

cubemx配置添加自己的代码_cubemx配置添加自己的代码_06

配置简要解释

这里说明一下,为什么要另外选择一个时钟作为STM32的时钟心跳。我们注意看第二步,在配置NVIC的时候,会发现SysTick已经由rt-thread管理了,也就是SysTick是作为rt-thread的心跳。rt-thread进行一些关于系统处理所有和时间有关的事件,如线程的延时、线程的时间片轮转调度以及定时器超时等都是需要这个时钟提供心跳的。

那为什么不将STM32HAL库的时钟和将rt-thread的时钟作为同一个时钟源呢?如果你尝试过这样做,会发现,一开始系统很小,可能没什么问题,但是后面功能多了,你会发现,系统会一直卡在判断当前时间跳不出循环。因为HAL库在初始化或者其他的一些操作会调用HAL_Delay函数,这个与时间有关的函数,而由于中断优先级的问题,系统会跳不出当前Systick所在优先级的中断,而Systick是被rt-thread管理的,不能更改,就造成了系统的卡死。

说完了系统时钟的问题,说一下硬件错误PSV异常中断。当发生硬件错误,比如内存越界,野指针导致的错误等等,就不会进入STM32HAL库原来的硬件中断函数,进入rt-thread的硬件中断错误函数,并会打印相关寄存器的值和错误类型,还是挺方便的。PSV,PendSV 异常会被初始化为最低优先级的异常。每次需要进行上下文切换的时候,会手动触发 PendSV 异常,在 PendSV 异常处理函数中进行上下文切换。

硬件错误打印例子:提示硬件错误发生在rs485线程

psr: 0x21000000
 pc: 0x08010d9a
 lr: 0x08010cbd
r12: 0x00000000
r03: 0x000001f4
r02: 0x00000008
r01: 0x20005558
r00: 0x0000012d
hard fault on thread: rs485
 thread  pri  status      sp     stack size max used   left tick  error
-------- ---- ------- ---------- ---------- ---------- ---------- ---
heartbea 0x19 suspend 0x00000100 0x00000200 0x00000100 0x00000005 000
hall     0x13 suspend 0x00000118 0x00000400 0x00000118 0x0000000a 000
stepper_ 0x04 suspend 0x00000100 0x00000400 0x00000100 0x00000005 000
flowmete 0x14 suspend 0x00000108 0x00000400 0x00000108 0x00000005 000
nrf24l01 0x15 suspend 0x00000108 0x00000400 0x00000108 0x00000014 000
comm_ove 0x08 suspend 0x00000100 0x00000400 0x00000100 0x00000005 000
breath_t 0x12 suspend 0x00000100 0x00000400 0x00000100 0x00000005 000
debug    0x18 suspend 0x00000118 0x00000400 0x00000118 0x00000005 000
h_l_stat 0x0b suspend 0x00000128 0x00000400 0x00000148 0x00000005 000
chest_st 0x0c suspend 0x00000128 0x00000400 0x00000128 0x00000005 000
encoder  0x17 suspend 0x00000100 0x00000400 0x00000100 0x00000005 000
heartbea 0x0d suspend 0x00000128 0x00000400 0x00000128 0x0000000a 000
epulse   0x0e suspend 0x00000150 0x00000400 0x00000178 0x00000032 000
protocol 0x09 suspend 0x00000100 0x00000400 0x00000120 0x0000000a 000
rs485    0x08 ready   0x00000128 0x00000800 0x00000128 0x0000000a 000
collectb 0x07 suspend 0x00000108 0x00000400 0x00000108 0x0000000a 000
rs232    0x06 suspend 0x00000160 0x00000400 0x00000160 0x00000009 000
valve    0x16 suspend 0x00000110 0x00000400 0x00000128 0x00000005 -02
motor    0x11 suspend 0x00000118 0x00000400 0x00000118 0x00000005 000
adc      0x05 suspend 0x00000138 0x00000800 0x00000138 0x00000032 000
cpr      0x0f suspend 0x00000118 0x00000400 0x00000118 0x0000000a 000
wifi_mod 0x03 suspend 0x00000100 0x00000400 0x00000100 0x00000009 000
tidle    0x1f ready   0x000000e0 0x00000400 0x000000e0 0x00000020 000
tshell   0x14 suspend 0x00000110 0x00000800 0x00000110 0x0000000a 000

最后一步配置串口

随便配置一个自己想要打印输出rt-thread信息的串口

默认配置就行,一开始可以先不用中断。

cubemx配置添加自己的代码_单片机_07

注意生成路径不要有中文:

这里使用MDK进行开发:

cubemx配置添加自己的代码_单片机_08

cubemx配置添加自己的代码_串口_09


3.MDK进行最后的配置

1.宏定义配置

MDK进行最后的配置,主要是更改一下宏定义,对Shell进行配置,如果自己观察过的话,会发现cubemx里面并没有对Fish Shell进行相关的设置,这里需要添加一个头文件,rtconfig.h进行一些配置,以便使用shell。rtconfig.h在RT-threa的文件里面。

解释一下这个文件,对系统的裁剪也是在这个头文件里面进行裁剪的,通过对宏定义的修改,使用或者关闭相关功能。这里的修改和在cubemx修改的效果是一样的。

cubemx配置添加自己的代码_rtos_10


进去这个文件,添加相关宏定义:

#define RT_USING_FINSH

cubemx配置添加自己的代码_单片机_11

2.串口修改

进去board.c,RT-Thread Nano 3.1.5生成的默认端口USART2

cubemx配置添加自己的代码_rtos_12


如果是别的串口把USART2改了,根据你usart.c文件改配置的参数,这里使用的就是串口2,配置也是默认配置就不用改了

cubemx配置添加自己的代码_stm32_13

main函数添加头文件和while添加rt_thread_mdelay(100);

#include <rtthread.h>
rt_thread_mdelay(100);

编译,其实这时候已经能用了,但是有22个警告(不影响使用),如果想要警告消除,需要把一句宏定义更改了

cubemx配置添加自己的代码_rtos_14


找到rtdef.h头文件的231行,屏蔽了,就OK了

头文件路径:当前cumemx生成文件下的Middlewares\Third_Party\RealThread_RTOS\include

cubemx配置添加自己的代码_串口_15


再次进行编译,成功

cubemx配置添加自己的代码_串口_16

三、测试

打开串口,一个字节一个字节这样发送,最后发送空

cubemx配置添加自己的代码_rtos_17


cubemx配置添加自己的代码_串口_18