一. 為什么要實施BSP瘦身計劃
當(dāng)前RT-Thread倉庫中BSP和.git內(nèi)容占比約90%,而RT-Thread核心代碼及文檔僅占約100MB,約為3%。為進一步優(yōu)化用戶體驗,我們計劃了對現(xiàn)有BSP結(jié)構(gòu)進行改進。過去,為了實現(xiàn)開箱即用的快速開發(fā),HAL庫被集成到BSP中,但隨著支持的芯片和BSP數(shù)量增加,包體體積顯著增長,且部分HAL內(nèi)容可能未被充分利用。
為此,我們提出優(yōu)化方案:將廠商SDK以軟件包形式提供,保留RT-Thread的適配接口,用戶可根據(jù)需求靈活選擇所需芯片的SDK并集成到BSP中。這樣既保持了快速開發(fā)的便利性,又顯著減小了包體體積,讓RT-Thread更輕量、高效,滿足多樣化的芯片應(yīng)用場景。
本指南以stm32為例。
二. 操作流程
操作流程大致可以分為三步。以 stm32f4 為例。
(一). 軟件包索引倉庫更新
軟件包目前統(tǒng)一放到下面的目錄中,bsp中默認(rèn)選中即可。
https://github.com/RT-Thread/packages/tree/master/peripherals/hal-sdk
1.fork一份軟件包索引倉庫
倉庫地址:RT-Thread/packages: packages index repository for rt-thread.
2.將fork的倉庫克隆到本地
gitclonehttps://github.com/fengmuyou/packages.git
3. 打開本地倉庫進行修改
在本地打開克隆的索引倉庫,創(chuàng)建一個新的分支,在packages\peripherals\hal-sdk路徑下創(chuàng)建stm32文件夾
git checkout -b"f4_hal"http://創(chuàng)建一個新分支
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 defaultnifPKG_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" ifPKG_USING_STM32F4_CMSIS_DRIVER_LATEST_VERSIONendif
2.package.json
{ "name":"stm32f4_cmsis_driver", "description":"STM32 F4 CMSIS driver package", "description_zh":"STM32 F4 CMSIS 驅(qū)動包", "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 defaultnifPKG_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" ifPKG_USING_STM32F4_HAL_DRIVER_LATEST_VERSIONendif
2.package.json
{ "name":"stm32f4_hal_driver", "description":"STM32 F4 HAL driver package", "description_zh":"STM32 F4 HAL 驅(qū)動包", "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" } ]}
注意!?。。簜}庫地址要保證正確,軟件包才能正確地被拉下來。
5. 修改Kconfig文件
在stm32文件夾下的 Kconfig 文件里添加配置,確保能找到對應(yīng)的Kconfig文件
6. 工作流文件修改
在workflows/aciont_tool.yml 文件里添加 pkgs --update,這個修改一次即可,后續(xù)添加其他軟件包索引不用再修改。
7. 修改完之后進行提交
gitadd.gitcommit-m "add stm32_f4 軟件包倉庫索引"git push origin f4_hal
8. 創(chuàng)建pr,等待審核合并。
(二). 軟件包倉庫更新
1. 軟件包分為cmsis與drivers
首先就是分別 forkcmsis與 drivers 兩個軟件包倉庫,并克隆倉庫到本地,在本地創(chuàng)建一個新分支再進行修改。
2. 適配stm32f4_cmsis_driver
創(chuàng)建一個新的分支
git checkout -b f4_cmsis//創(chuàng)建一個新分支
添加 SConscript 文件
添加啟動文件選擇以及system_stm32f4xx.c文件,芯片型號宏定義在 stm32f4xx.h 文件下可以找到。
frombuildingimport*importos# 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 fileformcu, startup_fileinmcu_startup_files.items(): ifmcuinenv.get('CPPDEFINES', []): ifrtconfig.PLATFORMin['gcc','llvm-arm']: src += [os.path.join(cwd,'Source','Templates','gcc', startup_file)] elifrtconfig.PLATFORMin['armcc','armclang']: src += [os.path.join(cwd,'Source','Templates','arm', startup_file)] elifrtconfig.PLATFORMin['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.importosimportre# replace 'bl main' to 'bl entry'defstm32update_main2entry(path): oldline ='' newline ='' forroot, dirs, filesinos.walk(path): forfileinfiles: ifos.path.splitext(file)[1] =='.s':# find .s files (Keil MDK) file_path = os.path.join(root,file) flag_need_replace =False withopen(file_path,'r+',)asf: whileTrue: line = f.readline() ifline =='': break elif('bl'inline)and('main'inline):# 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 0x000defstm32update_heap2zero(path): oldline ='' newline ='' forroot, dirs, filesinos.walk(path): forfileinfiles: file_path = os.path.join(root,file) ifos.path.splitext(file)[1] =='.s':# find .s files (Keil MDK) withopen(file_path,'r+',)asf: flag_need_replace =False whileTrue: line = f.readline() ifline =='': break re_result = re.match('\\s*Heap_Size\\s+EQU\\s+0[xX][0-9a-fA-F]+', line) ifre_result !=None: oldline = line newline = re.sub('0[xX][0-9a-fA-F]+','0x00000000', oldline) flag_need_replace =True break ifflag_need_replace ==True: f.seek(0) content = f.read() f.seek(0) f.truncate() newcontent = content.replace(oldline, newline) f.write(newcontent) elifos.path.splitext(file)[1] =='.icf':# find .icf files (IAR) withopen(file_path,'r+',)asf: flag_need_replace =False whileTrue: line = f.readline() ifline =='': break re_result = re.match('\\s*define\\s+symbol\\s+__ICFEDIT_size_heap__\\s*=\\s*0[xX][0-9a-fA-F]+', line) ifre_result !=None: oldline = line newline = re.sub('0[xX][0-9a-fA-F]+','0x000', oldline) flag_need_replace =True break ifflag_need_replace ==True: f.seek(0) content = f.read() f.seek(0) f.truncate() newcontent = content.replace(oldline, newline) f.write(newcontent) elifos.path.splitext(file)[1] =='.lds':# find .lds files (GCC) withopen(file_path,'r+',)asf: flag_need_replace =False whileTrue: line = f.readline() ifline =='': break re_result = re.match('\\s*_system_stack_size\\s*=\\s*0[xX][0-9a-fA-F]+', line) ifre_result !=None: oldline = line newline = re.sub('0[xX][0-9a-fA-F]+','0x400', oldline) flag_need_replace =True break ifflag_need_replace ==True: f.seek(0) content = f.read() f.seek(0) f.truncate() newcontent = content.replace(oldline, newline) f.write(newcontent)defstm32_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下啟動文件的入口函數(shù)由 main 改成 entry。
以及將arm下啟動文件的堆的大小改為0。
修改完成后提交
gitadd.gitcommit-m "adapt stm32f4 cmsis for rtt"git push origin f4_cmsis
創(chuàng)建pr,等待審核合并。
3. 適配stm32f4_hal_driver
創(chuàng)建一個新的分支
git checkout -b f4_drivers//創(chuàng)建一個新分支
添加 SConscript 文件,可根據(jù) rt-thread\bsp\stm32\libraries\STM32F4xx_HAL 文件夾下的 SConscript 對應(yīng)著修改,改變文件引用的路徑。
frombuilding 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'),]ifGetDepend(['RT_USING_SERIAL'])orGetDepend(['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')]ifGetDepend(['RT_USING_I2C']): src += [os.path.join(src_path,'stm32f4xx_hal_i2c.c')] src += [os.path.join(src_path,'stm32f4xx_hal_i2c_ex.c')]ifGetDepend(['RT_USING_SPI']): src += [os.path.join(src_path,'stm32f4xx_hal_spi.c')] src += [os.path.join(src_path,'stm32f4xx_hal_qspi.c')]ifGetDepend(['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')]ifGetDepend(['RT_USING_CAN']): src += [os.path.join(src_path,'stm32f4xx_hal_can.c')]ifGetDepend(['RT_USING_HWTIMER'])orGetDepend(['RT_USING_PWM'])orGetDepend(['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')]ifGetDepend(['BSP_USING_ETH']): ifGetDepend(['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')]ifGetDepend(['RT_USING_ADC']): src += [os.path.join(src_path,'stm32f4xx_hal_adc.c')] src += [os.path.join(src_path,'stm32f4xx_hal_adc_ex.c')]ifGetDepend(['RT_USING_DAC']): src += [os.path.join(src_path,'stm32f4xx_hal_dac.c')] src += [os.path.join(src_path,'stm32f4xx_hal_dac_ex.c')]ifGetDepend(['RT_USING_RTC']): src += [os.path.join(src_path,'stm32f4xx_hal_rtc.c')] src += [os.path.join(src_path,'stm32f4xx_hal_rtc_ex.c')]ifGetDepend(['RT_USING_WDT']): src += [os.path.join(src_path,'stm32f4xx_hal_iwdg.c')] src += [os.path.join(src_path,'stm32f4xx_hal_wwdg.c')]ifGetDepend(['RT_USING_SDIO']): src += [os.path.join(src_path,'stm32f4xx_ll_sdmmc.c')] src += [os.path.join(src_path,'stm32f4xx_hal_sd.c')]ifGetDepend(['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')]ifGetDepend(['RT_USING_MTD_NOR']): src += [os.path.join(src_path,'stm32f4xx_hal_nor.c')]ifGetDepend(['RT_USING_MTD_NAND']): src += [os.path.join(src_path,'stm32f4xx_hal_nand.c')]ifGetDepend(['BSP_USING_FMC']): src += [os.path.join(src_path,'stm32f4xx_ll_fmc.c')] src += [os.path.join(src_path,'stm32f4xx_ll_fsmc.c')]ifGetDepend(['BSP_USING_SDRAM']): src += [os.path.join(src_path,'stm32f4xx_hal_sdram.c')]ifGetDepend(['BSP_USING_EXT_FMC_IO']): src += [os.path.join(src_path,'stm32f4xx_hal_sram.c')]ifGetDepend(['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')]ifGetDepend(['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')
修改完成后提交
gitadd.gitcommit-m "adapt stm32f4 drivers for rtt"git push origin f4_drivers
創(chuàng)建pr,等待審核合并。
(三). 主線倉庫更新
這里bsp的修改以stm32f407-rt-spark為例,具體的需要把f4系列所有的bsp都進行修改,編譯測試通過后再提交。
1. 準(zhǔn)備工作
fork 一份最新的主線倉庫,克隆到本地,基于master分支創(chuàng)建一個新的分支。
創(chuàng)建一個新的分支
git checkout -bf4_sdk
2. 在主線倉庫目錄(bsp\stm32\libraries\Kconfig)中 select PKG_USING_STM32xx_HAL_DRIVER
3. 修改SConstruct文件
4. board文件夾下的SConscript
5. 在port文件夾下添加SConscript文件
ps: stm32f407-rt-spark 的 port 文件夾下有SConscript文件,我們只需簡單的修改即可。有些bsp的port文件下沒有SConscript文件,需要我們自己添加,可以參考這里進行修。
6. 在 README.md 文件添加說明
在快速上手下添加說明
中文版本
**請注意?。?!**在執(zhí)行編譯工作前請先打開ENV執(zhí)行以下指令(該指令用于拉取必要的HAL庫及CMSIS庫,否則無法通過編譯):```bashpkgs --update```
英文版本
**Attentionplease!?。?*Beforethe compilation work, please openENVand execute the following command (thiscommand is used to pull the necessaryHALlibrary andCMSISlibrary, otherwise it cannot be compiled):```bashpkgs --update```
7.編譯結(jié)果
確保能編譯 packages 下的 f4_hal 文件
8. 燒錄測試
將rt-thread.elf文件燒錄到板子上,觀察是否能夠正常運行。
ps:板子支持的一些外設(shè)也需要在env中開啟,進行編譯測試。
9. 刪除主線上的STM32F4_HAL驅(qū)動
ps: 請把f4系列所有的bsp都進行修改,測試通過后在刪除主線上的 STM32F4_HAL 驅(qū)動。
10.修改工作流文件
在workflows/aciont_tool.yml 文件里添加 pkgs --update,這個修改一次即可,后續(xù)添加其他修改其他bsp不用再修改。
11.提交到遠(yuǎn)程倉庫
全部測試沒問題后,提交的遠(yuǎn)程倉庫。
gitadd.gitcommit-m "bsp:Separate STM32F4 HAL drivers"git push origin f4_sdk
12. 創(chuàng)建pr,等待審核合并。
-
STM32
+關(guān)注
關(guān)注
2287文章
10988瀏覽量
361592 -
BSP
+關(guān)注
關(guān)注
1文章
91瀏覽量
26670 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1357瀏覽量
41415
發(fā)布評論請先 登錄
BSP是如何構(gòu)造的?
Vivado工程源碼大瘦身
AXU4EV-E開發(fā)板提供的BSP(板級支持包)說明
NUCLEO-WL55JC2開發(fā)板的BSP(板級支持包)說明
基于VxWorks的BSP技術(shù)分析
MQX BSP移植指南

bsp是什么
如何開發(fā)BSP中的BootLoader

ARM開發(fā)教程之ARM體系的嵌入式系統(tǒng)BSP的程序的設(shè)計說明

嵌入式中的BSP---BSP到底是什么

評論