Files
FilmForge/README.md
T
2026-10-09 18:45:50 +08:00

15 KiB
Raw Blame History

GD32F4xx 工程模板

本仓库为兆易创新 GD32F4xx 系列 MCU(Cortex-M4)的 CMake + VSCode 工程模板, 组织方式与编译方法沿用 gd32e23x_template_cmake_vscode, 在其基础上适配 GD32F405RET6(默认型号,64 脚 LQFP,512KB Flash / 192KB SRAM)。 构建输出位于工程根 Build/。


目录


适用范围

  • 适用于兆易创新 GD32F4xx 系列 Cortex-M4 内核单片机(默认按 GD32F405RET6 配置)
  • 支持标准外设库开发(GD32F4xx_Firmware_Library V3.3.x,取自 GD32F4xx_Demo_Suites_V3.3.3)
  • 推荐开发环境:VSCode + CMake + ARM GCC 工具链

默认配置

  • 目标型号:GD32F405RET6(64 脚 LQFP;设备宏 GD32F405,启动文件 startup_gd32f405_425.S,链接脚本 gd32f405_407_xE_flash.ld,512K Flash / 128K RAM + 64K TCMRAM)
  • MCU 主频:内部 IRC16M 经 PLL 倍频至 168MHz(板子无外部晶振;时钟源切换方法见时钟配置说明)
  • 调试串口:USART1(PA2 TX / PA3 RX,AF7,纯串口非 RS485),115200 波特率,printf 已重定向到该串口。注意 GD32F4xx 外设编号比 STM32 整体小 1:PA2/PA3 是 USART1,PA9/PA10 才是 USART0
  • LED:PA15(demo 板实测引脚;复位后默认 JTDI 功能,配置为 GPIO 输出即接管,SWD 调试不受影响)
  • I2C0:PB6 SCL / PB7 SDA(AF4)——驱动尚未移植,见 AGENTS.md 进度清单
  • 浮点:硬件 FPU(-mfpu=fpv4-sp-d16 -mfloat-abi=hard),SystemInit 中自动使能

快速开始

基于模板创建新项目

  1. 克隆或复制本仓库

  2. 修改项目配置 — 编辑 cmake/project_config.cmake:

    set(PROJECT_NAME "MyProject")     # 项目名称
    set(BOARD_TYPE_CODE 40)           # 板卡类型码(协议帧中的标识)
    set(VERSION_MAJOR 1)              # 主版本号
    set(VERSION_MINOR 0)              # 次版本号
    set(VERSION_PATCH 0)              # 修订号
    set(BUILD_VARIANT "APP")          # 编译变体
    
  3. 添加业务源文件 — 编辑 CMakeLists.txt,在 TARGET_SRC 中添加你的 .c 文件。

  4. 配置板级引脚 — 编辑 Inc/board_config.h,修改 LED、UART、I2C 等引脚定义。

  5. 编译

    cmake --preset Debug
    cmake --build Build/Debug
    

    产物在 Build/Debug/ 下,包含 .elf、.hex、.bin、.map、.list。


工程结构

.
├── CMakeLists.txt              # 主构建文件
├── CMakePresets.json           # CMake 预设(Debug/Release,构建树位于 Build/)
├── cmake/
│   ├── arm-none-eabi-gcc.cmake # ARM GCC 工具链配置(cortex-m4 + 硬件 FPU)
│   ├── project.cmake           # 编译选项(-Os/-O0, -mcpu=cortex-m4)
│   ├── project_config.cmake    # 项目名/版本号/编译变体
│   └── version.h.in            # 自动生成固件版本头
├── Inc/                        # 头文件
│   ├── board_config.h          # 板级引脚定义 + 功能开关
│   ├── gd32f4xx_libopt.h       # 标准外设库统一包含
│   ├── gd32f4xx_it.h / led.h / systick.h / uart.h
│   └── uart_ring_buffer.h
├── Src/                        # 源码
│   ├── main.c                  # 入口函数
│   ├── board_config.c          # Flash 容量检测 + 串口资源配置
│   ├── uart.c / led.c / systick.c / uart_ring_buffer.c
│   └── gd32f4xx_it.c / system_gd32f4xx.c / syscalls.c
├── SDK/
│   ├── CMSIS/                  # CMSIS core_cm4 + GD32F4xx 设备头 + 启动文件
│   │   └── startup/startup_gd32f405_425.S   # GCC 版启动文件
│   ├── GD32F4xx_standard_peripheral/        # GD32 标准外设库(29 个模块)
│   ├── GD32F4xx_usb_library/   # USB 库(默认不编译,-DGD32_ENABLE_USB=ON 启用,
│   │   └── ...                 #   默认含 driver+device core+CDC 虚拟串口,详见其 CMakeLists)
│   └── SEGGER_RTT/             # SEGGER RTT 调试输出
├── LD/                         # 链接脚本(gd32f405_407_xE/xG/xK 三种容量)
├── OpenOCD/                    # 工程内 OpenOCD 会话配置(GD-LINK/CMSIS-DAP)
├── GD32F4xx.svd                # CMSIS-SVD 外设寄存器描述(调试视图用)
├── doc/                        # 芯片数据手册/用户手册/固件库指南/AN(已齐备)
├── Build/                      # 构建输出目录(temp 之外,gitignore)
├── GD32F4xx_Demo_Suites_V3.3.3/# 官方原始素材包(本地参考,不入库)
└── .vscode/                    # VSCode 调试/烧录配置

板级配置(Inc/board_config.h)

所有功能开关和引脚定义集中在 Inc/board_config.h。功能开关均为单行数值宏:将右侧的 ENABLE 或 DISABLE 改为另一值即可;其中 ENABLE 为 1,DISABLE 为 0。

功能开关速查表

宏 作用 默认值 Release 建议
SOFTWARE_IIC I2C 实现方式 DISABLE(硬件) DISABLE
DEBUG_MODE printf 串口输出 DISABLE DISABLE
COM_DEBUG 命令帧调试打印 DISABLE DISABLE
DEBUG_VERBOSE 详细调试信息 DISABLE DISABLE
SEGGER_RTT_DETECTION SEGGER RTT 支持 ENABLE DISABLE
RS485_MODE RS485 DE 引脚控制 DISABLE 按需

RS485_MODE:GD32F4xx 的 USART 没有 E23x 那样的硬件 RS485 DE 驱动,本模板用 GPIO 手动控制 DE 引脚(rs485_de_set()/rs485_de_clear()),收发切换逻辑需在 业务层调用。

引脚定义

/* I2C0(驱动待移植) */
#define RCU_GPIO_I2C         RCU_GPIOB
#define I2C_SCL_PORT         GPIOB
#define I2C_SCL_PIN          GPIO_PIN_6
#define I2C_SDA_PORT         GPIOB
#define I2C_SDA_PIN          GPIO_PIN_7
#define I2C_GPIO_AF          GPIO_AF_4

/* LED(demo 板: PA15) */
#define LED_RCU              RCU_GPIOA
#define LED_PORT             GPIOA
#define LED_PIN              GPIO_PIN_15

/* 调试串口 USART1(PA2/PA3,纯串口;GD 编号比 STM32 小 1) */
#define UART_GPIO_PORT       GPIOA
#define UART_TX_PIN          GPIO_PIN_2
#define UART_RX_PIN          GPIO_PIN_3
#define UART_BAUDRATE        115200U

Flash 容量切换(xE / xG / xK)

同系列不同容量的芯片(如 GD32F405RE 512K → GD32F405RG 1024K)在编译期切换, 无需改代码:CMake 变量 GD32_FLASH_CAPACITY(定义在 cmake/project_config.cmake, 默认 xE)决定链接脚本(LD/gd32f405_407_xE|xG|xK_flash.ld)并向代码注入 GD32_FLASH_SIZE_KB 宏(512/1024/2048)。

# 切换到 1024K 容量(对当前 preset 的构建目录生效)
cmake --preset Debug -DGD32_FLASH_CAPACITY=xG
cmake --build Build/Debug

注意:该变量写入 CMake cache,切换后会保持——恢复默认需显式 -DGD32_FLASH_CAPACITY=xE 或删除 Build/<Config> 目录重新配置。 也可在 VSCode CMake Tools 的缓存编辑界面直接修改。


更换目标型号

换用 GD32F405/425、GD32F450/470 等 F4 家族其它型号时,修改 4 处:

  1. 设备宏 — cmake/project.cmake 与 SDK/GD32F4xx_standard_peripheral/CMakeLists.txt 中的 GD32F405 改为 GD32F407 / GD32F425 / GD32F450 / GD32F470。

  2. 启动文件 — CMakeLists.txt 的 TARGET_SRC:

    • F405/F425:startup_gd32f405_425.S(默认)
    • F407/F427:startup_gd32f407_427.S
    • F450/F470:startup_gd32f450_470.S

    备份均在 SDK/CMSIS/GD/GD32F4xx/Source/GCC/ 下,复制到 SDK/CMSIS/startup/ 使用。

  3. 链接脚本 — CMakeLists.txt 中 -T 参数按容量选择 LD/gd32f405_407_xE_flash.ld(512K,默认)/ xG(1024K)/ xK(2048K)。

  4. 时钟上限 — Src/system_gd32f4xx.c:F405/407 最高 168MHz、F450/425/427 最高 200MHz、F470 最高 240MHz(该文件已按型号条件编译,换宏后默认值自动跟随)。


Flash 偏移配置(配合 Bootloader)

如果固件需要通过 Bootloader 启动(Bootloader 占用 Flash 前部区域),需修改两处:

1. 链接脚本 — LD/gd32f405_407_xE_flash.ld 开头的 MEMORY:

// 默认:从 Flash 起始运行
FLASH (rx): ORIGIN = 0x08000000, LENGTH = 1024K

// 配合 Bootloader:前 64KB 留给 Bootloader,App 从 0x08010000 开始
FLASH (rx): ORIGIN = 0x08010000, LENGTH = 960K

2. 向量表偏移 — Src/system_gd32f4xx.c 第 44 行:

// 默认
#define VECT_TAB_OFFSET  (uint32_t)0x00

// 配合 Bootloader(值 = Flash 偏移量,不含 0x0800 前缀)
#define VECT_TAB_OFFSET  (uint32_t)0x10000

⚠️ 两个偏移值必须对应修改:LD 中的 ORIGIN 减去 0x08000000 应等于 VECT_TAB_OFFSET。


工具链准备

1. ARM GCC 工具链

  • 验证版本:xpack-arm-none-eabi-gcc-15.2.1-1.1(本机当前使用,已验证编译链接通过)
  • 安装位置:每台电脑本机任意目录,工具包不放入工程仓库
  • 官方下载地址:https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases
  • 活动变量:GD32_GCC_BIN,值为工具链的 bin 目录(也接受工具链根目录)

2. OpenOCD(调试/烧录)

与 E23x 工程不同,本模板的 OpenOCD 目标配置放在工程内(借鉴 metax-sensors/gd32-cmake-example): OpenOCD/gd32f405_gdlink_cmsis_dap.cfg,内容为 CMSIS-DAP 接口 + target/stm32f4x.cfg (GD32F4xx 的 SWD ID 与 flash 扇区布局与 STM32F4 兼容)。标准脚本仍通过 GD32_OPENOCD_SCRIPTS 解析。换 J-Link/OpenOCD 时只需改这一份文件。

每台开发电脑配置一次用户环境变量(路径按本机实际位置填写):

[Environment]::SetEnvironmentVariable("GD32_GCC_BIN", "D:\toolchain\xpack-arm-none-eabi-gcc-15.2.1-1.1\bin", "User")
[Environment]::SetEnvironmentVariable("GD32_OPENOCD_BIN", "D:\Tools\xpack-openocd-0.11.0-3\bin", "User")
[Environment]::SetEnvironmentVariable("GD32_OPENOCD_SCRIPTS", "D:\Tools\xpack-openocd-0.11.0-3\scripts", "User")

环境变量命名、工具链切换方法(多套 GCC 变量 + GD32_GCC_ENV_VAR)与 E23x 模板完全一致, 详见 E23x 工程 README 的"工具链切换"章节。

环境要求清单

变量名 值 用途
GD32_GCC_BIN 活动 ARM GCC 的 bin 目录 CMake 编译、GDB 调试、binutils
GD32_OPENOCD_BIN 包含 openocd.exe 的 bin 目录 OpenOCD 任务/调试
GD32_OPENOCD_SCRIPTS OpenOCD scripts 根目录 -s 脚本搜索路径

另需:CMake ≥ 3.20、Ninja、VSCode CMake Tools、cortex-debug;J-Link 任务另需 JLink.exe 在 PATH 中(device 为 GD32F405RE,见 .vscode/settings.json)。


使用说明

编译

# Debug 构建(-O0, -g3)
cmake --preset Debug
cmake --build Build/Debug

# Release 构建(-Os, -g0)
cmake --preset Release
cmake --build Build/Release

构建树与产物位于工程根的 Build/<配置名>/(与 E23x 模板一致),可随时整目录删除重新配置。

烧录

通过 VSCode 任务栏运行 Flash MCU(OpenOCD/GD-LINK)或 Flash MCU (Jlink) 任务。

产物

编译输出位于 Build/<Config>/:

文件 说明
Application/Application.elf ELF 固件(调试用)
Application/Application.hex/.map 烧录用 hex、内存映射
{项目名}_{版本}_{编译条件}_{日期}.hex/.bin 版本化发布产物
{项目名}_{版本}_{编译条件}_{日期}.list/.bsz/.ssz 反汇编清单、尺寸记录

时钟配置说明

本工程默认系统时钟为内部 16MHz IRC 振荡器(IRC16M)经 PLL 倍频后的 168MHz—— 因为当前 demo 板没有外部晶振。注意:HXTAL 方案在晶振不起振时会死循环等待 (system_gd32f4xx.c 各 HXTAL 分支的 while 等待),表现为程序完全不动,因此 无晶振的板子必须使用 IRC16M 方案。

时钟源切换方法

修改 Src/system_gd32f4xx.c 的宏定义区(约第 46~69 行),同一型号组内只保留 一行未注释:

#if defined (GD32F405) || defined (GD32F407)
#define __SYSTEM_CLOCK_168M_PLL_IRC16M          (uint32_t)(168000000)   // 无外部晶振(默认)
//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)   // 板载 8MHz 晶振
//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL       (uint32_t)(168000000)   // 板载 25MHz 晶振
#endif
  • 切换到外部晶振(8M/25M HXTAL):改用对应宏之外,还需同步修改 SDK/CMSIS/GD/GD32F4xx/Include/gd32f4xx.h 中的 HXTAL_VALUE (默认 25000000,8M 晶振改为 8000000),两处必须一致。
  • 切换回内部时钟(IRC16M):注释 HXTAL 行、放开 IRC16M 行即可,无需其它修改。
  • 主频也可在宏区选择 120MHz 档(详见文件内注释),F405/407 最高 168MHz。

改完保存,重新编译烧录即生效。

实测参考:IRC16M 方案下 SCSS=PLLP(系统时钟已锁定 PLL)、SysTick 1ms 精确、 LED 心跳周期 2 秒整、USART1@APB1(42MHz) 波特率寄存器 365 对应 115200 精确。


芯片文档清单

doc/ 目录已齐备:

文件 说明
GD32F405xx_Datasheet_Rev2.8.pdf 芯片数据手册(RET6 属 xE 容量档)
GD32F4xx_User_Manual_Rev3.3.pdf 用户手册(寄存器/外设描述)
GD32F4xx_Firmware_Library_User_Guide_Rev1.2.pdf 固件库使用指南(英文)
GD32F4xx_固件库使用指南_Rev1.2.pdf 固件库使用指南(中文)
AN059 提高ADC采样精度的方法.pdf 应用笔记
AN200 GD32 Embedded Builder 链接脚本说明_Rev1.0.pdf 应用笔记

另:GD32F4xx.svd(调试寄存器视图)在工程根目录。


致谢