0%

【RT-Thread】学习笔记 --> STM32 Series BSP Production(BSP制作)

😊 转载请全文转载,并标明文章出处

环境介绍

  • 操作系统: Window10 企业版
  • IDE开发环境: RT-Thread Studio (Version: 1.1.3)
  • SDK版本: STM32H7 (Released V0.1.9)
  • STM32CubeMX 版本:Version 6.0.1
  • 硬件开发板: STM32H743IITx 最小系统开发板 (本人自己设计的最小系统)

STM32 Series BSP Production(BSP制作教程)

STM32 Series BSP Production 制作方法

BSP 的制作过程分为以下五个步骤:

  • 复制通用模板
  • 使用STM32CubeMX工具配置工程
  • 修改 BSP 中的 Kconfig 文件
  • 修改构建工程相关文件
  • 重新生成工程

1. 复制通用模板

1.1 下载 RT-Thread 源代码

下载请点击这里哦 ! ! !

 本人采用 Gitee (码云) 下载方式

RT-Thread_Source_code_download_address

RT-Thread_Source_code

1.2 打开源代码模板路径 rt-thread\bsp\stm32\libraries\templates\stm32h7xx。

RT-Thread_Source_code_template

1.3 创建 01_STM32H743_BSP 文件夹,将官方提供的模板 (stm32h7xx) 拷贝进来。

RT-Thread_Source_code_template

1.3.1 Board 文件夹下修改的内容
Board 下文件夹/文件 内容修改说明
CubeMX_Config STM32CubeMX工程
linker_scripts 工程构建相关文件(链接脚本)
board.c / board.h SystemClock_Config、Flash Memory Size、RAM Size
Kconfig System peripheral resources Configuration
SConscript System Chip Startup File

2. STM32CubeMX 工程配置

2.1 打开 CubeMX_Config.ioc 工程文件

CubeMX_Config.ioc 工程文件路径:*01_STM32H743_BSP\board\CubeMX_Config\CubeMX_Config.ioc *

STM32CubeMX

2.2 STM32CubeMX 工程生成
2.2.1 打开外部时钟设置

STM32CubeMX

2.2.2 下载方式配置 (SWD)

STM32CubeMX

2.2.3 调试串口配置 (UASRT1)

STM32CubeMX

2.2.4 EEPROM 配置 (IIC)

STM32CubeMX

2.2.5 系统时钟配置

STM32CubeMX

2.2.6 Project Manager 设置 (基本不需要修改)

STM32CubeMX

2.2.7 点击 GENERAYE CODE 直接生成工程

STM32CubeMX

2.2.8 CubeMX_Config目录下生成的文件如下

STM32CubeMX

3. Board.c / Board.h 文件修改

3.1 SystemClock_Config() 函数拷贝 (整个系统唯一拷贝的函数)

  board.c 文件中存放了SystemClock_Config()函数,该函数负责初始化系统时钟。如果 STM32CubeMX 对系统时钟重新配置,需要重新更新 SystemClock_Config() 函数。

  STM32CubeMX工具生成的 SystemClock_Config() 函数默认在 CubeMX_Config\Src\main.c,所以我们将main.c 文件中的 SystemClock_Config() 函数拷贝到 board.c 中。

/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

/**Supply configuration update enable
*/
MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);
/**Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY)
{

}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C2;
PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C123CLKSOURCE_D2PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
3.2 系统芯片 Flash 和 RAM 相关参数配置
  • STM32_FLASH_SIZE 和 STM32_SRAM_SIZE 两个参数需要修改 (针对实际芯片大小设置)
  • 本 BSP 使用的芯片为 STM32H743IITx 系列,Flash 大小 2024kBytes, RAM 大小 1024kBytes

board.h

4. Kconfig 文件修改 (初次制作BSP先不着急修改,后续根据Kconfig语法在修改)

Kconfig

5. 工程构建相关文件修改

5.1 linker_scripts 链接脚本修改

linker_scripts 文件夹下包含链接脚本,如图下图所示:

linker_scripts

5.1.1 MDK 链接脚本修改

linker_scripts

5.1.2 IAR 链接脚本修改

linker_scripts

5.1.3 GCC 链接脚本修改

linker_scripts

5.2 SConscript 脚本修改

  SConscript 脚本决定 MDK/IAR 工程的生成以及编译过程中要添加文件。

  修改芯片型号以及芯片启动文件的地址:

SConscript

  注意:如果在文件夹中找不到相应系列的 .s 文件,可能是多个系列的芯片重用了相同的启动文件,此时可以在 CubeMX 中生成目标芯片的工程,查看使用了哪个启动文件,然后再修改启动文件名。

5.3 工程模板修改
5.3.1 打开 template.uvprojx 工程

MDK

5.3.2 选择 BSP 使用的芯片型号

MDK

5.3.3 选择并配置下载方式

MDK

MDK

5.4 基于Env重新生成工程

Env 工具使用及配置,请点这里!!!

Env Tools 的路径必须是英文并且路径文件夹不能有空格!!!

5.4.1 重新生成 rtconfig.h 文件

输入menuconfig 命令后出现如下图所示的情况:

Env

注意:针对以上情况如何处理,出现这样的情况是因为脱离了官方源代码 rt-thread\bsp\stm 路径。

  • 首先,要知道自己下载 RT-Thread 源代码的路径 (本人 RT-Thread 源代码路径:D:\00_RT-Thread\00_RT-Thread_Source_code\rt-thread)

  • 修改第一个 Kconfig 文件

    Env

    config RTT_DIR
    string
    option env="RTT_ROOT"
    default "../../.."
    /*-----------------------------------------------------------*/
    config RTT_DIR
    string
    option env="RTT_ROOT"
    default "D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread"
    source "../libraries/Kconfig"
    source "board/Kconfig"
    /*-----------------------------------------------------------*/
    source "D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread/bsp/stm32/libraries/Kconfig"
    source "D:/00_RT-Thread/02_RT-Thread_BSP_Project/01_STM32H743_BSP/board/Kconfig"

Env

  • 修改第二个 Kconfig 文件

    Env

    source "../libraries/HAL_Drivers/Kconfig"
    /*-----------------------------------------------------------*/
    source "D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread/bsp/stm32/libraries/HAL_Drivers/Kconfig"

Env

然后在Env界面再次输入 menuconfig 命令对工程进行配置,并生成 rtconfig.h 文件。

Env

Env

5.4.2 重新生成 MDK / IAR 工程

输入 scons 命令后出现如下图所示的情况:

Env

注意:针对以上情况如何处理,出现这样的情况是因为脱离了官方源代码 rt-thread\bsp\stm 路径。

  • 首先,要知道自己下载 RT-Thread 源代码的路径 (本人 RT-Thread 源代码路径:D:\00_RT-Thread\00_RT-Thread_Source_code\rt-thread)

  • 修改 SConstruct 文件

    if os.getenv('RTT_ROOT'):
    RTT_ROOT = os.getenv('RTT_ROOT')
    else:
    RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..')

    /*-----------------------------------------------------------*/

    RTT_ROOT = 'D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread'
    SDK_ROOT = os.path.abspath('./')

    if os.path.exists(SDK_ROOT + '/libraries'):
    libraries_path_prefix = SDK_ROOT + '/libraries'
    else:
    libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'

    SDK_LIB = libraries_path_prefix
    Export('SDK_LIB')

    # prepare building environment
    objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)

    stm32_library = 'STM32H7xx_HAL'
    rtconfig.BSP_LIBRARY_TYPE = stm32_library

    # include drivers
    objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript')))

    # include libraries
    objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript')))

    /*-----------------------------------------------------------*/

    SDK_ROOT = os.path.abspath('D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread/bsp/stm32')

    if os.path.exists(SDK_ROOT + '/libraries'):
    libraries_path_prefix = SDK_ROOT + '/libraries'
    else:
    libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'

    SDK_LIB = libraries_path_prefix
    Export('SDK_LIB')

    # prepare building environment
    objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)

    stm32_library = 'D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread/bsp/stm32/libraries/STM32H7xx_HAL'
    rtconfig.BSP_LIBRARY_TYPE = stm32_library

    # include drivers
    objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript')))

    # include libraries
    objs.extend(SConscript(os.path.join(libraries_path_prefix, 'D:/00_RT-Thread/00_RT-Thread_Source_code/rt-thread/bsp/stm32/libraries/HAL_Drivers', 'SConscript')))

然后在Env界面再次输入 scons –target=mdk5 命令重新生成工程。

Env

Env

如果出现以上结果,新的 BSP 已经制作成功了,可以使用了 。

6. 文档参考