π Welcome to the GD32F527 Demo Suites CMake Visual Studio Code repository! This project integrates the CMake build system with Visual Studio Code for GD32F527 Demo Suites V1.4.0 and GD32F527 Firmware Library V1.4.0, running entirely inside a container β no local toolchain installation needed.
π³ The development environment is fully containerized. The compiler, debugger, CMake, Ninja, and OpenOCD are all pre-installed inside a Docker/Podman container that VS Code manages automatically.
- β¨ Features
- π οΈ Requirements
- π§ Getting Started
- β¨οΈ VS Code Tasks
- π¦ Drivers and Middlewares
- π Folder Structure
- π³ Toolchain Container
- π Troubleshooting
- π¦ Zero-Setup Toolchain: Everything runs inside a container β no manual GCC or OpenOCD installation required.
- π§ Pre-configured Toolchain: ARM GNU GCC (
gcc-arm-none-eabi) and GigaDevice-patched xpack-openocd 0.12.0-6 with full GD32 flash algorithm support. - π Robust Debug Configuration: Pre-configured
launch.jsonwith live watch, SVD peripheral views, and one-click GDB debugging via OpenOCD. - π§© Rich Extension Support: Extensions like
ms-vscode.cmake-tools,marus25.cortex-debug,mcu-debug.peripheral-viewer, andmcu-debug.memory-vieware automatically installed inside the container β peripheral viewers, RTOS views, memory views, and GNU map file tools provide a comprehensive debugging experience. - βοΈ Works on Windows (WSL2) and Linux: The container abstracts away the host OS. Native macOS support (build + debug) is on the roadmap β contributions and feedback are welcome.
| Tool | Purpose |
|---|---|
| VS Code | IDE |
| Dev Containers extension | Opens the project inside the container |
| Podman Desktop | Container engine (Docker works too) |
| WSL 2 (Windows only) | Linux environment required by Dev Containers on Windows |
| Git | Clone the repository |
π§ Linux users can skip this step.
Open PowerShell as Administrator and run:
wsl --installThis installs WSL 2 with Ubuntu by default. Restart your computer when prompted.
Verify the installation:
wsl --list --verboseThe Ubuntu distribution should show Version 2. If it shows Version 1, upgrade it:
wsl --set-version Ubuntu 2Windows (inside WSL Ubuntu) / Linux:
sudo apt update && sudo apt install -y podman
systemctl --user enable --now podman.socketVerify Podman is working:
podman --versionOpen VS Code settings (Ctrl+,), search for dockerPath, and set dev.containers.dockerPath to podman.
π‘ If you prefer Docker, install Docker Desktop instead and skip the VS Code setting above β Dev Containers detects it automatically.
- Install Visual Studio Code.
- Open VS Code, go to the Extensions panel (
Ctrl+Shift+X), search for Dev Containers, and install:- Dev Containers (
ms-vscode-remote.remote-containers)
- Dev Containers (
git clone https://github.com/burakenez/gd32f527-cmake-vscode.git
β οΈ Avoid long directory paths β they can cause build failures on Windows.
Opening a project is a two-step process: first start the container from the repository root, then open the specific project inside it.
Step 1 β Start the container
- Open VS Code.
- Go to File β Open Folder and select the repository root (the folder that contains
.devcontainer/). - VS Code detects
.devcontainer/devcontainer.jsonand shows a notification:"Folder contains a Dev Container configuration file. Reopen folder to develop in a container."
- Click Reopen in Container.
VS Code builds the container image (first time only, a few minutes) and opens the repository root inside it. All tools β compiler, debugger, CMake, Ninja β are available immediately.
Step 2 β Open the project
Once inside the container, go to File β Open Folder and select the project you want to work on:
Projects/<BoardName>/<ProjectName>
VS Code reopens that folder inside the same running container. The project's .vscode/launch.json and tasks.json become active, and ${workspaceFolder} resolves correctly to the project directory.
β‘ On subsequent opens VS Code reconnects to the existing container instantly.
Inside the container, build using any of these methods:
- Click the Build button in the VS Code status bar.
- Press
Ctrl+Shift+Band select Build. - Press
Ctrl+Shift+P, type CMake: Build, and press Enter.
Output files are placed in:
Projects/<BoardName>/<ProjectName>/Build/Debug/Application/
| Output file | Description |
|---|---|
Application.elf |
ELF with debug symbols β used for debugging |
Application.bin |
Raw binary β ready to flash |
Application.hex |
Intel HEX format |
Application.map |
Memory map |
Application.list |
Assembly listing |
On Linux: The USB device is directly accessible β no extra setup needed.
On Windows (WSL 2): USB devices are not automatically shared with WSL. Use usbipd-win to attach the probe:
Step 1 β Install usbipd-win on Windows (one-time)
Open PowerShell as Administrator:
winget install usbipdStep 2 β Install client tools inside WSL (one-time)
Open a WSL terminal:
sudo apt install linux-tools-generic hwdata usbutils
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20Step 3 β Grant USB device access (one-time, in WSL terminal)
WSL 2 creates USB device nodes owned by root:root with mode 664, which blocks write access from inside the devcontainer. Fix this permanently with a udev rule:
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="28e9", MODE="0666"' | sudo tee /etc/udev/rules.d/99-gdlink.rules && sudo udevadm control --reload-rulesπ‘ If your WSL 2 distro doesn't run udevd (check with
systemctl is-active systemd-udevd), apply the permission manually after eachusbipd attach:sudo chmod a+rw $(ls /dev/bus/usb/*/*)
Step 4 β Attach the GD-Link to WSL (each session)
Open PowerShell as Administrator and list USB devices:
usbipd listFind the GD-Link entry β known VID:PID values are 28e9:0189, 28e9:058f, 28e9:0497, 28e9:068f, 28e9:f002. Then bind (first time only) and attach:
usbipd bind --busid <BUSID>
usbipd attach --wsl --busid <BUSID>Verify it is visible inside WSL:
lsusbYou should see a line containing GDMicroelectronics or GD-Link.
β οΈ Attach the GD-Link to WSL before opening the devcontainer. The container captures USB device nodes at startup β devices attached after the container starts will not be visible inside it. If you forget, see GD-Link not detected after plugging in in the Troubleshooting section.
Step 5 β Detach when done
usbipd detach --busid <BUSID>- Go to Run and Debug (
Ctrl+Shift+D) in VS Code. - Select Debug with OpenOCD from the dropdown.
- Press
F5or click Start Debugging.
To flash without debugging, use the Flash MCU task (Ctrl+Shift+B β Flash MCU).
All tasks are available via Ctrl+Shift+B:
| Task | Description |
|---|---|
| Build | Compile the project with CMake + Ninja (Debug preset) |
| Build and Flash | Build then immediately flash the firmware |
| Flash MCU | Flash the last built .elf via OpenOCD |
| Reset MCU | Reset the target MCU via OpenOCD |
| Mass Erase MCU | Erase the entire flash memory |
| OpenOCD Server | Start a standalone OpenOCD server for external GDB clients |
| Kill OpenOCD | Terminate any running OpenOCD process |
- Version:
v6.3.0 - Path:
Drivers/CMSIS
- Version:
V1.4.0 (2026-01-31) - Path:
Drivers/CMSIS/GD/GD32F527 - Source:
GD32F527 Demo Suites V1.4.0
- Version:
V1.4.0 (2026-01-31) - Path:
Drivers/GD32F527_standard_peripheral - Source:
GD32F527 Demo Suites V1.4.0
- Version:
V1.4.0 (2026-02-06) - Path:
Drivers/GD32F527_usb_library - Source:
GD32F527 Demo Suites V1.4.0
- Version:
V11.3.0 - Path:
Middlewares/FreeRTOS - Source:
FreeRTOS-Kernel
- Version:
R0.16 - Path:
Middlewares/FatFs - Source:
FatFs by ChaN
- Version:
STABLE-2.2.1 - Path:
Middlewares/lwip - Source:
lwIP
βββ .devcontainer
β βββ Containerfile # Container image definition
β βββ devcontainer.json # VS Code Dev Container configuration
βββ Drivers # Shared drivers (CMSIS, BSP, standard peripheral, USB)
βββ Middlewares # Shared middleware libraries (FreeRTOS, FatFs, lwIP, ...)
βββ Projects # Demo suite board projects
β βββ <BoardName>
β βββ <ProjectName>
β βββ .vscode
β β βββ launch.json # Debug configuration (OpenOCD + GDB + SVD)
β β βββ settings.json # Workspace settings
β β βββ tasks.json # Build, flash, reset, and erase tasks
β βββ Application
β β βββ Core
β β β βββ Inc
β β β β βββ gd32f527_it.h # Interrupt handler declarations
β β β β βββ gd32f527_libopt.h # Library options
β β β β βββ systick.h # SysTick timer declarations
β β β βββ Src
β β β βββ gd32f527_it.c # Interrupt service routines
β β β βββ main.c # Application entry point
β β β βββ system_gd32f527.c # Clock and core initialisation
β β β βββ systick.c # SysTick timer implementation
β β βββ Startup
β β β βββ startup_gd32f527.s # Reset handler and vector table
β β βββ CMakeLists.txt # Application build rules
β βββ cmake
β β βββ arm-none-eabi-gcc.cmake # ARM GCC toolchain settings
β β βββ project.cmake # Project-wide CMake configuration
β βββ Drivers
β β βββ BSP/GD32F527I_EVAL # Board support package for GD32F527I_EVAL
β β βββ CMSIS # CMSIS for Cortex-M / GD32F527
β β βββ GD32F527_standard_peripheral # Standard peripheral library
β βββ .clang-format # Code style rules
β βββ CMakeLists.txt # Top-level CMake build file
β βββ CMakePresets.json # Debug / Release preset definitions
β βββ gd32f527_flash.ld # Linker script (memory regions)
β βββ GD32F527.svd # SVD file for peripheral register views
βββ Examples # Firmware library examples (one project per example)
β βββ <Peripheral> # e.g. ADC, CAN, TIMER, USART, ...
β βββ <ExampleName> # Same project structure as Projects/<BoardName>/<ProjectName>
βββ Template # Bare-minimum template project (firmware library)
β βββ ... # Same project structure as Projects/<BoardName>/<ProjectName>
βββ README.md
The container is defined by .devcontainer/Containerfile and built locally the first time you open the project in VS Code β no registry login or pre-built image required.
| Tool | Version | Purpose |
|---|---|---|
gcc-arm-none-eabi |
system apt | ARM C/C++ compiler |
gdb-multiarch |
system apt | GDB debugger (symlinked as arm-none-eabi-gdb) |
binutils-multiarch |
system apt | objdump and nm required by cortex-debug |
cmake + ninja-build |
system apt | Build system |
xpack-openocd |
0.12.0-6 | Installed to /opt/xpack-openocd-0.12.0-6/ with GD32 flash algorithm support |
| Extension | Purpose |
|---|---|
ms-vscode.cmake-tools |
CMake integration |
ms-vscode.cpptools |
C/C++ IntelliSense and debugging |
marus25.cortex-debug |
ARM Cortex-M debug adapter (OpenOCD, J-Link, ...) |
mcu-debug.peripheral-viewer |
SVD-based peripheral register viewer |
mcu-debug.memory-view |
Live memory inspector |
mcu-debug.rtos-views |
FreeRTOS task and queue viewer |
ms-vscode.hexeditor |
Hex file viewer |
dan-c-underwood.arm |
ARM assembly syntax highlighting |
zixuanwang.linkerscript |
Linker script syntax highlighting |
trond-snekvik.gnu-mapfiles |
GNU map file viewer |
π§ xpack-openocd's bundled
libhidapi-hidrawcannot access/dev/hidraw*inside Docker+WSL2 containers. TheContainerfilereplaces it withlibhidapi-libusb(same API, accesses the GD-Link via/dev/bus/usbinstead).
π§ The devcontainer uses
--device=/dev/bus/usb:/dev/bus/usbto pass USB devices into the container. Device nodes are captured at container startup β attach the GD-Link before opening the container. If the board is replugged or attached after startup, rebuild the container (Ctrl+Shift+Pβ Dev Containers: Rebuild Container).
β±οΈ The first container build takes a few minutes (downloads xpack-openocd from GitHub). Subsequent opens reuse the cached image instantly.
The container captures USB device nodes at startup. If you attached the GD-Link after the container was already running:
- In PowerShell, attach the board to WSL first:
usbipd attach --wsl --busid <BUSID>
- In VS Code, rebuild the container:
Ctrl+Shift+Pβ Dev Containers: Rebuild Container
If VS Code appears frozen while building or rebuilding the container (spinning indefinitely with no progress):
Ctrl+Shift+P β Developer: Reload Window
VS Code will reconnect and continue where it left off.
After extensions are installed inside the container, you may see:
"Cannot activate the 'Cortex-Debug' extension because it depends on the 'debug-tracker-vscode' extension, which is not loaded. Would you like to reload the window to load the extension?"
Click Reload Window. This is a one-time ordering issue on first install β it will not appear again after the reload.