Template
356 lines
15 KiB
Markdown
356 lines
15 KiB
Markdown
# 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 来源。
|