RT-Thread Studio与STM32CubeMX集成:自动生成STM32的RT-Thread代码全攻略
目录
一、RT-Thread,全称是 Real Time-Thread
二、目前 RT-Thread 有三个版本
三、软件安装参考
四、打开RT-Thread Studio创建新工程
五、双击RT-Thread Setting
六、点击项目构建
七、双击CubeMX Setting进入STM32CUBEMX
八、配置完成后不用打开工程,关闭STM32CubeMX软件,跳转到RT-Thread Studio,可以看到检查到了文件变更,点击”确定“
九、 点击构建项目,发现报错了
十、再构建项目发现了如下报错
十一、进行编写main.C
十二、下载程序
十三、再进行RT-Thread程序编写如下:
一、RT-Thread,全称是 Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统。主要是它是国产的RTOS所以它在国内越来越流行了。
RT-Thread 与其他很多 RTOS 如 FreeRTOS、uC/OS 的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件,如下图所示。
二、目前 RT-Thread 有三个版本:RT-Thread 文档中心
标准版:标准版本
是学习 RT-Thread 的基础
nano版:Nano 版本
是 标准版本
的极简内核版本
Smart版:Smart 版本
是在 标准版本
上增加了用户态创造而来
三、软件安装参考:安装 RT-Thread Studio 、安装STM32CubeMX
安装与配置完成
四、打开RT-Thread Studio创建新工程:
进行项目配置:
创建完成目录如下:
五、双击RT-Thread Setting:
这里可以添加软件包:
点击右边的"《"图标,进入了RT-Thread的配置:
六、点击项目构建:
看到出现了报错,
这个是RT-Thread5.1.0版本的BUG,选择其他版本没有这个问题:
双击error,进入到了board.C,错误原因是RT_WEAK为找到定义,添加下面宏定义在构建既没有了error。
#define RT_WEAK __weak
七、双击CubeMX Setting进入STM32CUBEMX:
首先进行时钟配置:
启用外部晶振:
时钟树配置:
进行LED引脚配置:
这里要注意引脚要点击"Signal Unpinning",要不然后面无法导入gpio.c文件:
工程进行配置:
选上生成单独.H.C文件的选项:
八、配置完成后不用打开工程,关闭STM32CubeMX软件,跳转到RT-Thread Studio,可以看到检查到了文件变更,点击”确定“:
RT-Thread
九、 点击构建项目,发现报错了(这是特殊情况一般是不应该报错的),这个因为软件没有正确生成cubemx文件夹下的SConscript
文件:
手动创建cubemx文件夹下的SConscript
文件:
SConscript
文件内容如下:
import os
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
src = Split('''
Src/stm32f4xx_hal_msp.c #依据所用芯片引入
Src/main.c
Src/gpio.c
''')
path = [cwd]
path += [cwd + '/Inc']
group = DefineGroup('cubemx', src, depend = [''], CPPPATH = path)
Return('group')
注意”Src/gpio.c“是一定要先写入到SConscript
文件里再进行项目构建的要不然cubemx\Src文件下将不会导入gpio.c文件,项目将找不到里面的内容如MX_GPIO_Init();
十、再构建项目发现了如下报错,这个因为项目在创建时将串口1创建成立交互口,但是我们在STM32CUBEMX配置项目时没有将串口1开启所以产生了找不到相关定义的错误:
双击CubeMX Setting进入STM32CUBEMX,进行串口1配置:
十一、解决这几个错误,在构建项目,就没有错误了,我们进行编写main.C如下:
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-03-19 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include"gpio.h"
#define LED0_TOGGLE() do{ HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9); }while(0) /* LED0 = !LED0 */
#define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); }while(0) /* LED1 = !LED1 */
int main(void)
{
int count = 1;
MX_GPIO_Init();
while (count++)
{
LOG_D("Hello RT-Thread!");
LOG_D("System Clock information");
LOG_D("SYSCLK_Frequency = %d", HAL_RCC_GetSysClockFreq());
LOG_D("HCLK_Frequency = %d", HAL_RCC_GetHCLKFreq());
LOG_D("PCLK1_Frequency = %d", HAL_RCC_GetPCLK1Freq());
LOG_D("PCLK2_Frequency = %d", HAL_RCC_GetPCLK2Freq());
rt_thread_mdelay(1000);
LED0_TOGGLE();
}
return RT_EOK;
}
打开一个端口:
十二、下载程序:
如果出现了如下错误,请将单片机重新上电在尝试下载:
看着错误像烧入地址错误,开始我尝试在配置烧入上指定地址,发现烧入是可以正常烧入的,但是程序却不会运行,所以这个办法是错误的:
程序下载成功如下:
程序下载后,在串口终端可以看到时钟消息被成功打印出来了:
十三、再进行RT-Thread程序编写如下:
/*
* Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-03-19 RT-Thread first version
*/
#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include"gpio.h"
#define LED0_TOGGLE() do{ HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9); }while(0) /* LED0 = !LED0 */
#define LED1_TOGGLE() do{ HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); }while(0) /* LED1 = !LED1 */
static rt_thread_t led0_thread = RT_NULL;/* 定义线程控制块 */
static rt_thread_t led1_thread = RT_NULL;/* 定义线程控制块 */
static void led0_thread_entry(void* parameter);
static void led1_thread_entry(void* parameter);
int main( void )
{
/* LED 端口初始化 */
MX_GPIO_Init();
led0_thread = /* 线程控制块指针 */
rt_thread_create( "led0", /* 线程名字 */
led0_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
2, /* 线程的优先级 */
20); /* 线程时间片 */
led1_thread = /* 线程控制块指针 */
rt_thread_create( "led1", /* 线程名字 */
led1_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
3, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
rt_thread_startup(led0_thread);
rt_thread_startup(led1_thread);
}
static void led0_thread_entry(void* parameter)
{
while (1)
{
LED0_TOGGLE();
rt_thread_mdelay(500);
}
}
static void led1_thread_entry(void* parameter)
{
while (1)
{
LED1_TOGGLE();
rt_thread_mdelay(500);
}
}
成功运行:
作者:从正经走向抽象的派大星