本文介绍了如何基于 CubeMX 移植 RT-Thread Nano,并说明生成代码工程的步骤。
RT-Thread Nano 已集成在 CubeMX 中,可以直接在 IDE 中进行下载添加。本文档介绍了如何使用 CubeMX 移植 RT-Thread Nano,并以一个 stm32f103 的基础工程作为示例进行讲解。
移植 Nano 的主要步骤:
- 准备一个 CubeMX 基础工程,并获取 RT-Thread Nano pack 安装包进行安装。
- 在基础工程中添加 RT-Thread Nano 源码。
- 适配 Nano,主要从 中断、时钟、内存、应用 这几个方面进行适配,实现移植。
- 最后可对 Nano 进行配置:Nano 是可裁剪的,可以通过配置文件 rtconfig.h 实现对系统的裁剪。
准备工作
- 下载 Cube MX 6.0 ,下载地址 https://www.st.com/en/development-tools/stm32cubemx.html 。
- 在 CubeMX 上下载 RT-Thread Nano pack 安装包。
Nano pack 安装
要获取 RT-Thread Nano 软件包,需要在 CubeMX 中添加 https://www.rt-thread.org/download/cube/RealThread.RT-Thread.pdsc 。
具体步骤:进入打开 CubeMX,从菜单栏 help
进入 Manage embedded software packages
界面,点击 From Url
按钮,进入 User Defined Packs Manager
界面,其次点击 new
,填入上述网址,然后点击 check
,如下图所示:
check
通过后,点击 OK 回到 User Defined Packs Manager
界面,再次点击 OK,CubeMX 自动连接服务器,获取包描述文件。回到 Manage embedded software packages
界面,就会发现 RT-Thread Nano 3.1.3
软件包,选择该软件包,点击 Install Now
,如下图所示:
点击安装之后,弹出 Licensing Agreement
,同意协议,点击 Finish
,如下图所示:
等待安装完成,成功安装后,版本前面的小蓝色框变成填充的黄绿色,现象如下图所示:
至此,RT-Thread Nano 软件包安装完毕,退出 Manage embedded software packages
界面,进入 CubeMX 主界面。
创建基础工程
在 CubeMX 主界面的菜单栏中 File
选择 New Project
,如下图所示
新建工程之后,在弹出界面芯片型号中输入某一芯片型号,方便锁定查找需要的芯片,双击被选中的芯片,如下图所示
时钟树的配置直接使用默认即可,然后还需要配置下载方式。
添加 RT-Thread Nano 到工程
选择 Nano 组件
选中芯片型号之后,点击 Additional Softwares
,进入 Additional Software Components selection
界面,在 Pack Vendor
中选择 RealThread
, 然后根据需求选择 RT-Thread 组件(此处只移植 Nano,只选择 kernel 即可),然后点击 OK 按钮,如下图所示:
注意:RT-Thread Nano 软件包中包含 kernel 与 shell 两个部分,仅选择 kernel 表示只使用 RT-Thread 内核,工程中会添加内核代码;选择 kernel 与 shell 表示在使用 RT-Thread Nano 的基础上使用 FinSH Shell 组件,工程中会添加内核代码与 FinSH 组件的代码,FinSH 的移植详见 《在 RT-Thread Nano 上添加控制台与 FinSH》。
配置 Nano
选择组件之后,对组件参数进行配置。在工程界面 Pinout & Configuration
中,进入所选组件参数配置区,按照下图进行配置
工程管理
给工程取名、选择代码存放位置、选择生成代码的 Toolchain/IDE
。Cube MX
不仅能够生成 Keil4/Keil5
的工程,而且还能够生成 IAR7/IAR8
等 IDE 的工程,功能强大,本文从下拉框中选择 MDK5,操作如图所示
配置 MCU
根据需求配置 MCU 的功能。
适配 RT-Thread Nano
中断与异常处理
RT-Thread 操作系统重定义 HardFault_Handler
、PendSV_Handler
、SysTick_Handler
中断函数,为了避免重复定义的问题,在生成工程之前,需要在中断配置中,代码生成的选项中,取消选择三个中断函数(对应注释选项是 Hard fault interrupt
, Pendable request
, Time base :System tick timer
),最后点击生成代码,具体操作如下图中步骤 11-15 所示:
等待工程生成完毕,点击打开工程,如下图所示,即可进入 MDK5 工程中。
以上是RT-THREAD官网的教程。官网教程接下来是 实现第一个应用:板载 LED 指示灯闪烁。我在这里要实现串口rt_kprintf函数打印输出。
既然官网有教程,为何我又重新“造轮子”?因为我觉得官网的教程说的不太详细,初学者不易上手实践。
- MDK打开先前生成的工程,再编译一下。
- 之后把工程树的Application/User/Core加号点开,双击usart.c,具体如图
复制31行的MX_USART1_UART_Init();到board.c,注意该语句必须放在SystemCoreClockUpdate();之后,否者串口波特率不是设置的值,如图,
粘贴MX_USART1_UART_Init()到board.c时,MDK会报错,把#include "usart.h"粘贴到board.c就可以了。
根据官网教程实现rt_hw_console_output函数,
void rt_hw_console_output(const char *str)
{
rt_size_t i = 0, size = 0;
char a = '\r';
__HAL_UNLOCK(&UartHandle);
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if (*(str + i) == '\n')
{
HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1, 1);
}
HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1, 1);
}
}
下面编写main.c文件以便测试串口输出
首先包含#include <rtthread.h>,然后在while(1)中添加如下语句:
while (1)
{
/* USER CODE END WHILE */
rt_kprintf("HELLO RT-THREAD Nano!\n");
rt_thread_mdelay(500);
/* USER CODE BEGIN 3 */
}