操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载本文以 RT-Thread 仓库中的 GD32 ARM 系列 BSP 为对象系统讲解如何从既有模板出发逐步移植出适配新芯片/新开发板的 BSP 工程。文章覆盖 BSP 框架结构、Keil 环境与 DFP 安装、SConstruct/链接脚本/board 层/Kconfig 的逐项修改、menuconfig 配置、驱动与应用开发、ENV 编译、MDK 工程生成、GD-Link 下载调试、RT-Thread Studio 导入以及 BSP 制作与提交规范配合仓库中 gd32407v-start 的实际文件作为对照让读者可以按图索骥完成一次完整的 BSP 移植。1. 认识 GD32 ARM 系列 BSP 框架GD32 ARM 系列 BSP 的架构分为三个部分libraries、tools和具体的Boards其框架关系如下图所示。librariesGD32 的通用库包含每个系列的 Firmware Library如 GD32F4xx 固件库以及适配 RT-Thread 的 drivers即libraries/gd32_drivers位于 bsp/gd32/arm/libraries对外提供串口、GPIO、SPI、ADC、定时器、RTC、看门狗、SDIO、USB 等 RT-Thread 设备驱动框架的实现tools生成工程的 Python 脚本工具位于 bsp/gd32/arm/tools其中的sdk_dist.py用于 BSP 发布/dist 处理Boards具体的开发板工程例如 bsp/gd32/arm/gd32407v-start 对应兆易创新官方 GD32407V-START 开发板主控 GD32F407VKT6Cortex-M4 内核。打开 bsp/gd32/arm/README.md 可以看到当前仓库中已按F1 / F2 / F3 / F4 / E5 / E23系列维护了大量官方及三方开发板 BSP例如gd32103c-eval、gd32207i-eval、gd32307e-start、gd32407v-lckfb立创天空星 GD32F407VET6、gd32470z-lckfb立创梁山派 GD32F470ZGT6、gd32e230-lckfb立创 GD32E230C8T6等。新 BSP 的移植通常就是从这些现成模板中选择一个内核相近的复制改造而来。2. 制作前的知识准备制作 BSP 的过程本质上是构建一个新系统的过程在动手前需要具备以下四方面知识掌握 GD32 ARM 系列 BSP 的使用方法先读懂现有 BSP 的用法可参考 bsp/gd32/arm/README.md 中使用教程表格内的文档外设驱动使用教程、驱动介绍与应用。了解 SCons 工程构建方法RT-Thread 使用 SCons 作为构建工具scons、scons --targetmdk5、scons --dist等常用命令是制作新 BSP 的基本功。了解设备驱动框架应用程序通过 RT-Thread 设备驱动框架操作硬件添加 BSP 驱动前需要理解 pin/serial/spi 等设备模型。了解 Kconfig 语法menuconfig中的配置项由各层的 Kconfig 文件决定RT-Thread 的配置体系依赖 Kconfig 描述。3. 环境准备安装 Keil 与 GD32 DFP 支持包3.1 安装 MDK市面通用 MDK for ARM 版本有 Keil 4 与 Keil 5Keil 4 建议 4.74 及以上Keil 5 建议 5.20 以上教程编写环境为 MDK 5.30。从 MDK 官网下载安装包并安装安装完成后会自动打开先将其关闭。3.2 安装 GD32F4xx 软件支持包从 GD32 官网下载页下载 GD32F4xx 的软件支持包如GigaDevice.GD32F4xx_DFP.2.1.0.pack下载后双击运行点击 Next 即可完成安装。安装成功后重新打开 Keil在File - Device Database中会出现Gigadevice下拉选项展开即可看到相应型号。4. 构建基础工程从相似模板复制改造查看 RT-Thread 代码仓库中已有的 BSP找到一颗内核相似的芯片工程作为起点。以教程中的 Cortex-M4 为例将相似的 BSP 整体复制一份并改名为目标工程名如gd32407v-start然后在副本上增删改查。几乎所有 BSP 的制作都是这个套路先复制出可编译的工程骨架再逐层修改直至适配目标芯片。以仓库中的 bsp/gd32/arm/gd32407v-start 为例其目录结构包含applications/用户应用main.c与 SConscriptboard/板级初始化board.c/board.h、Kconfig、SConscript、链接脚本linker_scripts/link.icf、link.ld、link.sct、固件库裁剪配置gd32f4xx_libopt.hlibraries/通过上层共享固件库与 RT-Thread 驱动适配各类工程文件project.ewp/ewwIAR、project.uvprojx/uvprojMDK以及对应的template.*模板文件rtconfig.h/rtconfig.pyRT-Thread 配置产物SConscript/SConstruct构建脚本。5. 修改顶层构建脚本 SConstructSConstruct负责链接所有依赖文件定位 RT-Thread 根目录、加载tools/building.py、注册编译器环境、引入固件库与驱动目录最后调用DoBuilding完成构建。核心修改点是固件库路径。以 bsp/gd32/arm/gd32407v-start/SConstruct 为例与教程版本略有演进但思路一致import os import sys import rtconfig if os.getenv(RTT_ROOT): RTT_ROOT os.getenv(RTT_ROOT) else: RTT_ROOT os.path.normpath(os.getcwd() /../../../..) sys.path sys.path [os.path.join(RTT_ROOT, tools)] try: from building import * except: print(Cannot found RT-Thread root directory, please check RTT_ROOT) print(RTT_ROOT) exit(-1) TARGET rtthread. rtconfig.TARGET_EXT DefaultEnvironment(tools[]) env Environment(tools [mingw], AS rtconfig.AS, ASFLAGS rtconfig.AFLAGS, CC rtconfig.CC, CFLAGS rtconfig.CFLAGS, AR rtconfig.AR, ARFLAGS -rc, CXX rtconfig.CXX, CXXFLAGS rtconfig.CXXFLAGS, LINK rtconfig.LINK, LINKFLAGS rtconfig.LFLAGS) env.PrependENVPath(PATH, rtconfig.EXEC_PATH) if rtconfig.PLATFORM in [iccarm]: env.Replace(CCCOM [$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES]) env.Replace(ARFLAGS []) env.Replace(LINKCOM env[LINKCOM] --map rtthread.map) Export(env) Export(RTT_ROOT) Export(rtconfig) 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_libcpuFalse) # include libraries objs.extend(SConscript(os.path.join(libraries_path_prefix, GD32F4xx_Firmware_Library, SConscript))) # include drivers objs.extend(SConscript(os.path.join(libraries_path_prefix, gd32_drivers, SConscript))) # make a building DoBuilding(TARGET, objs)几个关键点RTT_ROOT通过环境变量或相对路径推算用于定位 RT-Thread 根目录及tools目录进而from building import *SDK_LIB指向固件库根目录会Export给子目录的 SConscript 使用新芯片移植时需要把GD32F4xx_Firmware_Library换成目标系列的固件库名并确保固件库目录下有对应的 SConscript仓库当前版本中gd32407v-start已将固件库改为通过packagesgd32-arm-cmsis-latest、gd32-arm-series-latest方式引入并在编译前通过bsp_pkg_check检查依赖包是否就绪缺少时会提示先执行pkgs --update。6. 修改链接脚本适配芯片 Flash 与 SRAM链接脚本决定程序在芯片上的内存布局必须与目标芯片的存储资源严格对应。以 GD32F407VKT6 为例根据《GD32F407xx_Datasheet》手册其 Flash 大小为 3072KB、SRAM 为 192KB。三种编译器各有一份链接脚本位于 bsp/gd32/arm/gd32407v-start/board/linker_scripts6.1 IARlink.icf/*###ICF### Section handled by ICF editor, dont touch! */ define symbol __ICFEDIT_intvec_start__ 0x08000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ 0x08000000; define symbol __ICFEDIT_region_ROM_end__ 0x082FFFFF; define symbol __ICFEDIT_region_RAM_start__ 0x20000000; define symbol __ICFEDIT_region_RAM_end__ 0x2002FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ 0x2000; define symbol __ICFEDIT_size_heap__ 0x2000; /* End of ICF editor section. ###ICF###*/ export symbol __ICFEDIT_region_RAM_end__; define symbol __region_RAM1_start__ 0x10000000; define symbol __region_RAM1_end__ 0x1000FFFF; define memory mem with size 4G; define region ROM_region mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region RAM1_region mem:[from __region_RAM1_start__ to __region_RAM1_end__]; define block CSTACK with alignment 8, size __ICFEDIT_size_cstack__ { }; define block HEAP with alignment 8, size __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; keep { section FSymTab }; keep { section VSymTab }; keep { section .rti_fn* }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; place in RAM1_region { section .sram };注意keep段对 RT-Thread 的意义FSymTab、VSymTab对应 FinSH 符号表.rti_fn*对应组件自动初始化节它们必须被保留且不能被垃圾回收否则 FinSH 命令和自动初始化将失效。6.2 GCClink.ldMEMORY { CODE (rx) : ORIGIN 0x08000000, LENGTH 3072k /* 3072KB flash */ DATA (rw) : ORIGIN 0x20000000, LENGTH 192k /* 192KB sram */ } ENTRY(Reset_Handler) _system_stack_size 0x200; SECTIONS { .text : { . ALIGN(4); _stext .; KEEP(*(.isr_vector)) /* Startup code */ . ALIGN(4); *(.text) /* remaining code */ *(.text.*) *(.rodata) /* read-only data (constants) */ *(.rodata*) *(.glue_7) *(.glue_7t) *(.gnu.linkonce.t*) /* section information for finsh shell */ . ALIGN(4); __fsymtab_start .; KEEP(*(FSymTab)) __fsymtab_end .; . ALIGN(4); __vsymtab_start .; KEEP(*(VSymTab)) __vsymtab_end .; . ALIGN(4); /* section information for initial. */ . ALIGN(4); __rt_init_start .; KEEP(*(SORT(.rti_fn*))) __rt_init_end .; . ALIGN(4); . ALIGN(4); _etext .; } CODE 0 /* .ARM.exidx is sorted, so has to go in its own output section. */ __exidx_start .; .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) _sidata .; } CODE __exidx_end .; .data : AT (_sidata) { . ALIGN(4); _sdata . ; *(.data) *(.data.*) *(.gnu.linkonce.d*) . ALIGN(4); _edata . ; } DATA .stack : { . . _system_stack_size; . ALIGN(4); _estack .; } DATA __bss_start .; .bss : { . ALIGN(4); _sbss .; *(.bss) *(.bss.*) *(COMMON) . ALIGN(4); _ebss . ; *(.bss.init) } DATA __bss_end .; _end .; /* 调试节区stab / DWARF 等省略 */ }这里的MEMORY块把CODE设为 3072k、DATA设为 192kENTRY(Reset_Handler)指向启动文件入口。其他 GD32 芯片地址段基本相同只需按数据手册调整LENGTH。6.3 MDKlink.sct; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x00300000 { ; load region size_region ER_IROM1 0x08000000 0x00300000 { ; load address execution address *.o (RESET, First) *(InRoot$$Sections) .ANY (RO) } RW_IRAM1 0x20000000 0x00030000 { ; RW data .ANY (RW ZI) } }0x00300000 3MB对应 3072KB Flash0x00030000 192KB对应 SRAM 大小RESET, First保证中断向量表放在首地址。7. 修改 board 层板级初始化与内存堆7.1 board.h定义 SRAM 边界与堆起止bsp/gd32/arm/gd32407v-start/board/board.h 定义了堆区HEAP_BEGIN/HEAP_END并针对不同编译器做了分支处理#ifdef __ICCARM__ /* Use *.icf ram symbal, to avoid hardcode. */ extern char __ICFEDIT_region_RAM_end__; #define GD32_SRAM_END __ICFEDIT_region_RAM_end__ #else #define GD32_SRAM_SIZE 128 #define GD32_SRAM_END (0x20000000 GD32_SRAM_SIZE * 1024) #endif #ifdef __ARMCC_VERSION extern int Image$$RW_IRAM1$$ZI$$Limit; #define HEAP_BEGIN (Image$$RW_IRAM1$$ZI$$Limit) #elif __ICCARM__ #pragma sectionHEAP #define HEAP_BEGIN (__segment_end(HEAP)) #else extern int __bss_end; #define HEAP_BEGIN (__bss_end) #endif #define HEAP_END GD32_SRAM_END不同编译器规定的堆栈内存起始/结束地址符号各不相同必须与对应链接脚本保持一致MDKarmcc/armclang下HEAP_BEGIN取Image$$RW_IRAM1$$ZI$$Limit对应 link.sct 中RW_IRAM1区 ZI 段结束处IAR 下HEAP_BEGIN取__segment_end(HEAP)对应 link.icf 中HEAP块GCC 下HEAP_BEGIN取__bss_end对应 link.ld 中的__bss_end符号GD32_SRAM_END即堆的结束地址__ICCARM__下直接从 icf 符号读取避免硬编码。7.2 board.c板级初始化入口bsp/gd32/arm/gd32407v-start/board/board.c 的核心是rt_hw_board_init它在系统启动早期完成向量表重定位、系统时钟配置、串口初始化、堆初始化与控制台绑定void rt_hw_board_init() { /* NVIC Configuration */ #define NVIC_VTOR_MASK 0x3FFFFF80 #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x10000000 */ SCB-VTOR (0x10000000 NVIC_VTOR_MASK); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ SCB-VTOR (0x08000000 NVIC_VTOR_MASK); #endif SystemClock_Config(); #ifdef RT_USING_SERIAL rt_hw_usart_init(); #endif #ifdef BSP_USING_SDRAM rt_system_heap_init((void *)EXT_SDRAM_BEGIN, (void *)EXT_SDRAM_END); #else rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); #endif #ifdef RT_USING_CONSOLE rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif }重点理解向量表重定位默认向量表位于 Flash0x08000000对应各链接脚本的intvec/RESET段起始若定义VECT_TAB_RAM则重定位到0x10000000RAM1 区见 link.icf 的RAM1_region系统时钟SystemClock_Config通过SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND)配置 SysTick 定时中断其中SystemCoreClock在system_gd32f4xx.c固件库中定义NVIC_SetPriority(SysTick_IRQn, 0)将 SysTick 中断优先级设为最高心跳SysTick_Handler中调用rt_interrupt_enter()→rt_tick_increase()→rt_interrupt_leave()这是 RT-Thread 系统时钟节拍tick的来源堆初始化rt_system_heap_init是必做项对应制作规范中的要求默认使用内部 SRAM 的HEAP_BEGIN~HEAP_END当板载 SDRAM 且使能BSP_USING_SDRAM时改用外部 SDRAM 区间EXT_SDRAM_BEGIN/EXT_SDRAM_END控制台通过rt_console_set_device(RT_CONSOLE_DEVICE_NAME)绑定 FinSH/打印输出设备组件自动初始化rt_components_board_init()触发板级组件的INIT_BOARD_EXPORT自动初始化。7.3 board/SConscript汇集板级源文件与启动文件bsp/gd32/arm/gd32407v-start/board/SConscript 将board.c加入编译组并按编译器选择对应的启动汇编文件新版已改为在固件库 SConscript 中处理启动文件此处以教程版本示例说明src Split( board.c ) path [cwd] if rtconfig.PLATFORM in [gcc]: src [startup_path_prefix /GD32F4xx_Firmware_Library/CMSIS/GD/GD32F4xx/Source/GCC/startup_gd32f4xx.s] elif rtconfig.PLATFORM in [armcc, armclang]: src [startup_path_prefix /GD32F4xx_Firmware_Library/CMSIS/GD/GD32F4xx/Source/ARM/startup_gd32f4xx.s] elif rtconfig.PLATFORM in [iccarm]: src [startup_path_prefix /GD32F4xx_Firmware_Library/CMSIS/GD/GD32F4xx/Source/IAR/startup_gd32f4xx.s] CPPDEFINES [GD32F407] group DefineGroup(Drivers, src, depend [], CPPPATH path, CPPDEFINES CPPDEFINES)注意CPPDEFINES [GD32F407]该宏用于固件库内部选择器件型号移植到其他型号时必须同步修改。8. 修改模板工程与 board/Kconfig8.1 修改 Keil 模板工程 template.uvprojx双击template.uvprojx修改模板工程以gd32407v-start的 template.uvprojx 为例需要修改的内容包括芯片设备在 Device 中选择对应芯片型号Flash 与 RAM 配置按芯片数据手册设置片上 Flash/SRAM 大小可执行文件名字统一为rtthread输出rtthread.axf默认调试工具选择 CMSIS-DAP Debugger编程算法选择对应 Flash 编程算法如 GD32F4xx 使用 GD32F4xx FMC。这些配置与第 6 节链接脚本中的地址/容量必须一致否则会出现下载或运行异常。8.2 修改 board/Kconfig驱动菜单bsp/gd32/arm/gd32407v-start/board/Kconfig 是menuconfig中硬件驱动配置菜单的来源。教程版本的核心结构如下menu Hardware Drivers Config config SOC_SERIES_GD32F4xx default y config SOC_GD32407V bool select SOC_SERIES_GD32F4xx select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN default y menu Onboard Peripheral Drivers endmenu menu On-chip Peripheral Drivers config BSP_USING_GPIO bool Enable GPIO select RT_USING_PIN default y menuconfig BSP_USING_UART bool Enable UART default y select RT_USING_SERIAL if BSP_USING_UART config BSP_USING_UART1 bool Enable UART1 default y config BSP_UART1_RX_USING_DMA bool Enable UART1 RX DMA depends on BSP_USING_UART1 RT_SERIAL_USING_DMA default n endif menuconfig BSP_USING_SPI bool Enable SPI BUS default n select RT_USING_SPI # ... SPI1 及 TX/RX DMA 选项 ... source ../libraries/gd32_drivers/Kconfig endmenu menu Board extended module Drivers endmenu endmenu实际仓库中的 board/Kconfig 已进一步丰富提供了 UART0~UART3 的引脚名TX/RX、复用功能AFIO、串口框架版本选择Serial V1/V2、DMA 收发及 ping-pong 缓冲区大小、SPI/ADC/定时器/RTC 告警/看门狗/SDIO/USB 设备/USB 主机含 U 盘挂载点等可配置项例如menuconfig BSP_USING_UART1 bool Enable UART1 default y if BSP_USING_UART1 config BSP_UART1_TX_PIN string UART1 TX name, such as PA8 default PA2 config BSP_UART1_RX_PIN string UART1 RX name, such as PA9 default PA3 config BSP_UART1_AFIO string UART1 alternate function, such as AF7 default AF7 # 以及 DMA、缓冲区大小等 endifsource语句会把 bsp/gd32/arm/libraries/gd32_drivers/Kconfig 中通用的驱动选项并入菜单从而复用仓库公共驱动配置。该文件就是配置板载驱动的入口可根据实际需求增删驱动选项。9. menuconfig 配置在bsp/gd32/arm/gd32407v-start目录下运行menuconfig针对板载资源裁剪系统功能。以 GD32407V-START 为例板载没有以太网因此教程中关闭了网络相关内容关闭套接字抽象层RT_USING_SAL相关选项关闭网络设备接口关闭 LWIP 协议栈。如果是其他 MCU 或板卡根据实际需求自行取舍——GD32407V-START 资源较丰富保留这些网络组件也不影响运行。menuconfig 保存后会生成rtconfig.h并同步影响 rtconfig.py 中定义的编译器类型PLATFORM、交叉编译工具链EXEC_PATH等构建参数。10. 驱动与应用开发一个基本 BSP 中串口驱动必不可少教程以串口 2 作为调试串口板载 LED 则需要 GPIO 驱动。串口与 LED 的驱动实现可查看仓库中 bsp/gd32/arm/libraries/gd32_drivers 下的源码如drv_usart.c、drv_gpio.c。驱动完成后在applications/main.c中编写应用代码。仓库中 bsp/gd32/arm/gd32407v-start/applications/main.c 正是教程中的 LED 闪烁示例#include stdio.h #include rtthread.h #include rtdevice.h #include board.h /* defined the LED2 pin: PC6 */ #define LED2_PIN GET_PIN(C, 6) int main(void) { int count 1; /* set LED2 pin mode to output */ rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT); while (count) { rt_pin_write(LED2_PIN, PIN_HIGH); rt_thread_mdelay(500); rt_pin_write(LED2_PIN, PIN_LOW); rt_thread_mdelay(500); } return RT_EOK; }该示例依赖 GPIO 驱动RT_USING_PIN与GET_PIN宏运行后 LED2 以 1Hz 频率闪烁同时可通过串口观察 FinSH 输出。11. 编译与生成 MDK 工程11.1 ENV 下编译在 ENV 环境进入bsp/gd32/arm/gd32407v-start目录执行scons编译成功后终端会打印生成rtthread.bin/rtthread.axf等信息。11.2 生成 MDK 工程scons --targetmdk5该命令会根据 SConscript 描述重新生成 Keil MDK 工程文件。生成后打开 MDK 工程project.uvprojx进行编译。12. 使用 GD-Link 下载调试GD32 部分开发板自带 GD-Link可直接用于仿真与下载不带 GD-Link 的板子可以外接 GD-Link 模块。操作步骤如下安装驱动第一次将 GD-Link 插入电脑后会自动安装驱动选择调试器在Options for Target - Debug中选择CMSIS-DAP Debugger。注意只有 Keil 4.74 以上版本和 Keil 5 才支持 CMSIS-DAP Debugger 选项配置调试参数在Options for Target - Debug - Settings中勾选 SWJPort 选择 SW右侧 IDcode 会出现0xXBAXXXXX形式的 ID添加 Flash 编程算法在Options for Target - Debug - Settings - Flash Download中添加 GD32 的 Flash 算法仿真与下载点击 Debug 快捷按钮即可进入仿真调试也可直接使用 GD-Link 下载程序。下载成功后复位运行串口将打印 RT-Thread 启动信息同时 LED 不断闪烁。13. 使用 RT-Thread Studio 开发除 ENVMDK 工作流外该 BSP 也可以导出到 RT-Thread Studio 中开发在 ENV 中执行scons --dist导出独立工程dist 发布会把 RT-Thread 内核、组件与 BSP 打成一份可直接分发的源码树将导出的工程导入 RT-Thread Studio之后即可在 RT-Thread Studio 中进行编辑、编译、下载与调试。14. BSP 制作与提交规范BSP 制作完成后在提交前需要依据以下规范逐项检查确保 BSP 质量。14.1 工程配置规范遵从 RT-Thread 编码规范代码注释风格统一main函数功能保持一致如果有 LEDmain函数里只放一个LED 1Hz 闪烁程序在rt_hw_board_init中必须完成堆初始化调用rt_system_heap_init默认只初始化 GPIO 驱动和 FinSH 对应的串口驱动不使用 DMA使能板载外设驱动时应做到不修改代码即可编译下载使用提交前检查 GCC / MDK / IAR 三种编译器直接编译或重新生成后编译是否成功使用dist命令对 BSP 进行发布并检查生成的工程可正常使用。14.2 ENV 配置规范系统心跳统一设置为 1000宏RT_TICK_PER_SECOND打开调试选项中的断言宏RT_USING_DEBUG系统空闲线程栈大小统一设置为 256宏IDLE_THREAD_STACK_SIZE开启组件自动初始化宏RT_USING_COMPONENTS_INIT开启 user main 选项宏RT_USING_USER_MAIN默认关闭 libc宏RT_USING_LIBCFinSH 默认只使用 MSH 模式宏FINSH_USING_MSH_ONLY。14.3 IDE 配置规范使能下载代码后自动运行使能 C99 支持MDK 使能 One ELF Section per FunctionMDK / IAR 生成的临时文件分别放到 build 下的 MDK / IAR 文件夹下MDK / GCC / IAR 生成的 bin 文件名字统一为rtthread.bin。14.4 BSP 提交规范提交前认真修改 BSP 的README.md外设支持表单只填写 BSP 实际支持的外设可参考其他 BSP 的写法驱动分类可查阅 bsp/gd32/arm/docs/GD32_ARM系列驱动介绍.md提交分两个阶段第一阶段基础 BSP包括串口驱动和 GPIO 驱动能运行 FinSH 控制台完成 MDK4、MDK5、IAR 和 GCC 编译器支持芯片不支持的编译器如 MDK4 可不做README.md 中需填写第二阶段计划完成的驱动第二阶段完成板载外设驱动支持所有板载外设经 menuconfig 配置后即可直接使用无板载外设则此阶段可跳过不同驱动分开提交方便 review 和合并只提交 BSP 必要文件删除无关中间文件可对照其他 BSP 确认可提交文件清单提交 GD32 不同系列的 Library 库时参考 F1/F4 系列的库删除多余库文件提交前进行编译测试确保在不同编译器下编译正常提交前进行功能测试确保 BSP 符合工程配置章节的各项要求。15. 小结从本教程可以看出RT-Thread GD32 ARM 系列 BSP 移植是一条高度模板化的路径复制相似内核的工程 → 修改 SConstruct 引入目标固件库 → 按数据手册调整三类链接脚本 → 修改 board 层board.h/board.c/SConscript/Kconfig→ 配置 Keil 模板工程 → menuconfig 裁剪系统 → 补齐串口与 GPIO 驱动 → 编写应用验证 → 多编译器编译测试 → 提交。整个过程中bsp/gd32/arm/gd32407v-start 是一个可直接对照的完整范例而 bsp/gd32/arm/README.md 与 bsp/gd32/arm/docs 下的配套文档外设驱动使用教程、驱动介绍与应用则提供了后续深度开发的指引。按照第 14 节的规范自查后提交即可产出一个质量达标的 BSP。赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread Infineon PSoC6 系列 BSP 制作教程从模板复制到工程提交的完整实践RT Thread Infineon PSoC6 系列 BSP 制作教程从模板复制到工程提交的完整实践 本教程面向希望为 Infineon PSoC6 系列开操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 的 GD32107C-EVAL 开发板 BSP 移植与使用指南RT Thread 的 GD32107C EVAL 开发板 BSP 移植与使用指南 本指南以 RT Thread 仓库中 bsp/gd32/arm/gd3210操作系统嵌入式物联网嵌入式OSRTOSRT-Thread BSP移植指南支持200开发板的秘密RT Thread BSP移植指南支持200开发板的秘密 RT Thread能够支持200开发板的核心秘密在于其精心设计的BSPBoard Suppor操作系统嵌入式物联网嵌入式OSRTOS上一篇wallabag开源自托管稍后阅读平台的全面介绍下一篇【亲测免费】 探索高效自动化Go-Tasks - 一个强大的任务调度框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考