BSP瘦身指南说明 | 技术集结

描述


 

一. 为什么要实施BSP瘦身计划

当前RT-Thread仓库中BSP和.git内容占比约90%,而RT-Thread核心代码及文档仅占约100MB,约为3%。为进一步优化用户体验,我们计划了对现有BSP结构进行改进。过去,为了实现开箱即用的快速开发,HAL库被集成到BSP中,但随着支持的芯片和BSP数量增加,包体体积显著增长,且部分HAL内容可能未被充分利用。

为此,我们提出优化方案:将厂商SDK以软件包形式提供,保留RT-Thread的适配接口,用户可根据需求灵活选择所需芯片的SDK并集成到BSP中。这样既保持了快速开发的便利性,又显著减小了包体体积,让RT-Thread更轻量、高效,满足多样化的芯片应用场景。


 

本指南以stm32为例。


 

二. 操作流程

操作流程大致可以分为三步。以 stm32f4 为例。

(一). 软件包索引仓库更新

软件包目前统一放到下面的目录中,bsp中默认选中即可。

https://github.com/RT-Thread/packages/tree/master/peripherals/hal-sdk

1.fork一份软件包索引仓库

仓库地址:RT-Thread/packages: packages index repository for rt-thread.

STM32

2.将fork的仓库克隆到本地

  •  

git clone https://github.com/fengmuyou/packages.git

STM32

3. 打开本地仓库进行修改

在本地打开克隆的索引仓库,创建一个新的分支,在packages\peripherals\hal-sdk路径下创建stm32文件夹

  •  

git checkout -b "f4_hal" //创建一个新分支

STM32

4. 添加stm32f4索引文件夹

在stm32下添加stm32f4_cmsis_driver文件夹和stm32f4_hal_driver文件夹,在两个文件夹下分别添加Kconfig、package.json这两个文件

stm32f4_cmsis_drivers

1.Kconfig

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

# Kconfig file for package stm32f4_cmsis_drivermenuconfig PKG_USING_STM32F4_CMSIS_DRIVER    bool "STM32 F4 CMSIS driver package"    select PKG_USING_CMSIS_CORE    default nif PKG_USING_STM32F4_CMSIS_DRIVER    config PKG_STM32F4_CMSIS_DRIVER_PATH        string        default "/packages/peripherals/hal-sdk/stm32/stm32f4_cmsis_driver"    choice        prompt "Version"        help            Select the package version        config PKG_USING_STM32F4_CMSIS_DRIVER_LATEST_VERSION            bool "latest"    endchoice    config PKG_STM32F4_CMSIS_DRIVER_VER       string       default "latest"    if PKG_USING_STM32F4_CMSIS_DRIVER_LATEST_VERSIONendif

2.package.json

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

{  "name": "stm32f4_cmsis_driver",  "description": "STM32 F4 CMSIS driver package",  "description_zh": "STM32 F4 CMSIS 驱动包",  "enable": "PKG_USING_STM32F4_CMSIS_DRIVER",  "keywords": [    "stm32f4_cmsis_driver",    "STM32"  ],  "category": "peripherals",  "author": {    "name": "RT-Thread-packages",    "email": "package_team@rt-thread.com",    "github": "RT-Thread-packages"  },  "license": "Apache-2.0",  "repository": "https://github.com/RT-Thread-packages/stm32f4_cmsis_driver",  "icon": "unknown",  "homepage": "https://github.com/RT-Thread-packages/stm32f4_cmsis_driver#readme",  "doc": "unknown",  "site": [    {      "version": "latest",      "URL": "https://github.com/RT-Thread-packages/stm32f4_cmsis_driver.git",      "filename": "",      "VER_SHA": "master"    }  ]}

stm32f4_hal_driver

1.Kconfig

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

# Kconfig file for package stm32f4_hal_drivermenuconfig PKG_USING_STM32F4_HAL_DRIVER    bool "STM32 F4 HAL driver package"    select PKG_USING_STM32F4_CMSIS_DRIVER    default nif PKG_USING_STM32F4_HAL_DRIVER    config PKG_STM32F4_HAL_DRIVER_PATH        string        default "/packages/peripherals/hal-sdk/stm32/stm32f4_hal_driver"    choice        prompt "Version"        help            Select the package version        config PKG_USING_STM32F4_HAL_DRIVER_LATEST_VERSION            bool "latest"    endchoice    config PKG_STM32F4_HAL_DRIVER_VER       string       default "latest"    if PKG_USING_STM32F4_HAL_DRIVER_LATEST_VERSIONendif

2.package.json

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

{  "name": "stm32f4_hal_driver",  "description": "STM32 F4 HAL driver package",  "description_zh": "STM32 F4 HAL 驱动包",  "enable": "PKG_USING_STM32F4_HAL_DRIVER",  "keywords": [    "stm32f4_hal_driver",    "STM32"  ],  "category": "peripherals",  "author": {    "name": "RT-Thread-packages",    "email": "package_team@rt-thread.com",    "github": "RT-Thread-packages"  },  "license": "BSD-3-Clause",  "repository": "https://github.com/RT-Thread-packages/stm32f4_hal_driver",  "icon": "unknown",  "homepage": "https://github.com/RT-Thread-packages/stm32f4_hal_driver#readme",  "doc": "unknown",  "site": [    {      "version": "latest",      "URL": "https://github.com/RT-Thread-packages/stm32f4_hal_driver.git",      "filename": "",      "VER_SHA": "master"    }  ]}

注意!!!:仓库地址要保证正确,软件包才能正确地被拉下来。

STM32

5. 修改Kconfig文件

在stm32文件夹下的 Kconfig 文件里添加配置,确保能找到对应的Kconfig文件

STM32

6. 工作流文件修改

在workflows/aciont_tool.yml 文件里添加 pkgs --update,这个修改一次即可,后续添加其他软件包索引不用再修改。

STM32

7. 修改完之后进行提交

  •  
  •  
  •  

git add . git commit -m "add stm32_f4 软件包仓库索引"git push origin f4_hal

8. 创建pr,等待审核合并。

(二). 软件包仓库更新

1. 软件包分为cmsis与drivers

首先就是分别 fork cmsis 与 drivers 两个软件包仓库,并克隆仓库到本地,在本地创建一个新分支再进行修改。

2. 适配stm32f4_cmsis_driver

创建一个新的分支

  •  

git checkout -b f4_cmsis //创建一个新分支

添加 SConscript 文件

添加启动文件选择以及system_stm32f4xx.c文件,芯片型号宏定义在 stm32f4xx.h 文件下可以找到。

  •  

from building import *import os# Import environment variablesImport('env')# Get the current working directorycwd = GetCurrentDir()# Initialize include paths and source files listpath = [os.path.join(cwd, 'Include')]src = [os.path.join(cwd, 'Source', 'Templates', 'system_stm32f4xx.c')]# Map microcontroller units (MCUs) to their corresponding startup filesmcu_startup_files = {    'STM32F401xC': 'startup_stm32f401xc.s',    'STM32F401xE': 'startup_stm32f401xe.s',    'STM32F405xx': 'startup_stm32f405xx.s',    'STM32F407xx': 'startup_stm32f407xx.s',    'STM32F410Cx': 'startup_stm32f410cx.s',    'STM32F410Rx': 'startup_stm32f410rx.s',    'STM32F410Tx': 'startup_stm32f410tx.s',    'STM32F411xE': 'startup_stm32f411xe.s',    'STM32F412Cx': 'startup_stm32f412cx.s',    'STM32F412Rx': 'startup_stm32f412rx.s',    'STM32F412Vx': 'startup_stm32f412vx.s',    'STM32F412Zx': 'startup_stm32f412zx.s',    'STM32F413xx': 'startup_stm32f413xx.s',    'STM32F415xx': 'startup_stm32f415xx.s',    'STM32F417xx': 'startup_stm32f417xx.s',    'STM32F423xx': 'startup_stm32f423xx.s',    'STM32F427xx': 'startup_stm32f427xx.s',    'STM32F429xx': 'startup_stm32f429xx.s',    'STM32F437xx': 'startup_stm32f437xx.s',    'STM32F439xx': 'startup_stm32f439xx.s',    'STM32F446xx': 'startup_stm32f446xx.s',    'STM32F469xx': 'startup_stm32f469xx.s',    'STM32F479xx': 'startup_stm32f479xx.s',}# Check each defined MCU, match the platform and append the appropriate startup filefor mcu, startup_file in mcu_startup_files.items():    if mcu in env.get('CPPDEFINES', []):        if rtconfig.PLATFORM in ['gcc', 'llvm-arm']:            src += [os.path.join(cwd, 'Source', 'Templates', 'gcc', startup_file)]        elif rtconfig.PLATFORM in ['armcc', 'armclang']:            src += [os.path.join(cwd, 'Source', 'Templates', 'arm', startup_file)]        elif rtconfig.PLATFORM in ['iccarm']:            src += [os.path.join(cwd, 'Source', 'Templates', 'iar', startup_file)]        break# Define the build groupgroup = DefineGroup('STM32F4-CMSIS', src, depend=['PKG_USING_STM32F4_CMSIS_DRIVER'], CPPPATH=path)# Return the build groupReturn('group')

添加stm32_update.py文件,并运行,对启动文件进行修改

  •  

python stm32_update.py //运行stm32_update.py

  •  
  •  

# Copyright (c) 2006-2022, RT-Thread Development Team## SPDX-License-Identifier: Apache-2.0## Change Logs:# Date           Author       Notes# 2021-10-11     Meco Man     First version# This file is suggested to use under Linux environment.# > python stm32_update.py# update STM32 startup assembly language file:# 1.replace main to entry (GCC)# 2.reduce the heap size as 0x000 (Keil IAR)# 3.extend the GCC stack size as 0x400, which is the same as Keil and IAR startup files.import osimport re# replace 'bl main' to 'bl entry'def stm32update_main2entry(path):    oldline = ''    newline = ''    for root, dirs, files in os.walk(path):        for file in files:            if os.path.splitext(file)[1] == '.s': # find .s files (Keil MDK)                file_path = os.path.join(root,file)                flag_need_replace = False                with open(file_path,'r+',) as f:                    while True:                        line = f.readline()                        if line == '':                            break                        elif ('bl' in line) and ('main' in line): # find 'bl main'                            oldline = line # bl main                            newline = line.replace('main', 'entry') # use 'entry' to replace 'main'                            flag_need_replace = True # mark that need to be replaced                            break                    if (flag_need_replace == True): # use 'entry' to replace 'main'                        f.seek(0)                        content = f.read()                        f.seek(0)                        f.truncate()                        newcontent = content.replace(oldline, newline)                        f.write(newcontent)#reduce the heap size as 0x000def stm32update_heap2zero(path):    oldline = ''    newline = ''    for root, dirs, files in os.walk(path):        for file in files:            file_path = os.path.join(root,file)            if os.path.splitext(file)[1] == '.s': # find .s files (Keil MDK)                with open(file_path,'r+',) as f:                    flag_need_replace = False                    while True:                        line = f.readline()                        if line == '':                            break                        re_result = re.match('\\s*Heap_Size\\s+EQU\\s+0[xX][0-9a-fA-F]+', line)                        if re_result != None:                            oldline = line                            newline = re.sub('0[xX][0-9a-fA-F]+','0x00000000', oldline)                            flag_need_replace = True                            break                    if flag_need_replace == True:                        f.seek(0)                        content = f.read()                        f.seek(0)                        f.truncate()                        newcontent = content.replace(oldline, newline)                        f.write(newcontent)            elif os.path.splitext(file)[1] == '.icf': # find .icf files (IAR)                with open(file_path,'r+',) as f:                    flag_need_replace = False                    while True:                        line = f.readline()                        if line == '':                            break                        re_result = re.match('\\s*define\\s+symbol\\s+__ICFEDIT_size_heap__\\s*=\\s*0[xX][0-9a-fA-F]+', line)                        if re_result != None:                            oldline = line                            newline = re.sub('0[xX][0-9a-fA-F]+','0x000', oldline)                            flag_need_replace = True                            break                    if flag_need_replace == True:                        f.seek(0)                        content = f.read()                        f.seek(0)                        f.truncate()                        newcontent = content.replace(oldline, newline)                        f.write(newcontent)            elif os.path.splitext(file)[1] == '.lds': # find .lds files (GCC)                with open(file_path,'r+',) as f:                    flag_need_replace = False                    while True:                        line = f.readline()                        if line == '':                            break                        re_result = re.match('\\s*_system_stack_size\\s*=\\s*0[xX][0-9a-fA-F]+', line)                        if re_result != None:                            oldline = line                            newline = re.sub('0[xX][0-9a-fA-F]+','0x400', oldline)                            flag_need_replace = True                            break                    if flag_need_replace == True:                        f.seek(0)                        content = f.read()                        f.seek(0)                        f.truncate()                        newcontent = content.replace(oldline, newline)                        f.write(newcontent)def stm32_update(path):    stm32update_main2entry(path)    stm32update_heap2zero(path)if __name__ == "__main__":    stm32_update(os.getcwd())    print("STM32 startup assembly language file update successfully!")

ps:对启动文件修改主要是将gcc下启动文件的入口函数由 main 改成 entry。

STM32

以及将arm下启动文件的堆的大小改为0。

STM32

修改完成后提交

  •  
  •  
  •  

git add . git commit -m "adapt stm32f4 cmsis for rtt"git push origin f4_cmsis

创建pr,等待审核合并。

3. 适配stm32f4_hal_driver

创建一个新的分支

  •  

git checkout -b f4_drivers //创建一个新分支

添加 SConscript 文件,可根据 rt-thread\bsp\stm32\libraries\STM32F4xx_HAL 文件夹下的 SConscript 对应着修改,改变文件引用的路径。

  •  
  •  

from building import *import oscwd = GetCurrentDir()path = [os.path.join(cwd, 'Inc')]src_path = os.path.join(cwd, 'Src')path += [os.path.join(cwd, 'Inc/Legacy')]CPPDEFINES = ['USE_HAL_DRIVER']src = [os.path.join(src_path, 'stm32f4xx_hal.c'),os.path.join(src_path, 'stm32f4xx_hal_cec.c'),os.path.join(src_path, 'stm32f4xx_hal_cortex.c'),os.path.join(src_path, 'stm32f4xx_hal_crc.c'),os.path.join(src_path, 'stm32f4xx_hal_cryp.c'),os.path.join(src_path, 'stm32f4xx_hal_cryp_ex.c'),os.path.join(src_path, 'stm32f4xx_hal_dma.c'),os.path.join(src_path, 'stm32f4xx_hal_dma_ex.c'),os.path.join(src_path, 'stm32f4xx_hal_pwr.c'),os.path.join(src_path, 'stm32f4xx_hal_pwr_ex.c'),os.path.join(src_path, 'stm32f4xx_hal_rcc.c'),os.path.join(src_path, 'stm32f4xx_hal_rcc_ex.c'),os.path.join(src_path, 'stm32f4xx_hal_rng.c'),os.path.join(src_path, 'stm32f4xx_hal_gpio.c'),]if GetDepend(['RT_USING_SERIAL']) or GetDepend(['RT_USING_NANO', 'RT_USING_CONSOLE']):    src += [os.path.join(src_path, 'stm32f4xx_hal_uart.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_usart.c')]if GetDepend(['RT_USING_I2C']):    src += [os.path.join(src_path, 'stm32f4xx_hal_i2c.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_i2c_ex.c')]if GetDepend(['RT_USING_SPI']):    src += [os.path.join(src_path, 'stm32f4xx_hal_spi.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_qspi.c')]if GetDepend(['RT_USING_USB']):    src += [os.path.join(src_path, 'stm32f4xx_hal_pccard.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_pcd.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_pcd_ex.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_hcd.c')]    src += [os.path.join(src_path, 'stm32f4xx_ll_usb.c')]if GetDepend(['RT_USING_CAN']):    src += [os.path.join(src_path, 'stm32f4xx_hal_can.c')]if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']) or GetDepend(['RT_USING_PULSE_ENCODER']):    src += [os.path.join(src_path, 'stm32f4xx_hal_tim.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_tim_ex.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_lptim.c')]if GetDepend(['BSP_USING_ETH']):    if GetDepend(['BSP_ETH_LEGACY_MODULE_ENABLED']):        src  += [os.path.join(src_path, 'Legacy/stm32f4xx_hal_eth.c')]    else:        src += [os.path.join(src_path, 'stm32f4xx_hal_eth.c')]if GetDepend(['RT_USING_ADC']):    src += [os.path.join(src_path, 'stm32f4xx_hal_adc.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_adc_ex.c')]if GetDepend(['RT_USING_DAC']):    src += [os.path.join(src_path, 'stm32f4xx_hal_dac.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_dac_ex.c')]if GetDepend(['RT_USING_RTC']):    src += [os.path.join(src_path, 'stm32f4xx_hal_rtc.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_rtc_ex.c')]if GetDepend(['RT_USING_WDT']):    src += [os.path.join(src_path, 'stm32f4xx_hal_iwdg.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_wwdg.c')]if GetDepend(['RT_USING_SDIO']):    src += [os.path.join(src_path, 'stm32f4xx_ll_sdmmc.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_sd.c')]if GetDepend(['RT_USING_AUDIO']):    src += [os.path.join(src_path, 'stm32f4xx_hal_i2s.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_i2s_ex.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_sai.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_sai_ex.c')]if GetDepend(['RT_USING_MTD_NOR']):    src += [os.path.join(src_path, 'stm32f4xx_hal_nor.c')]if GetDepend(['RT_USING_MTD_NAND']):    src += [os.path.join(src_path, 'stm32f4xx_hal_nand.c')]if GetDepend(['BSP_USING_FMC']):    src += [os.path.join(src_path, 'stm32f4xx_ll_fmc.c')]    src += [os.path.join(src_path, 'stm32f4xx_ll_fsmc.c')]if GetDepend(['BSP_USING_SDRAM']):    src += [os.path.join(src_path, 'stm32f4xx_hal_sdram.c')]if GetDepend(['BSP_USING_EXT_FMC_IO']):    src += [os.path.join(src_path, 'stm32f4xx_hal_sram.c')]if GetDepend(['BSP_USING_ON_CHIP_FLASH']):    src += [os.path.join(src_path, 'stm32f4xx_hal_flash.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_flash_ex.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_flash_ramfunc.c')]if GetDepend(['BSP_USING_LTDC']):    src += [os.path.join(src_path, 'stm32f4xx_hal_ltdc.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_ltdc_ex.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_dma2d.c')]    src += [os.path.join(src_path, 'stm32f4xx_ll_dma2d.c')]    src += [os.path.join(src_path, 'stm32f4xx_hal_dsi.c')]group = DefineGroup('STM32F4-HAL', src, depend = ['PKG_USING_STM32F4_HAL_DRIVER'], CPPPATH = path, CPPDEFINES = CPPDEFINES)Return('group')

修改完成后提交

  •  
  •  
  •  

git add .git commit -m "adapt stm32f4 drivers for rtt"git push origin f4_drivers

创建pr,等待审核合并。

(三). 主线仓库更新

这里bsp的修改以stm32f407-rt-spark为例,具体的需要把f4系列所有的bsp都进行修改,编译测试通过后再提交。

1. 准备工作

fork 一份最新的主线仓库,克隆到本地,基于master分支创建一个新的分支。

创建一个新的分支

  •  

git checkout -b f4_sdk

2. 在主线仓库目录(bsp\stm32\libraries\Kconfig)中 select PKG_USING_STM32xx_HAL_DRIVER

STM32

3. 修改SConstruct文件

STM32

4. board文件夹下的SConscript

STM32

5. 在port文件夹下添加SConscript文件

STM32

ps: stm32f407-rt-spark 的 port 文件夹下有SConscript文件,我们只需简单的修改即可。有些bsp的port文件下没有SConscript文件,需要我们自己添加,可以参考这里进行修。

6. 在 README.md 文件添加说明

在快速上手下添加说明

中文版本

  •  
  •  
  •  
  •  
  •  

**请注意!!!**在执行编译工作前请先打开ENV执行以下指令(该指令用于拉取必要的HAL库及CMSIS库,否则无法通过编译):```bashpkgs --update```

英文版本

  •  
  •  
  •  
  •  
  •  

**Attention please!!!**Before the compilation work, please open ENV and execute the following command (this command is used to pull the necessary HAL library and CMSIS library, otherwise it cannot be compiled):```bashpkgs --update```

7.编译结果

确保能编译 packages 下的 f4_hal 文件

STM32

8. 烧录测试

将rt-thread.elf文件烧录到板子上,观察是否能够正常运行。

STM32

ps:板子支持的一些外设也需要在env中开启,进行编译测试。

9. 删除主线上的STM32F4_HAL驱动

ps: 请把f4系列所有的bsp都进行修改,测试通过后在删除主线上的 STM32F4_HAL 驱动。

STM32

10.修改工作流文件

在workflows/aciont_tool.yml 文件里添加 pkgs --update,这个修改一次即可,后续添加其他修改其他bsp不用再修改。

STM32

11.提交到远程仓库

全部测试没问题后,提交的远程仓库。

  •  
  •  
  •  

git add .git commit -m "bsp:Separate STM32F4 HAL drivers"git push origin f4_sdk

12. 创建pr,等待审核合并。

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分