问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

RT-Thread Studio联合STM32CubeMX开发STM32完整教程

创作时间:
作者:
@小白创作中心

RT-Thread Studio联合STM32CubeMX开发STM32完整教程

引用
CSDN
1.
https://blog.csdn.net/wallwayj/article/details/146376046

RT-Thread是一个国产的实时操作系统,具有丰富的中间层组件和良好的社区支持。本文将介绍如何使用RT-Thread Studio联合STM32CubeMX开发STM32,通过一个LED闪烁的示例展示整个开发流程。

一、RT-Thread简介

RT-Thread,全称是 Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统。与其他很多RTOS如FreeRTOS、uC/OS的主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件,如下图所示。

二、RT-Thread版本

目前RT-Thread有三个版本:

  • 标准版:是学习RT-Thread的基础
  • nano版:是标准版本的极简内核版本
  • Smart版:是在标准版本上增加了用户态创造而来

三、软件安装

参考安装RT-Thread Studio和STM32CubeMX。

四、创建新工程

打开RT-Thread Studio创建新工程,进行项目配置,创建完成后的目录结构如下:

五、RT-Thread Setting配置

双击RT-Thread Setting,可以添加软件包。点击右边的"《"图标,进入RT-Thread的配置。

六、项目构建

点击项目构建,可能会遇到RT-Thread 5.1.0版本的BUG,选择其他版本可以避免这个问题。如果遇到RT_WEAK未定义的错误,可以在代码中添加如下宏定义:

#define RT_WEAK __weak

七、STM32CubeMX配置

双击CubeMX Setting进入STM32CubeMX,进行时钟配置和LED引脚配置。注意引脚要点击"Signal Unpinning",否则无法导入gpio.c文件。

八、SConscript文件配置

配置完成后关闭STM32CubeMX软件,跳转到RT-Thread Studio。如果发现报错,可能是由于软件没有正确生成cubemx文件夹下的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')

九、解决报错

如果遇到找不到相关定义的错误,需要在STM32CubeMX中配置串口1。

十、main.C代码编写

在main.C中编写LED控制代码:

/*
 * 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程序编写

编写一个多线程控制LED的程序:

/*
 * 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);
    }
}

十三、运行结果

程序成功运行后,可以看到LED闪烁效果,同时在串口终端可以看到时钟消息被成功打印出来。

本文原文来自CSDN

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号