feat(build): 工具链改用 GD32_GCC_BIN 环境变量方案并新增 .vscode 烧录调试配置

This commit is contained in:
2026-09-14 17:17:57 +08:00
parent ec412b1ffd
commit 5723f521d7
9 changed files with 408 additions and 34 deletions
-1
View File
@@ -1,6 +1,5 @@
# 忽略构建输出目录 # 忽略构建输出目录
Build/ Build/
.vscode/
# 忽略 Toolchain 目录下所有内容,但保留目录本身 # 忽略 Toolchain 目录下所有内容,但保留目录本身
Toolchain/* Toolchain/*
+2
View File
@@ -0,0 +1,2 @@
erase
exit
+8
View File
@@ -0,0 +1,8 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cmake-tools",
"twxs.cmake",
"ms-vscode.cpptools"
]
}
+4
View File
@@ -0,0 +1,4 @@
loadfile Application.hex
r
go
exit
+58
View File
@@ -0,0 +1,58 @@
{
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/Build/Debug/Application/Application.elf",
"name": "Debug with OpenOCD",
"request": "launch",
"type": "cortex-debug",
"runToEntryPoint": "main",
"showDevDebugOutput": "none",
"gdbPath": "${env:GD32_GCC_BIN}/arm-none-eabi-gdb.exe",
"servertype": "openocd",
"serverpath": "${env:GD32_OPENOCD_BIN}/openocd.exe",
"svdFile": "${workspaceFolder}/GD32E230.svd",
"configFiles": [
"${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}"
],
"serverArgs": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}"
],
"env": {
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
},
"searchDir": [
"${workspaceFolder}"
],
"preLaunchTask": "Build",
"preRestartCommands": [
"load",
"continue"
]
},
{
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/Build/Debug/Application/Application.elf",
"name": "Debug with J-Link",
"request": "launch",
"type": "cortex-debug",
"runToEntryPoint": "main",
"showDevDebugOutput": "none",
"gdbPath": "${env:GD32_GCC_BIN}/arm-none-eabi-gdb.exe",
"servertype": "jlink",
"device": "${config:gd32.jlink.device}",
"interface": "${config:gd32.jlink.interface}",
"svdFile": "${workspaceFolder}/GD32E230.svd",
"liveWatch": {
"enabled": true,
"samplesPerSecond": 1
},
"preLaunchTask": "Build",
"preRestartCommands": [
"load",
"continue"
]
}
]
}
+2
View File
@@ -0,0 +1,2 @@
r
exit
+15
View File
@@ -0,0 +1,15 @@
{
"cmake.configureOnOpen": true,
"cmake.useCMakePresets": "always",
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cortex-debug.variableUseNaturalFormat": true,
"gd32.openocd.targetConfig": "target/openocd_gdlink_gd32e23x.cfg",
"gd32.openocd.massEraseCommand": "gd32e23x mass_erase 0",
"gd32.jlink.device": "GD32E230F8",
"gd32.jlink.interface": "SWD",
"gd32.jlink.speed": "4000",
"files.associations": {
"*.h": "c",
"*.c": "c"
}
}
+229
View File
@@ -0,0 +1,229 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "cmake",
"command": "build",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
{
"base": "$gcc",
"fileLocation": [
"relative",
"${command:cmake.buildDirectory}"
]
}
],
"options": {
"environment": {
"CLICOLOR_FORCE": "1",
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
}
},
"presentation": {
"clear": true
},
"icon": {
"id": "code",
"tooltip": "Build"
}
},
{
"label": "Build and Flash",
"dependsOn": [
"Build",
"Flash MCU"
],
"dependsOrder": "sequence",
"group": "build",
"icon": {
"id": "insert",
"tooltip": "Build and Flash"
}
},
{
"label": "Flash MCU",
"type": "process",
"command": "${env:GD32_OPENOCD_BIN}/openocd.exe",
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
"-c", "init; reset halt; flash write_image erase ${command:cmake.launchTargetFilename}; reset; exit"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${command:cmake.buildDirectory}/Application",
"environment": {
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
}
},
"presentation": {
"clear": true
},
"icon": {
"id": "gather",
"tooltip": "Flash MCU"
}
},
{
"label": "Reset MCU",
"type": "process",
"command": "${env:GD32_OPENOCD_BIN}/openocd.exe",
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
"-c", "init; reset; exit"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${command:cmake.buildDirectory}/Application",
"environment": {
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
}
},
"presentation": {
"clear": true
},
"icon": {
"id": "discard",
"tooltip": "Reset MCU"
}
},
{
"label": "Mass Erase MCU",
"type": "process",
"command": "${env:GD32_OPENOCD_BIN}/openocd.exe",
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
"-c", "init; reset halt; ${config:gd32.openocd.massEraseCommand}; exit"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${command:cmake.buildDirectory}/Application",
"environment": {
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
}
},
"presentation": {
"clear": true
},
"icon": {
"id": "clear-all",
"tooltip": "Erase MCU"
}
},
{
"label": "OpenOCD Server",
"type": "process",
"command": "${env:GD32_OPENOCD_BIN}/openocd.exe",
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${command:cmake.buildDirectory}/Application",
"environment": {
"OPENOCD_SCRIPTS": "${env:GD32_OPENOCD_SCRIPTS}"
}
},
"presentation": {
"clear": true
}
},
{
"label": "Build and Flash (Jlink)",
"dependsOn": [
"Build",
"Flash MCU (Jlink)"
],
"dependsOrder": "sequence",
"group": "build",
"icon": {
"id": "insert",
"tooltip": "Build and Flash (Jlink)"
}
},
{
"label": "Flash MCU (Jlink)",
"type": "process",
"command": "JLink.exe",
"args": [
"-device", "${config:gd32.jlink.device}",
"-if", "${config:gd32.jlink.interface}",
"-speed", "${config:gd32.jlink.speed}",
"-autoconnect", "1",
"-CommanderScript", "${workspaceFolder}/.vscode/flash.jlink"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${command:cmake.buildDirectory}/Application"
},
"presentation": {
"clear": true
},
"icon": {
"id": "gather",
"tooltip": "Flash MCU (Jlink)"
}
},
{
"label": "Reset MCU (Jlink)",
"type": "process",
"command": "JLink.exe",
"args": [
"-device", "${config:gd32.jlink.device}",
"-if", "${config:gd32.jlink.interface}",
"-speed", "${config:gd32.jlink.speed}",
"-autoconnect", "1",
"-CommanderScript", "${workspaceFolder}/.vscode/reset.jlink"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${workspaceFolder}"
},
"presentation": {
"clear": true
},
"icon": {
"id": "discard",
"tooltip": "Reset MCU (Jlink)"
}
},
{
"label": "Mass Erase MCU (Jlink)",
"type": "process",
"command": "JLink.exe",
"args": [
"-device", "${config:gd32.jlink.device}",
"-if", "${config:gd32.jlink.interface}",
"-speed", "${config:gd32.jlink.speed}",
"-autoconnect", "1",
"-CommanderScript", "${workspaceFolder}/.vscode/erase.jlink"
],
"group": "build",
"problemMatcher": [],
"options": {
"cwd": "${workspaceFolder}"
},
"presentation": {
"clear": true
},
"icon": {
"id": "clear-all",
"tooltip": "Erase MCU (Jlink)"
}
}
]
}
+89 -32
View File
@@ -1,24 +1,62 @@
# You can change TOOLCHAIN_DIRECTORY if you want to use different toolchain. # The project never stores a compiler package. Each machine supplies a path.
# set(TOOLCHAIN_DIRECTORY "${CMAKE_SOURCE_DIR}/Toolchain/xpack-arm-none-eabi-gcc-11.3.1-1.1/bin") # TOOLCHAIN_DIRECTORY (CMake cache) has priority over the environment variable.
# GD32_GCC_ENV_VAR lets a workstation use a different variable name if needed.
set(TOOLCHAIN_DIRECTORY "" CACHE PATH "Path to arm-none-eabi toolchain bin directory") set(TOOLCHAIN_DIRECTORY "" CACHE PATH "Path to arm-none-eabi toolchain bin directory")
set(GD32_GCC_ENV_VAR "GD32_GCC_BIN" CACHE STRING "Environment variable containing the ARM GCC path")
set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES TOOLCHAIN_DIRECTORY GD32_GCC_ENV_VAR)
if(GD32_GCC_ENV_VAR AND NOT GD32_GCC_ENV_VAR MATCHES "^GD32_[A-Za-z0-9_]+$")
message(FATAL_ERROR "GD32_GCC_ENV_VAR must use the GD32_ prefix: ${GD32_GCC_ENV_VAR}")
endif()
if(NOT TOOLCHAIN_DIRECTORY AND GD32_GCC_ENV_VAR)
if(DEFINED ENV{${GD32_GCC_ENV_VAR}} AND NOT "$ENV{${GD32_GCC_ENV_VAR}}" STREQUAL "")
file(TO_CMAKE_PATH "$ENV{${GD32_GCC_ENV_VAR}}" TOOLCHAIN_DIRECTORY)
endif()
endif()
if(NOT TOOLCHAIN_DIRECTORY) if(NOT TOOLCHAIN_DIRECTORY)
# Add extra auto-detect paths in this list when using another machine. message(FATAL_ERROR
# Example: "C:/your/path/xpack-arm-none-eabi-gcc-11.3.1-1.1/bin" "Cannot find ARM GCC toolchain. Set ${GD32_GCC_ENV_VAR} in the machine environment "
set(_TOOLCHAIN_CANDIDATES "or pass -DTOOLCHAIN_DIRECTORY=<toolchain-bin>.")
"D:/toolchain/xpack-arm-none-eabi-gcc-11.3.1-1.1/bin"
"C:/toolchain/xpack-arm-none-eabi-gcc-11.3.1-1.1/bin"
"${CMAKE_SOURCE_DIR}/Toolchain/xpack-arm-none-eabi-gcc-11.3.1-1.1/bin"
)
foreach(_candidate IN LISTS _TOOLCHAIN_CANDIDATES)
if(EXISTS "${_candidate}/arm-none-eabi-gcc.exe" OR EXISTS "${_candidate}/arm-none-eabi-gcc")
set(TOOLCHAIN_DIRECTORY "${_candidate}")
break()
endif()
endforeach()
endif() endif()
file(TO_CMAKE_PATH "${TOOLCHAIN_DIRECTORY}" TOOLCHAIN_DIRECTORY)
get_filename_component(TOOLCHAIN_DIRECTORY "${TOOLCHAIN_DIRECTORY}" ABSOLUTE)
if(WIN32)
set(TOOLCHAIN_SUFFIX ".exe")
else()
set(TOOLCHAIN_SUFFIX "")
endif()
# Accept either the package root or its bin directory.
if(NOT EXISTS "${TOOLCHAIN_DIRECTORY}/arm-none-eabi-gcc${TOOLCHAIN_SUFFIX}" AND
EXISTS "${TOOLCHAIN_DIRECTORY}/bin/arm-none-eabi-gcc${TOOLCHAIN_SUFFIX}")
set(TOOLCHAIN_DIRECTORY "${TOOLCHAIN_DIRECTORY}/bin")
endif()
set(_ARM_GCC_EXECUTABLE "${TOOLCHAIN_DIRECTORY}/arm-none-eabi-gcc${TOOLCHAIN_SUFFIX}")
set(_TOOLCHAIN_BINARIES
arm-none-eabi-gcc
arm-none-eabi-g++
arm-none-eabi-gdb
arm-none-eabi-ar
arm-none-eabi-ranlib
arm-none-eabi-as
arm-none-eabi-ld
arm-none-eabi-objcopy
arm-none-eabi-objdump
arm-none-eabi-size
)
foreach(_binary IN LISTS _TOOLCHAIN_BINARIES)
if(NOT EXISTS "${TOOLCHAIN_DIRECTORY}/${_binary}${TOOLCHAIN_SUFFIX}")
message(FATAL_ERROR
"ARM GCC toolchain is incomplete; missing ${_binary}${TOOLCHAIN_SUFFIX} in ${TOOLCHAIN_DIRECTORY}")
endif()
endforeach()
set(CMAKE_C_FLAGS_DEBUG "") set(CMAKE_C_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_DEBUG "") set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_ASM_FLAGS_DEBUG "") set(CMAKE_ASM_FLAGS_DEBUG "")
@@ -26,18 +64,10 @@ set(CMAKE_C_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELEASE "") set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_ASM_FLAGS_RELEASE "") set(CMAKE_ASM_FLAGS_RELEASE "")
if(NOT TOOLCHAIN_DIRECTORY)
message(FATAL_ERROR "Cannot find ARM GCC toolchain. Set TOOLCHAIN_DIRECTORY cache variable or install toolchain in one of the default locations.")
endif()
set(CMAKE_COLOR_DIAGNOSTICS ON) set(CMAKE_COLOR_DIAGNOSTICS ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
if(WIN32)
set(TOOLCHAIN_SUFFIX ".exe")
endif()
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_SYSTEM_PROCESSOR arm)
@@ -50,18 +80,45 @@ set(FLAGS "-mcpu=cortex-m23 -std=gnu11 -fstack-usage -
set(ASM_FLAGS "-x assembler-with-cpp") set(ASM_FLAGS "-x assembler-with-cpp")
set(CPP_FLAGS "-fno-rtti -fno-exceptions -fno-threadsafe-statics") set(CPP_FLAGS "-fno-rtti -fno-exceptions -fno-threadsafe-statics")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}) set(_REQUESTED_C_COMPILER "${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}")
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++${TOOLCHAIN_SUFFIX}) if(DEFINED CMAKE_C_COMPILER AND CMAKE_C_COMPILER AND
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}) IS_ABSOLUTE "${CMAKE_C_COMPILER}" AND
NOT CMAKE_C_COMPILER STREQUAL "${_REQUESTED_C_COMPILER}")
message(FATAL_ERROR
"The build directory is already configured for a different ARM GCC compiler:\n"
" cached: ${CMAKE_C_COMPILER}\n"
" selected: ${_REQUESTED_C_COMPILER}\n"
"Delete the build directory or run CMake Tools 'Delete Cache and Reconfigure'.")
endif()
set(CMAKE_C_COMPILER "${_REQUESTED_C_COMPILER}")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PREFIX}g++${TOOLCHAIN_SUFFIX}")
set(CMAKE_ASM_COMPILER "${TOOLCHAIN_PREFIX}gcc${TOOLCHAIN_SUFFIX}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS} ${CPP_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS} ${CPP_FLAGS}")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${FLAGS} ${ASM_FLAGS}") set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${FLAGS} ${ASM_FLAGS}")
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy${TOOLCHAIN_SUFFIX}) set(CMAKE_AR "${TOOLCHAIN_PREFIX}ar${TOOLCHAIN_SUFFIX}")
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size${TOOLCHAIN_SUFFIX}) set(CMAKE_RANLIB "${TOOLCHAIN_PREFIX}ranlib${TOOLCHAIN_SUFFIX}")
set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump${TOOLCHAIN_SUFFIX}) set(CMAKE_OBJCOPY "${TOOLCHAIN_PREFIX}objcopy${TOOLCHAIN_SUFFIX}")
set(CMAKE_AS ${TOOLCHAIN_PREFIX}as${TOOLCHAIN_SUFFIX}) set(CMAKE_SIZE "${TOOLCHAIN_PREFIX}size${TOOLCHAIN_SUFFIX}")
set(CMAKE_LD ${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}) set(CMAKE_OBJDUMP "${TOOLCHAIN_PREFIX}objdump${TOOLCHAIN_SUFFIX}")
set(CMAKE_AS "${TOOLCHAIN_PREFIX}as${TOOLCHAIN_SUFFIX}")
set(CMAKE_LD "${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}")
set(CMAKE_LINKER "${TOOLCHAIN_PREFIX}ld${TOOLCHAIN_SUFFIX}")
execute_process(
COMMAND "${_ARM_GCC_EXECUTABLE}" --version
OUTPUT_VARIABLE _ARM_GCC_VERSION_OUTPUT
ERROR_VARIABLE _ARM_GCC_VERSION_ERROR
RESULT_VARIABLE _ARM_GCC_VERSION_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT _ARM_GCC_VERSION_RESULT EQUAL 0)
message(FATAL_ERROR "Unable to execute ${_ARM_GCC_EXECUTABLE}: ${_ARM_GCC_VERSION_ERROR}")
endif()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" _ARM_GCC_VERSION "${_ARM_GCC_VERSION_OUTPUT}")
message(STATUS "Using ARM GCC ${_ARM_GCC_VERSION} from ${TOOLCHAIN_DIRECTORY}")
set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf") set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf")
set(CMAKE_EXECUTABLE_SUFFIX_C ".elf") set(CMAKE_EXECUTABLE_SUFFIX_C ".elf")