Setting Up GD32 Development Environment on Windows Using VSCode and CMake
I previously set up the GD32 development environment in a Linux environment, but since I often use Windows, I made some improvements based on the original setup to enable compiling, downloading, and debugging microcontroller programs on Windows. See the following tweets for details:
Building GD32F470 Project Based on CMake
Debugging GD32F470 Based on PyOCD
Implementation Approach
- Code Build: CMake, using the original CMakeLists file
- Code Compilation: Invoking CMake
- Program Download: Invoking OpenOCD
- Program Debugging: Using Cortex-Debug
- Program Printing: Using RTT via PyOCD
Among these, building, compiling, downloading, and printing are all written as VSCode tasks and visualized with Task Buttons.
Results
Results of building, compiling, downloading, and printing:
Debugging results
Preparation Work
- Microcontroller: GD32F450
- Debugger: DAPLink
- PC: Windows 10
- Editor: VSCode
- Cross Compilation Toolchain: gcc-arm-none-eabi-10.3-2021.10
- Build Tools: CMake, MinGW64 (mainly provides make tools)
- Code Flashing and Debugging Tool: OpenOCD (Windows version)
- Debug Plugin: Cortex-Debug (plugin used in VSCode)
- VSCode Task Visualization Button Plugin: Task Buttons
- RTT Printing Tool: PyOCD (PyOCD can also perform code flashing and debugging, but when using DAPLink + Cortex-Debug, live watch is not available)
Code Build
Code build refers to automatically generating a Makefile using CMake to prepare for the next step of compilation (if you directly use the Makefile, building is not necessary).
Implementing this by writing a task to invoke the CMake command:
Add to the <span>.vscode/tasks.json</span> tasks field (create this file if it does not exist):
{
// Task name
"label": "CMake Configure",
// Terminal execution
"type": "shell",
// Command to execute
"command": "cmake",
// Arguments passed to the command
"args": [
"-S", "${workspaceFolder}", // Source directory
"-B", "${workspaceFolder}/build", // Build directory
"-DTOOLCHAIN_PREFIX=C:/Users/haijun/Desktop/123/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-", // Specify cross-compilation prefix
"-G", "MinGW Makefiles", // Specify generator
"-DCMAKE_MAKE_PROGRAM=C:/Users/haijun/Desktop/123/mingw64/bin/mingw32-make.exe"// Specify make program
],
// Specify the directory for task execution and add temporary environment variables
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PATH": "C:/Users/haijun/Desktop/123/mingw64/bin;${env:PATH}"
}
},
// Task belongs to the build group.
"group": {
"kind": "build",
"isDefault": false
},
// Parse error messages
"problemMatcher": [],
"detail": "Configure CMake project"
},
- Since I did not add the CMake tool to the environment variable, I temporarily added CMake to the environment variable using
<span>env</span>. - Both the cross-compilation toolchain and make program are not added to the environment variable, so absolute paths are used directly.
- The actual CMake command executed:
cmake -S source_path \
-B build_directory \
-DTOOLCHAIN_PREFIX=C:/Users/haijun/Desktop/123/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi- \
-G MinGW Makefiles \
-DCMAKE_MAKE_PROGRAM=C:/Users/haijun/Desktop/123/mingw64/bin/mingw32-make.exe
Open the command palette <span>ctrl+shift+p</span>, search for <span>tasks:run Task</span>, you can see the task and click to execute it.
Code Compilation
Add to the <span>.vscode/tasks.json</span> tasks field:
{
"label": "CMake Build",
"type": "shell",
"command": "cmake",
"args": [
"--build", "build", // Path to build
"--target", "all", // Compile all
"-j 8" // Multi-threading to speed up compilation
],
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PATH": "C:/Users/haijun/Desktop/123/openocd-v0.12.0-i686-w64-mingw32/bin;${env:PATH}"
},
"group": {
"kind": "build",
"isDefault": true
},
// Automatically parse compiler output
"problemMatcher": {
"owner": "cpp", // Parse C/C++ output
"fileLocation": ["relative", "${workspaceFolder}"], // Use relative paths
// Match compiler output using regular expressions
"pattern": {
"regexp": "^(.*):(\d+):(\d*):\s*(warning|error):\s*(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
- The actual command executed:
cmake --build build --target all -j 8
- Configure the
<span>problemMatcher</span>field to match C errors and warnings and allow jumping to them.
Open the command palette <span>ctrl+shift+p</span>, search for <span>tasks:run Task</span>, you can see the task and click to execute it.
Code Download
Code download uses OpenOCD.
Add to the <span>.vscode/tasks.json</span> tasks field:
{
"label": "flash-openocd",
"type": "shell",
"command": "openocd",
"args": [
"-f", "./pyocd/openocd.cfg",
"-c", "program build/gd32f470BaseProject.elf verify reset exit"
],
"group": {
"kind": "build",
"isDefault": false
},
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PATH": "C:/Users/haijun/Desktop/123/openocd-v0.12.0-i686-w64-mingw32/bin;${env:PATH}"
},
},
// There are dependencies, dependent tasks are executed in order
"dependsOn": ["CMake Build"],
"dependsOrder": "sequence",
"problemMatcher": [],
"detail": "Flashing using OpenOCD"
},
The actual command executed:
openocd -f ./pyocd/openocd.cfg -c program build/gd32f470BaseProject.elf verify reset exit
Among them:
<span>openocd.cfg</span>is the configuration file for OpenOCD.
# Downloader: cmsis-dap
adapter driver cmsis-dap
# Download method swd
transport select swd
# Target chip configuration file (since there is no gd32f4, use stm32f4x instead)
source [find target/stm32f4x.cfg]
<span>-c indicates the command to execute</span><span>program</span>is the program to be downloaded<span>verify</span>verifies after downloading<span>reset</span>resets the MCU<span>exit</span>exits OpenOCD
Open the command palette <span>ctrl+shift+p</span>, search for <span>tasks:run Task</span>, you can see the task and click to execute it.
- This task depends on
<span>CMake Build</span>and executes in order.
Program Debugging
Debugging uses Cortex-Debug, so you need to configure the <span>launch.json</span> file.
Two methods for invoking <span>openocd</span> and <span>pyocd</span> are provided.
{
// Use IntelliSense to learn about related properties.
// Hover to view descriptions of existing properties.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug with OpenOCD",
"serverpath": "C:/Users/haijun/Desktop/123/openocd-v0.12.0-i686-w64-mingw32/bin/openocd.exe",
"armToolchainPath": "C:/Users/haijun/Desktop/123/gcc-arm-none-eabi-10.3-2021.10/bin/",
"cwd": "${workspaceRoot}",
"executable": "./build/gd32f470BaseProject.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"configFiles": [
"./pyocd/openocd.cfg"],
"searchDir": [],
"runToEntryPoint": "main",
"showDevDebugOutput": "none",
"liveWatch": {
"enabled": true,
"samplesPerSecond": 1
},
"preLaunchTask": "CMake Build"
},
{
"name": "GD32 Debug with PyOCD",
"armToolchainPath": "C:/Users/haijun/Desktop/123/gcc-arm-none-eabi-10.3-2021.10/bin/",
"cwd": "${workspaceRoot}",
"executable": "./build/gd32f470BaseProject.elf",
"request": "launch",
"type": "cortex-debug",
"runToEntryPoint": "main",
"servertype": "pyocd",
"targetId":"gd32f470zg",
"showDevDebugOutput": "none",
"cmsisPack": "./pyocd/GigaDevice.GD32F4xx_DFP.3.2.0.pack",
"liveWatch": {
"enabled": true,
"samplesPerSecond": 1
}
}
]
}
RTT Printing
Invoke the <span>pyocd rtt</span> command.
Add to the <span>.vscode/tasks.json</span> tasks field:
{
"label": "RTT Print via pyOCD",
"type": "shell",
"command": "pyocd rtt",
"args": [
"--config", "pyocd.yaml"
],
"presentation": {
"reveal": "always",
"panel": "shared",
"echo": true,
"focus": true,
"showReuseMessage": true,
"clear": false
},
"options": {
"cwd": "${workspaceFolder}/pyocd",
},
"problemMatcher": [],
"isBackground": true,
"detail": "View RTT print using pyOCD"
}
The actual command executed:
pyocd rtt --config pyocd.yaml
Task Visualization Buttons
Use the <span>Task Buttons</span> plugin to visualize tasks.
Add to the <span>settings.json</span>:
{
// Whether to show tasks
"VsCodeTaskButtons.showCounter": true,
// Button list
"VsCodeTaskButtons.tasks": [
{
// Button name
"label": "๐ ๏ธ",
// Associated task
"task": "CMake Configure",
// Mouse hover tip
"tooltip": "Start cmake Configure",
// "color": "warning",
},
{
"label": "๐ ",
"task": "CMake Build",
"tooltip": "Build the project",
},
{
"label": "๐ฅ",
"task": "flash-openocd",
"tooltip": "Download bin file to flash",
},
{
"label": "๐งน",
"task": "CMake Clean",
"tooltip": "Clean the project",
},
{
"label": "๐จ๏ธ",
"task": "RTT Print via pyOCD",
"tooltip": "Print RTT info",
}
]
}