如何进行GD32F103系列的BSP制作

2024-01-17  

熟悉RT-Thread的朋友都知道,RT-Thread提供了许多BSP,但不是所有的板子都能找到相应的BSP,这时就需要移植新的BSP。RT-Thread的所有BSP中,最完善的BSP就是STM32系列,但从2020年下半年开始,国内出现史无前例的芯片缺货潮,我们参考STM32F103系列进行GD32F103系列的BSP制作。


我使用的是GD32F103VET6芯片进行移植,以下是本人的gitee库。

Gitee//gitee.com/zhaodhajhdjahwd/gd32-bsp


1 BSP 框架制作

在具体移植GD32407V-START的BSP之前,先做好GD32的BSP架构。BSP 框架结构如下图所示:在这里插入图片描述
6a344936-d19f-11ec-bce3-dac502259ad0.pngGD32的BSP架构主要分为三个部分:libraries、tools和具体的Boards,其中libraries包含了GD32的通用库,包括每个系列的HAL以及适配RT-Thread的drivers;tools是生成工程的Python脚本工具;另外就是Boards文件,当然这里的Boards有很多,我这里值列举了GD32103C-eval。这里先谈谈libraries和tools的构建,然后在后文单独讨论具体板级BSP的制作。1.1 Libraries构建
Libraries文件夹包含兆易创新提供的HAL库,这个直接在兆易创新的官网就可以下载。

http://www.gd32mcu.com/cn/download/0?kw=GD32F1


然后将HAL库(GD32F10x_Firmware_Library)复制到libraries目录下,重命名为GD32F10x_Firmware_Library,其他的系列类似

6a4debca-d19f-11ec-bce3-dac502259ad0.png
GD32F10x_Firmware_Library就是官方的文件,基本是不用动的,只是在文件夹中需要添加构建工程的脚本文件SConscript,其实也就是Python脚本。6a9bf8a6-d19f-11ec-bce3-dac502259ad0.pngSConscript文件的内容如下:

 1importrtconfig

 2frombuildingimport*

 3

 4#getcurrentdirectory

 5cwd=GetCurrentDir()

 6

 7#ThesetofsourcefilesassociatedwiththisSConscriptfile.

 8

 9src=Split('''

10CMSIS/GD/GD32F10x/Source/system_gd32f10x.c

11GD32F10x_standard_peripheral/Source/gd32f10x_gpio.c

12GD32F10x_standard_peripheral/Source/gd32f10x_rcu.c

13GD32F10x_standard_peripheral/Source/gd32f10x_exti.c

14GD32F10x_standard_peripheral/Source/gd32f10x_misc.c

15''')

16

17ifGetDepend(['RT_USING_SERIAL']):

18src+=['GD32F10x_standard_peripheral/Source/gd32f10x_usart.c']

19

20ifGetDepend(['RT_USING_I2C']):

21src+=['GD32F10x_standard_peripheral/Source/gd32f10x_i2c.c']

22

23ifGetDepend(['RT_USING_SPI']):

24src+=['GD32F10x_standard_peripheral/Source/gd32f10x_spi.c']

25

26ifGetDepend(['RT_USING_CAN']):

27src+=['GD32F10x_standard_peripheral/Source/gd32f10x_can.c']

28

29ifGetDepend(['BSP_USING_ETH']):

30src+=['GD32F10x_standard_peripheral/Source/gd32f10x_enet.c']

31

32ifGetDepend(['RT_USING_ADC']):

33src+=['GD32F10x_standard_peripheral/Source/gd32f10x_adc.c']

34

35ifGetDepend(['RT_USING_DAC']):

36src+=['GD32F10x_standard_peripheral/Source/gd32f10x_dac.c']

37

38ifGetDepend(['RT_USING_HWTIMER']):

39src+=['GD32F10x_standard_peripheral/Source/gd32f10x_timer.c']

40

41ifGetDepend(['RT_USING_RTC']):

42src+=['GD32F10x_standard_peripheral/Source/gd32f10x_rtc.c']

43src+=['GD32F10x_standard_peripheral/Source/gd32f10x_pmu.c']

44

45ifGetDepend(['RT_USING_WDT']):

46src+=['GD32F10x_standard_peripheral/Source/gd32f10x_wwdgt.c']

47src+=['GD32F10x_standard_peripheral/Source/gd32f10x_fwdgt.c']

48

49ifGetDepend(['RT_USING_SDIO']):

50src+=['GD32F10x_standard_peripheral/Source/gd32f10x_sdio.c']

51

52path=[

53cwd+'/CMSIS/GD/GD32F10x/Include',

54cwd+'/CMSIS',

55cwd+'/GD32F10x_standard_peripheral/Include',]

56

57CPPDEFINES=['USE_STDPERIPH_DRIVER']

58

59group=DefineGroup('Libraries',src,depend=[''],CPPPATH=path,CPPDEFINES=CPPDEFINES)

60

61Return('group')


该文件主要的作用就是添加库文件和头文件路径,一部分文件是属于基础文件,因此直接调用Python库的Split包含,另外一部分文件是根据实际的应用需求添加的。

接下来说说Kconfig文件,这里是对内核和组件的功能进行配置,对RT-Thread的组件进行自由裁剪。如果使用RT-Thread studio,则通过RT-Thread Setting可以体现Kconfig文件的作用。

6aecf5c6-d19f-11ec-bce3-dac502259ad0.jpg


如果使用ENV环境,则在使用 menuconfig配置和裁剪 RT-Thread时体现。


6afe5e2e-d19f-11ec-bce3-dac502259ad0.jpg

后面所有的Kconfig文件都是一样的逻辑。下表列举一些常用的Kconfig句法规则。

6b17c65c-d19f-11ec-bce3-dac502259ad0.jpg

Kconfig的语法规则网上资料很多,自行去学习吧。

bsp/gd32/Kconfig内容如下:

 1configSOC_FAMILY_GD32

 2bool

 3

 4configSOC_SERIES_GD32F1

 5bool

 6selectARCH_ARM_CORTEX_M3

 7selectSOC_FAMILY_GD32

 8

 9configSOC_SERIES_GD32F2

10bool

11selectARCH_ARM_CORTEX_M3

12selectSOC_FAMILY_GD32

13

14configSOC_SERIES_GD32F3

15bool

16selectARCH_ARM_CORTEX_M4

17selectSOC_FAMILY_GD32

18

19configSOC_SERIES_GD32F4

20bool

21selectARCH_ARM_CORTEX_M4

22selectSOC_FAMILY_GD32


最后谈谈HAL_Drivers,这个文件夹就是GD32的外设驱动文件夹,为上层应用提供调用接口。

6b300a00-d19f-11ec-bce3-dac502259ad0.jpg

好了,先看

E:RT_ThreadGD32_BSPrt_thread_codebspgd32f103librariesgd32_drivers/SConscript文件。


 1Import('RTT_ROOT')

 2Import('rtconfig')

 3frombuildingimport*

 4

 5cwd=GetCurrentDir()

 6

 7#addthegeneraldrivers.

 8src=Split("""

 9""")

10

11#addpindrivers.

12ifGetDepend('RT_USING_PIN'):

13src+=['drv_gpio.c']

14

15#addusartdrivers.

16ifGetDepend(['RT_USING_SERIAL']):

17src+=['drv_usart.c']

18

19#addi2cdrivers.

20ifGetDepend(['RT_USING_I2C','RT_USING_I2C_BITOPS']):

21ifGetDepend('BSP_USING_I2C0')orGetDepend('BSP_USING_I2C1')orGetDepend('BSP_USING_I2C2')orGetDepend('BSP_USING_I2C3'):

22src+=['drv_soft_i2c.c']

23

24#addspidrivers.

25ifGetDepend('RT_USING_SPI'):

26src+=['drv_spi.c']

27

28#addspiflashdrivers.

29ifGetDepend('RT_USING_SFUD'):

30src+=['drv_spi_flash.c','drv_spi.c']

31

32ifGetDepend('RT_USING_WDT'):

33src+=['drv_wdt.c']

34

35ifGetDepend('RT_USING_RTC'):

36src+=['drv_rtc.c']

37

38ifGetDepend('RT_USING_HWTIMER'):

39src+=['drv_hwtimer.c']

40

41ifGetDepend('RT_USING_ADC'):

42src+=['drv_adc.c']

43

44path=[cwd]

45

46group=DefineGroup('Drivers',src,depend=[''],CPPPATH=path)

47

48Return('group')

E:RT_ThreadGD32_BSPrt_thread_codebspgd32f103librariesgd32_drivers/Kconfig文件结构如下:


 1ifBSP_USING_USBD

 2configBSP_USBD_TYPE_FS

 3bool

 4#"USBFullSpeed(FS)Core"

 5configBSP_USBD_TYPE_HS

 6bool

 7#"USBHighSpeed(HS)Core"

 8

 9configBSP_USBD_SPEED_HS

10bool

11#"USBHighSpeed(HS)Mode"

12configBSP_USBD_SPEED_HSINFS

13bool

14#"USBHighSpeed(HS)CoreinFSmode"

15

16configBSP_USBD_PHY_EMBEDDED

17bool

18#"UsingEmbeddedphyinterface"

19configBSP_USBD_PHY_UTMI

20bool

21#"UTMI:USB2.0TransceiverMacrocellInterace"

22configBSP_USBD_PHY_ULPI

23bool

24#"ULPI:UTMI+LowPinInterface"

25endif

1.2 Tools构建


该文件夹就是工程构建的脚本,


 1importos

 2importsys

 3importshutil

 4

 5cwd_path=os.getcwd()

 6sys.path.append(os.path.join(os.path.dirname(cwd_path),'rt-thread','tools'))

 7

 8

 9#BSPdistfunction

10defdist_do_building(BSP_ROOT,dist_dir):

11frommkdistimportbsp_copy_files

12importrtconfig

13

14print("=>copygd32bsplibrary")

15library_dir=os.path.join(dist_dir,'libraries')

16library_path=os.path.join(os.path.dirname(BSP_ROOT),'libraries')

17bsp_copy_files(os.path.join(library_path,rtconfig.BSP_LIBRARY_TYPE),

18os.path.join(library_dir,rtconfig.BSP_LIBRARY_TYPE))

19

20print("=>copybspdrivers")

21bsp_copy_files(os.path.join(library_path,'HAL_Drivers'),os.path.join(library_dir,'HAL_Drivers'))

22shutil.copyfile(os.path.join(library_path,'Kconfig'),os.path.join(library_dir,'Kconfig'))


以上代码很简单,主要使用了Python的OS模块的join函数,该函数的作用就是连接两个或更多的路径名。最后将BSP依赖的文件复制到指定目录下。在使用scons --dist 命令打包的时候,就是依赖的该脚本,生成的dist 文件夹的工程到任何目录下使用,也就是将BSP相关的库以及内核文件提取出来,可以将该工程任意拷贝。1.3 gd32f103vet6-eval构建
6b8e0fec-d19f-11ec-bce3-dac502259ad0.jpg 

2 BSP移植

2.1 Keil环境准备

接下来我们下载GD32F30x的软件支持包。

下载地址:http://www.gd32mcu.com/cn/download/0?kw=GD32F1


6ba753d0-d19f-11ec-bce3-dac502259ad0.png双击安装包,按照操作步骤进行安装。
安装成功后,重新打开Keil,则可以在File->Device Database中出现Gigadevice的下拉选项,点击可以查看到相应的型号。6bc650e6-d19f-11ec-bce3-dac502259ad0.jpg2.2 BSP工程制作

1.构建基础工程
首先看看RT-Thread代码仓库中已有很多BSP,而我要移植的是Cortex-M4内核。这里我找了一个相似的内核,把它复制一份,并修改文件名为:gd32103C-eval。这样就有一个基础的工程。然后就开始增删改查,完成最终的BSP,几乎所有的BSP的制作都是如此。


2.修改BSP构建脚本

E:RT_ThreadGD32_BSPrt_thread_codebspgd32f103gd32f103vet6/Kconfig修改后的内容如下


 1mainmenu"RT-ThreadConfiguration"

 2

 3configBSP_DIR

 4string

 5optionenv="BSP_ROOT"

 6default"."

 7

 8configRTT_DIR

 9string

10optionenv="RTT_ROOT"

11default"../../.."

12

13configPKGS_DIR

14string

15optionenv="PKGS_ROOT"

16default"packages"

17

18source"$RTT_DIR/Kconfig"

19source"$PKGS_DIR/Kconfig"

20source"../libraries/Kconfig"

21source"board/Kconfig"

该文件是获取所有路径下的Kconfig。


E:RT_ThreadGD32_BSPrt_thread_codebspgd32f103gd32f103vet6/SConscript修改后的内容如下:


 1#formodulecompiling

 2importos

 3Import('RTT_ROOT')

 4frombuildingimport*

 5

 6cwd=GetCurrentDir()

 7objs=[]

 8list=os.listdir(cwd)

 9

10fordinlist:

11path=os.path.join(cwd,d)

12ifos.path.isfile(os.path.join(path,'SConscript')):

13objs=objs+SConscript(os.path.join(d,'SConscript'))

14

15Return('objs')

该文件是用于遍历当前目录的所有文件夹。


E:RT_ThreadGD32_BSPrt_thread_codebspgd32f103gd32f103vet6/SConstruct修改后的内容如下:


 1importos

 2importsys

 3importrtconfig

 4

 5ifos.getenv('RTT_ROOT'):

 6RTT_ROOT=os.getenv('RTT_ROOT')

 7else:

 8RTT_ROOT=os.path.normpath(os.getcwd()+'/../../..')

 9

10sys.path=sys.path+[os.path.join(RTT_ROOT,'tools')]

11try:

12frombuildingimport*

13except:

14print('CannotfoundRT-Threadrootdirectory,pleasecheckRTT_ROOT')

15print(RTT_ROOT)

16exit(-1)

17

18TARGET='rtthread.'+rtconfig.TARGET_EXT

19

20DefaultEnvironment(tools=[])

21env=Environment(tools=['mingw'],

22AS=rtconfig.AS,ASFLAGS=rtconfig.AFLAGS,

23CC=rtconfig.CC,CCFLAGS=rtconfig.CFLAGS,

24AR=rtconfig.AR,ARFLAGS='-rc',

25CXX=rtconfig.CXX,CXXFLAGS=rtconfig.CXXFLAGS,

26LINK=rtconfig.LINK,LINKFLAGS=rtconfig.LFLAGS)

27env.PrependENVPath('PATH',rtconfig.EXEC_PATH)

28

29ifrtconfig.PLATFORM=='iar':

30env.Replace(CCCOM=['$CC$CCFLAGS$CPPFLAGS$_CPPDEFFLAGS$_CPPINCFLAGS-o$TARGET$SOURCES'])

31env.Replace(ARFLAGS=[''])

32env.Replace(LINKCOM=env["LINKCOM"]+'--maprtthread.map')

33

34Export('RTT_ROOT')

35Export('rtconfig')

36

37SDK_ROOT=os.path.abspath('./')

38

39ifos.path.exists(SDK_ROOT+'/libraries'):

40libraries_path_prefix=SDK_ROOT+'/libraries'

41else:

42libraries_path_prefix=os.path.dirname(SDK_ROOT)+'/libraries'

43

44SDK_LIB=libraries_path_prefix

45Export('SDK_LIB')

46

47#preparebuildingenvironment

48objs=PrepareBuilding(env,RTT_ROOT,has_libcpu=False)

49

50gd32_library='GD32F10x_Firmware_Library'

51rtconfig.BSP_LIBRARY_TYPE=gd32_library

52

53#includelibraries

54objs.extend(SConscript(os.path.join(libraries_path_prefix,gd32_library,'SConscript')))

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。