STM32N6 系列作为 ST 新一代高性能 MCU,其开发工具链的选择却让不少习惯 VSCode 的开发者陷入两难。官方主推的 STM32CubeIDE 虽然功能强大,但臃肿的界面和繁琐的操作流程,对于追求效率的开发者来说实在不够友好。本文将分享一套基于 VSCode 的轻量化调试方案,帮助大家摆脱官方 IDE 的束缚,重获流畅的开发体验。
为什么放弃 STM32CubeIDE?
STM32CubeIDE 作为 ST 官方推荐的 IDE,在功能上无可挑剔,但实际使用中却存在不少痛点:
- 启动和响应速度慢:对于习惯 VSCode 或 Visual Studio 的开发者来说,其卡顿感尤为明显。
- 快捷键不通用:常规的调试快捷键与主流 IDE 不一致,增加了学习成本。
- STLink 兼容性问题:与 STM32CubeProg 配合使用时,常出现 STLink v2 版本检测冲突,导致下载程序时卡死或无响应。
虽然 ST 官方也提供了 STM32CubeIDE for Visual Studio Code 插件,但其依赖 CMake 配置,导致工程文件结构复杂,且 VSCode 版本升级后容易出现兼容性问题,调试环境难以稳定维持。对于追求极致效率的开发者而言,这无疑是一种折磨。
本文将介绍一种更简洁、更稳定的调试方案,仅需一个插件和简单的 Makefile 配置,即可在 VSCode 中轻松调试 STM32N6 系列单片机。
前期准备:VSCode 与插件安装
在开始之前,请确保已安装好 VSCode,并完成基础 C/C++ 开发环境的配置。如果尚未完成,可以参考网上相关教程进行安装。
接下来,我们需要在 VSCode 插件市场中搜索并安装 STM32Cube Debug STLink GDB Server 插件。该插件会自动安装所需的依赖项,无需额外手动配置,安装完成后即可使用。

工程编译:Makefile 的编写
在工程管理方面,虽然 CMake 在跨平台领域更具优势,但在 STM32N6 开发中,使用 CMake 会触发官方插件的干预,反而让事情变得复杂。因此,本文推荐使用 Makefile 来管理工程编译。
编写 Makefile 前,需要先理清工程的文件结构,明确参与编译和链接的文件以及需要包含的头文件路径。以下是一个典型的工程结构示例:
stm32n647_vscode_debug_demo_fsbl
├── Drivers
│ ├── CMSIS
│ │ ├── Device
│ │ │ └── ......
│ │ └── Include
│ │ ├── core_cm55.h
│ │ └── tz_context.h
│ │ └── ......
│ └── STM32N6xx_HAL_Driver
│ ├── Inc
│ │ ├── Legacy
│ │ │ └── stm32_hal_legacy.h
│ │ ├── stm32_assert_template.h
│ │ ├── stm32n6xx_hal.h
│ │ ├── ......
│ └── Src
│ ├── stm32n6xx_hal.c
│ ├── stm32n6xx_hal_cortex.c
│ ├── stm32n6xx_hal_crc.c
│ ├── stm32n6xx_hal_crc_ex.c
│ ├── ......
├── HyperRAM
│ ├── hyperram.c
│ └── hyperram.h
├── Makefile
├── NORFlash
│ └── ***.c/h
├── Output
├── STM32CubeIDE
│ ├── .cproject
│ ├── .project
│ ├── STM32N647X0HXQ_AXISRAM2_fsbl.ld
│ └── postbuild.sh
├── STM32_ExtMem_Manager
│ ├── boot
│ │ ├── ***.c/h
│ └── ......
├── SVD
│ └── STM32N647.svd
├── Startup
│ └── startup_stm32n647x0hxq_fsbl.s
├── System
│ ├── syscalls.c
│ └── sysmem.c
├── User
│ ├── extmem
│ │ ├── extmem_manager.c
│ │ ├── extmem_manager.h
│ │ └── stm32_extmem_conf.h
│ ├── it
│ │ ├── stm32n6xx_it.c
│ │ └── stm32n6xx_it.h
│ ├── main
│ │ ├── main.c
│ │ └── main.h
│ ├── stm32n6xx_hal_conf.h
│ ├── stm32n6xx_hal_msp.c
│ ├── system_stm32n6xx_fsbl.c
│ ├── ulog
│ │ ├── uLog.c
│ │ └── uLog.h
│ └── usart
│ ├── usart.c
│ └── usart.h
└── vscode.code-workspace
在了解工程结构后,即可编写 Makefile 文件。以下是一个基础的 Makefile 配置示例,其中包含了详细的注释说明:
TARGET = STM32N647_FSBL
# IMPORTANT 请注意此处将会开启调试模式,将会有大量的日志输出并性能下降,请在正式发布之前关闭调试模式。
DEBUG_ENABLE ?= 0
# debug build?
DEBUG_MODE ?= $(DEBUG_ENABLE)
# optimization
OPT ?= -Os
# Og:优化调试体验。 -Og应该是标准edit-compile-debug周期的优化级别选择,
# 它提供了足够的优化以提高代码执行速度,同时保持了良好的调试体验。
# Os:这个选项是在-O2的基础之上,尽量的降低目标代码的大小,也是编译目标文件最小的选项
# O2:该优化选项会牺牲部分编译速度,除了执行-O1所执行的所有优化之外,还会采用几乎所有的目标
# 配置支持的优化算法,用以提高目标代码的运行速度
# O3:该选项除了执行-O2所有的优化选项之外,一般都是采取很多向量化算法,提高代码的并行执行程度,
# 利用现代CPU中的流水线,Cache等
# Build path
BUILD_DIR = build
OUTPUT_DIR = Output
# CPP sources
CPP_SOURCES = \
# C sources
C_SOURCES = \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_cortex.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_dma.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_dma_ex.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_exti.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_gpio.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_pwr.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_pwr_ex.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_rcc.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_rcc_ex.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_uart.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_uart_ex.c \
Drivers/STM32N6xx_HAL_Driver/Src/stm32n6xx_hal_xspi.c \
STM32_ExtMem_Manager/boot/stm32_boot_xip.c \
STM32_ExtMem_Manager/stm32_extmem.c \
STM32_ExtMem_Manager/psram/stm32_psram_driver.c \
STM32_ExtMem_Manager/sal/stm32_sal_sd.c \
STM32_ExtMem_Manager/sal/stm32_sal_xspi.c \
STM32_ExtMem_Manager/sdcard/stm32_sdcard_driver.c \
STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_data.c \
STM32_ExtMem_Manager/nor_sfdp/stm32_sfdp_driver.c \
STM32_ExtMem_Manager/user/stm32_user_driver.c \
User/extmem/extmem_manager.c \
User/main/main.c \
User/ulog/uLog.c \
User/usart/usart.c \
User/stm32n6xx_hal_msp.c \
User/it/stm32n6xx_it.c \
User/system_stm32n6xx_fsbl.c \
# 包含目录下的所有的.c文件
C_SOURCES += $(wildcard System/*.c)
C_SOURCES += $(wildcard HyperRAM/*.c)
C_SOURCES += $(wildcard NORFlash/*.c)
# ASM sources
ASM_SOURCES = \
Startup/startup_stm32n647x0hxq_fsbl.s
# link script
LDSCRIPT = \
STM32CubeIDE/STM32N647X0HXQ_AXISRAM2_fsbl.ld
# C includes
C_INCLUDES = \
-IDrivers/STM32N6xx_HAL_Driver/Inc \
-IDrivers/CMSIS/Device/ST/STM32N6xx/Include \
-IDrivers/STM32N6xx_HAL_Driver/Inc/Legacy \
-ISTM32_ExtMem_Manager \
-ISTM32_ExtMem_Manager/boot \
-ISTM32_ExtMem_Manager/sal \
-ISTM32_ExtMem_Manager/nor_sfdp \
-ISTM32_ExtMem_Manager/psram \
-ISTM32_ExtMem_Manager/sdcard \
-ISTM32_ExtMem_Manager/user \
-IDrivers/CMSIS/Include \
-INORFlash \
-IHyperRAM \
-IUser/extmem \
-IUser/it \
-IUser/ulog \
-IUser/main \
-IUser/usart \
-IUser \
# AS includes
AS_INCLUDES =
# 指定编译工具链的路径,使用CubeIDE带的编译器
ifeq ($(OS), Windows_NT)
GCC_PATH:=D:/SongshuaiWorkInstall/Stm32CubeIDE/STM32CubeIDE_1.19.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin
else
GCC_PATH:=/mnt/d/SongshuaiWorkInstall/Stm32CubeIDE/STM32CubeIDE_1.19.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344/tools/bin
endif
# binaries
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc.exe
CXX = $(GCC_PATH)/$(PREFIX)g++.exe
AS = $(GCC_PATH)/$(PREFIX)gcc.exe -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy.exe
SZ = $(GCC_PATH)/$(PREFIX)size.exe
else
CC = $(PREFIX)gcc
CXX = $(PREFIX)g++
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
ELF = $(PREFIX)gcc
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
# cpu With -mcpu=cortex-m55+nomve should be equivalent to -march=armv8.1-m.main+dsp
CPU=-mcpu=cortex-m55
# fpu
FPU =-mfpu=fpv5-d16
# float-abi
FLOAT-ABI =-mfloat-abi=hard
# mcu
MCU = $(CPU) $(FPU) $(FLOAT-ABI)
# macros for gcc
# AS defines
AS_DEFS =
C_STANDARD = -std=gnu11 #c++14
# C defines
C_DEFS = \
-DUSE_HAL_DRIVER \
-DSTM32N647xx \
# compile gcc flags
ASFLAGS += $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) $(C_STANDARD) -Wall -fdata-sections -ffunction-sections --specs=nano.specs
CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) $(C_STANDARD) -Wall -fdata-sections -ffunction-sections
# for warning: 'cmse_nonsecure_call' attribute ignored without '-mcmse' option
CFLAGS += -fstack-usage -fcyclomatic-complexity -mcmse --specs=nano.specs
# 配置为debug模式
ifeq ($(DEBUG_MODE), 1)
OPT = -O0
CFLAGS += -g3 -DDEBUG -DULOG_ENABLED
endif
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# 增加C++的支持
# CFLAGS += -Wl,--start-group -lstdc++ -Wl,--end-group
# libraries
LIBS = -Wl,--start-group -lc -lm -Wl,--end-group
# add .a library like this way! like "-L ./Libraries/ -lKinematic"
LIBDIR =
LDFLAGS = $(MCU) \
-T $(LDSCRIPT) $(LIBDIR) $(LIBS) \
-Wl,-Map=$(BUILD_DIR)/$(TARGET).map \
-Wl,--gc-sections \
--specs=nano.specs \
--specs=nosys.specs \
# -mthumb -u _printf_float \
# 配置FLASH的地址
FLASH_ADDR := 0x70000000
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin $(OUTPUT_DIR)/$(TARGET).hex
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp=.o)))
vpath %.cpp $(sort $(dir $(CPP_SOURCES)))
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
# list of ASMM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_SOURCES)))
$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(ELF) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(OUTPUT_DIR)/$(TARGET).hex: $(OUTPUT_DIR)/$(TARGET)-trusted.bin | $(OUTPUT_DIR)
$(HEX) -I binary $< --change-addresses $(FLASH_ADDR) $@
$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf | $(BUILD_DIR)
$(BIN) $< $@
$(OUTPUT_DIR)/$(TARGET)-trusted.bin: $(BUILD_DIR)/$(TARGET).bin | $(OUTPUT_DIR) clean
make sign
$(BUILD_DIR):
@mkdir $@
$(OUTPUT_DIR):
@mkdir $@
# SECTION 配置下载使用的工具路径
# 使用STM32CubeIDE自带的编译工具链,直接通过全路径指定,也可以使用自己安装的编译工具链,修改对应路径即可
ifeq ($(OS), Windows_NT)
PROTOOL_DIR:=D:/SongshuaiWorkInstall/Stm32CubeIDE/STM32CubeIDE_1.19.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.2.200.202503041107/tools/bin
else
PROTOOL_DIR:=/mnt/d/SongshuaiWorkInstall/Stm32CubeIDE/STM32CubeIDE_1.19.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.2.200.202503041107/tools/bin
endif
# 因为.exe的缘故,传入参数的路径得是win环境下的路径,所以使用固定的路径和文件,兼容WSL环境,Linux环境请自行修改
EXTMEM_LOADER=D:/SongshuaiWorkInstall/Stm32CubeIDE/STM32CubeIDE_1.19.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.2.200.202503041107/tools/bin/MX25UM25645G_ATK-CNN647B_ExtMemLoader.stldr
# !SECTION 配置下载使用的工具路径
# 输出的目标bin文件
.PHONY:sign
sign:
STM32_SigningTool_CLI.exe -bin $(BUILD_DIR)/$(TARGET).bin -nk -of 0x80000000 -t fsbl -o $(OUTPUT_DIR)/$(TARGET)-trusted.bin -hv 2.3 -dump $(OUTPUT_DIR)/$(TARGET)-trusted.bin
# 下载文件到flash中,使用STM32_Programmer_CLI.exe
.PHONY:download
download:
$(PROTOOL_DIR)/STM32_Programmer_CLI.exe -c port=SWD freq=4000 -w $(OUTPUT_DIR)/$(TARGET).hex -v -el $(EXTMEM_LOADER)
# 下载文件到flash中,使用STM32_Programmer_CLI.exe
.PHONY:download_bin
download_bin:
$(PROTOOL_DIR)/STM32_Programmer_CLI.exe -c port=SWD freq=4000 -w $(OUTPUT_DIR)/$(TARGET)-trusted.bin $(FLASH_ADDR) -v -el $(EXTMEM_LOADER)
# win环境下删除子目录中的文件 (需加 /S 参数),并且下面指令如果前面加@的话在不存在目标文件的情况下会报错出来导致编译中断
.PHONY:clean
clean:
ifeq ($(OS), Windows_NT)
del /S /F /Q $(OUTPUT_DIR)\*.bin $(OUTPUT_DIR)\*.hex
else
@rm -rf $(OUTPUT_DIR)/*.bin $(OUTPUT_DIR)/*.hex
endif
.PHONY:cleanall
cleanall:clean
ifeq ($(OS), Windows_NT)
@del /S /F /Q $(BUILD_DIR) $(OUTPUT_DIR) .clangd User/$(BUILD_DIR) User/.settings
else
@rm -rf $(BUILD_DIR) $(OUTPUT_DIR) .clangd User/$(BUILD_DIR) User/.settings
endif
.PHONY:debug
debug:
$(MAKE) DEBUG_ENABLE=1 all -j16
# dependencies
-include $(wildcard $(BUILD_DIR)/*.d)
提示:上述 Makefile 中的 Makefile 文件包含最基础的语法规则,相信大家都能轻松理解,此处不再赘述。
VSCode 工程配置:三件套详解
接下来,我们需要配置 VSCode 的工程文件,主要包括 c_cpp_properties.json、launch.json 和 tasks.json 三个文件。
4.1 c_cpp_properties.json
该文件用于配置 C/C++ 插件的智能提示和代码跳转功能,确保代码编辑时的流畅体验。
{
"configurations": [
{
"name": "STM32N6xx",
"includePath": [
"${default}",
"${workspaceFolder}/**",
"${workspaceFolder}/Drivers/STM32N6xx_HAL_Driver/Inc/**",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32N6xx/Include/**",
"${workspaceFolder}/Drivers/STM32N6xx_HAL_Driver/Inc/Legacy/**",
"${workspaceFolder}/STM32_ExtMem_Manager/**",
"${workspaceFolder}/STM32_ExtMem_Manager/boot/**",
"${workspaceFolder}/STM32_ExtMem_Manager/sal/**",
"${workspaceFolder}/STM32_ExtMem_Manager/nor_sfdp/**",
"${workspaceFolder}/STM32_ExtMem_Manager/psram/**",
"${workspaceFolder}/STM32_ExtMem_Manager/sdcard/**",
"${workspaceFolder}/STM32_ExtMem_Manager/user/**",
"${workspaceFolder}/Drivers/CMSIS/Include/**",
"${workspaceFolder}/NORFlash/**",
"${workspaceFolder}/HyperRAM/**",
"${workspaceFolder}/User/extmem/**",
"${workspaceFolder}/User/it/**",
"${workspaceFolder}/User/ulog/**",
"${workspaceFolder}/User/main/**",
"${workspaceFolder}/User/usart/**",
"${workspaceFolder}/User/**"
],
"defines": [
"USE_HAL_DRIVER",
"STM32N647xx",
"DEBUG",
"ULOG_ENABLED",
"uint8_t=unsigned char",
"uint16_t=unsigned int",
"uint32_t=unsigned long",
"int8_t=char",
"int16_t=int",
"int32_t=long",
"bool=unsigned char",
"static=",
"UNICODE",
"__GNUC__"
],
"intelliSenseMode": "${default}"
}
],
"version": 4
}
4.2 launch.json(核心配置)
这是整个调试流程中最关键的配置文件。由于 STM32N6 系列与普通 STM32 系列存在差异,因此需要针对性地进行配置。以下配置内容依赖于 STM32Cube Debug STLink GDB Server 插件,请确保已安装。
{
"configurations": [
{
"type": "stlinkgdbtarget",
"request": "launch",
"name": "Debug STM32N647 FSBL STLINK",
"cwd": "${workspaceFolder}",
"runEntry": "main",
"preLaunchTask": "build",
"imagesAndSymbols": [
{
"imageFileName": "${workspaceFolder}/build/STM32N647_FSBL.elf"
}
],
"verbose": false,
"deviceName": "STM32N647X0H3Q",
"deviceCore": "Cortex-M55",
"deviceTrustzone": "Secure-only",
"svdPath": "${workspaceFolder}/SVD/STM32N647.svd",
"serverApID": "1",
"serverReset": "Connect under reset",
"serverInterface": "SWD",
"serverInterfaceFrequency": "Auto",
"serverShared": false,
"serverHaltAllCores": false,
"serverHost": "localhost",
"serverPort": "61234",
"openGdbConsole": false,
"faultDivByZero": true,
"faultUnalignedAccess": false,
"faultHaltOnException": true
}
]
}
✅ 按照上述配置,即可正常启动调试,省去了在 CubeIDE 中手动配置的繁琐步骤。
4.3 tasks.json
该文件用于定义编译任务,与 Makefile 配合使用,实现一键编译。
{
"version": "2.0.0",
"tasks": [
{
// 编译任务
"label": "build",
"type": "shell",
"command": "make",
"args": [
"DEBUG_ENABLE=1",
"-j16"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
],
"detail": "Build the project using Makefile."
}
]
}
调试实战与问题排查
5.1 正常调试流程
完成上述配置后,打开调试面板,点击调试按钮即可开始调试。从输出信息
Start address 0x3418ef34, load size 65804
Transfer rate: 147 KB/sec, 5483 bytes/write.
set *(int *)0xE000ED14=*(int *)0xE000ED14|0x10
set *(int *)0xE000EDFC=*(int *)0xE000EDFC|0xff0
到
Temporary breakpoint 1, main () at User/main/main.c:42
42 SCB_EnableICache();
...
出现,大约需要 5~6 秒的等待时间,但相比 CubeIDE,这个速度已经非常令人满意了。调试效果如下图所示:

5.2 常见问题及解决方案
在调试过程中,可能会遇到以下问题,这里提供对应的解决方法:
- 弹出“无法识别类型”错误,如下图所示:

解决方法:
都说了要安装依赖的插件,安装之后再试试,要是还不行的重启Vscode再试试。
- 提示连接超时,如下图所示:

解决方法:
只要会一点英语知识会知道,说的是STLink初始化错误,没有发现单片机,只要打开开发板的电源、或者把STLink重新插拔一下、或者检查一下连接线是不是接对了等等,问题就解决了。
- 程序运行与实际代码不符,如下图所示:

解决方法:
没什么大不了的哈,这个是因为本次调试使用的 ***.elf 与调试的源代码没有关系,大概两个方面的原因:
1. launch.json配置内容中 “imageFileName” 指定的文件路径不是正确的文件路径
2. 本次调试的是因为源代码有错误导致编译失败,调试中使用的上次生成的 ***.elf 文件
版本更新引发的“血案”与最终解决方案
好景不长,在使用过程中,插件自动更新带来了新的麻烦。每次打开工程或异常断开后重新调试,都会出现长时间的等待,甚至弹出不确定的提示框,严重影响开发节奏。
经过排查,发现是插件自动升级到 V1.1.0 版本后导致的兼容性问题。将版本降回 V1.0.2 后问题暂时解决,但重启电脑后故障依旧。
最终,通过查找并定位插件实际调用的
ST-LINK_gdbserver.exe路径,发现其位于7.12.0+st.2目录下。删除该目录后,插件会回退到旧版本,问题得以彻底解决。⚠️ 建议:为了避免此类问题,建议在插件设置中关闭自动更新功能。如果问题依旧,可以尝试删除新版 GDB Server 目录,强制插件使用旧版本。
总结
本文详细介绍了在 VSCode 中调试 STM32N6 系列单片机的完整流程,包括插件安装、Makefile 编写、工程配置以及常见问题的解决方案。这套方案不仅简化了调试步骤,还摆脱了官方 IDE 的束缚,让开发者能够更加专注于代码本身。
虽然 STM32 的调试工具链仍有不少坑,但通过不断探索和实践,我们总能找到更高效的解决方案。希望本文能对大家有所帮助,也欢迎在评论区分享你的经验和问题。
[AFFILIATE_SLOT_1]如果你在开发过程中使用了其他编程语言(如 Java、JavaScript、C++、TypeScript 或 Python),这套 VSCode 调试思路同样适用,只需调整相应的编译和调试配置即可。
[AFFILIATE_SLOT_2]







浙公网安备 33010602011771号