Files
gd32f4xx_template_cmake_vscode/README.md
T

356 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GD32F4xx 工程模板
本仓库为兆易创新 GD32F4xx 系列 MCU(Cortex-M4)的 CMake + VSCode 工程模板,
组织方式与编译方法沿用 [gd32e23x_template_cmake_vscode](../gd32e23x_template_cmake_vscode),
在其基础上适配 **GD32F405RET6**(默认型号,64 脚 LQFP,512KB Flash / 192KB SRAM)。
构建输出位于工程根 `Build/`。
---
## 目录
- [适用范围](#适用范围)
- [默认配置](#默认配置)
- [快速开始](#快速开始)
- [工程结构](#工程结构)
- [板级配置](#板级配置)
- [更换目标型号](#更换目标型号)
- [Flash 偏移配置(配合 Bootloader)](#flash-偏移配置配合-bootloader)
- [工具链准备](#工具链准备)
- [使用说明](#使用说明)
- [时钟配置说明](#时钟配置说明)
- [芯片文档清单](#芯片文档清单)
- [致谢](#致谢)
---
## 适用范围
- 适用于兆易创新 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](AGENTS.md) 进度清单
- 浮点:硬件 FPU(`-mfpu=fpv4-sp-d16 -mfloat-abi=hard`),SystemInit 中自动使能
---
## 快速开始
### 基于模板创建新项目
1. **克隆或复制本仓库**
2. **修改项目配置** — 编辑 `cmake/project_config.cmake`:
```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. **编译**
```bash
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()`),收发切换逻辑需在
> 业务层调用。
### 引脚定义
```c
/* 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)。
```bash
# 切换到 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:
```c
// 默认:从 Flash 起始运行
FLASH (rx): ORIGIN = 0x08000000, LENGTH = 1024K
// 配合 Bootloader:前 64KB 留给 Bootloader,App 从 0x08010000 开始
FLASH (rx): ORIGIN = 0x08010000, LENGTH = 960K
```
**2. 向量表偏移** — `Src/system_gd32f4xx.c` 第 44 行:
```c
// 默认
#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(调试/烧录)
- **版本**:xpack-openocd-0.11.0-3(与 E23x 工程一致)
- **获取地址**:https://github.com/burakenez/gd32-tools-xpack-openocd/tree/v0.11.0-3
- **活动变量**:`GD32_OPENOCD_BIN`、`GD32_OPENOCD_SCRIPTS`
与 E23x 工程不同,本模板的 OpenOCD 目标配置**放在工程内**(借鉴
[metax-sensors/gd32-cmake-example](https://github.com/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 时只需改这一份文件。
每台开发电脑配置一次用户环境变量(路径按本机实际位置填写):
```powershell
[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`)。
---
## 使用说明
### 编译
```bash
# 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 行),**同一型号组内只保留
一行未注释**:
```c
#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`(调试寄存器视图)在工程根目录。
---
## 致谢
- [celalkismiroglu/gd32e23x-demo-suites-cmake](https://github.com/celalkismiroglu/gd32e23x-demo-suites-cmake)
—— E23x 模板的起点,本工程的模板体系由其迭代而来。
- [metax-sensors/gd32-cmake-example](https://github.com/metax-sensors/gd32-cmake-example)
—— GD32F4xx + CMake 的开源参考(OpenOCD stm32f4x 驱动方案、工程内 cfg 组织)。
- 兆易创新 GD32F4xx_Demo_Suites_V3.3.3 / GD32F4xx_Firmware_Library —— SDK 来源。