作为一个长期在嵌入式领域摸爬滚打的开发者,我尝试过各种STM32开发方案。从早期的Keil MDK到后来的STM32CubeIDE,最终在Ubuntu系统上搭建了VSCode+OpenOCD+Cortex-Debug的组合。这套方案最大的优势在于全开源工具链和高度可定制性,特别适合需要频繁切换项目或进行深度调试的场景。
你可能会有疑问:为什么不用Windows平台的主流IDE?这里有几个关键考量:
实测下来,这套环境特别适合以下开发者:
首先确保你的Ubuntu版本在20.04及以上(推荐22.04 LTS),然后依次执行以下命令安装基础工具链:
bash复制sudo apt update
sudo apt install -y build-essential git cmake gcc-arm-none-eabi
接下来安装OpenOCD(建议用最新版):
bash复制sudo apt install -y openocd
验证安装是否成功:
bash复制arm-none-eabi-gcc --version
openocd -v
在VSCode扩展商店安装以下关键插件:
特别提醒:Cortex-Debug插件的配置直接影响调试体验,建议安装后立即在设置中开启:
Cortex-Debug: Enable Register PlottingCortex-Debug: Show Memory Access对于使用Makefile的传统项目,这里给出一个通用模板:
makefile复制TARGET = my_project
BUILD_DIR = build
C_SOURCES = \
src/main.c \
src/stm32f1xx_it.c
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
CFLAGS = -mcpu=cortex-m3 -mthumb \
-DUSE_HAL_DRIVER -DSTM32F103xE \
-O0 -g3 -Wall -fdata-sections -ffunction-sections
LDFLAGS = -mcpu=cortex-m3 -mthumb \
-specs=nano.specs -TSTM32F103C8Tx_FLASH.ld \
-Wl,--gc-sections -static
all: $(BUILD_DIR)/$(TARGET).elf
$(BUILD_DIR)/$(TARGET).elf: $(C_SOURCES)
@mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
$(CP) -O ihex $@ $(BUILD_DIR)/$(TARGET).hex
对于新项目推荐使用CMake,这里给出关键配置片段:
cmake复制cmake_minimum_required(VERSION 3.12)
project(my_stm32_project LANGUAGES C CXX ASM)
set(CMAKE_EXECUTABLE_SUFFIX ".elf")
set(CMAKE_C_STANDARD 11)
find_package(ARM_NONE_EABI_TOOLCHAIN REQUIRED)
add_executable(${PROJECT_NAME}
src/main.c
src/system_stm32f1xx.c
)
target_compile_options(${PROJECT_NAME} PRIVATE
-mcpu=cortex-m3
-mthumb
-Og
-g3
)
target_link_options(${PROJECT_NAME} PRIVATE
-T${CMAKE_SOURCE_DIR}/STM32F103C8Tx_FLASH.ld
-specs=nosys.specs
)
创建openocd.cfg配置文件:
tcl复制source [find interface/jlink.cfg]
transport select swd
source [find target/stm32f1x.cfg]
reset_config srst_only
启动命令建议封装成shell脚本:
bash复制#!/bin/bash
openocd -f openocd.cfg -c "init" -c "reset halt"
这是调试配置的核心文件,关键参数解析:
json复制{
"version": "0.2.0",
"configurations": [
{
"name": "STM32 Debug",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/my_project.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"device": "STM32F103RC",
"configFiles": [
"openocd.cfg"
],
"svdFile": "${env:HOME}/STM32F103xx.svd",
"showDevDebugOutput": true,
"panel": "dedicated"
}
]
}
重点参数说明:
svdFile:提供外设寄存器描述,可从ST官网下载panel: "dedicated"会为每个调试会话创建独立面板showDevDebugOutput: 显示底层OpenOCD通信日志-exec x/16xw 0x20000000查看内存json复制{
"version": "2.0.0",
"tasks": [
{
"label": "Build Project",
"type": "shell",
"command": "make -j4",
"group": "build",
"problemMatcher": ["$gcc"],
"detail": "Building STM32 project with Makefile"
},
{
"label": "Flash Device",
"type": "shell",
"command": "openocd -f openocd.cfg -c \"program build/my_project.elf verify reset exit\"",
"dependsOn": "Build Project",
"problemMatcher": []
},
{
"label": "Build & Flash",
"dependsOrder": "sequence",
"dependsOn": ["Build Project", "Flash Device"],
"group": "build",
"problemMatcher": []
}
]
}
问题1:OpenOCD连接失败
dmesg | grep jlink确认设备识别adapter speed 1000问题2:程序无法停在main函数
json复制"runToMain": true,
"postRestartCommands": ["monitor reset halt"]
问题3:变量查看显示
-fno-omit-frame-pointer编译参数对于长期维护的项目,建议采用以下结构:
code复制project_root/
├── .vscode/
│ ├── launch.json
│ ├── tasks.json
│ └── settings.json
├── cmake/
│ └── toolchain.cmake
├── drivers/
├── src/
│ ├── main.c
│ └── ...
├── build/
└── openocd.cfg
关键点:
include()机制复用配置我在实际项目中验证,这套环境可以完美支持: