vscode、openocd 使用
常用命令:
# 先连接OpenOCD到硬件调试器,打开powershell命令行窗口, 会输出连接端口信息
# openocd -f <接口配置文件> -f <目标芯片配置文件>
openocd -f D:/program/xpack-openocd/openocd/scripts/interface/stlink-v2.cfg -f
D:/program/xpack-openocd/openocd/scripts/target/stm32f1x.cfg# 三种端口连接协议方式:tcl 、 telnet 、gdb
telnet localhost 4444# 目标芯片挂起,相当于关机
halt # 将文件下载到目标芯片flash
flash write_image erase <xx.elf> # 目标芯片复位
reset # 命令用于查询目标设备的当前状态,返回目标的xPSR: 0x81000000 pc: 0x080025be msp:0x200029a0
poll # one key for all
# -c表示要执行的选项,-c init 用于初始化
# -c "reset halt; wait_halt; flash write_image erase build/项目15.bin 0x08000000" 表示执行命令,其中 reset halt; wait_hal 先停止单片机 (分号不能少)
# -c reset -c shutdown,表示复位单片机,且退出OpenOCD
# reset halt; wait_hal ,这句必不可少,否则第一次下载能成功,但是第二次下载就会报错:timeout waiting for algorithm, a target reset is recommended
openocd -f xxx/stlink.cfg -f xxx/stm32f1x.cfg -c init -c "reset halt; wait_halt; flash write_image erase xxx.elf 0x08000000" -c resetopenocd -f interface/ftdi/jtagkey.cfg -f myboard_EK390.cfg -c "init; targets;
reset halt; wait_halt; poll; flash write_image erase unlock xxx.elf; flash
erase_check 0; reset run; shutdown"# ---
> Error: init mode failed (unable to connect to the target)
# 检查
st-info --probe> Failed to enter SWD mode
# 解决 + press reset
st-info --probe --connect-under-reset
# 擦除固件
st-flash --connect-under-reset erase
参考
AI回答:
STM32 OpenOCD 烧录配置指南
本文档详细说明如何在 Cursor 编辑器中配置 OpenOCD 来烧录 STM32F103RE 程序。
📋 目录
- 环境要求
- 文件结构
- 配置步骤
- 使用方法
- 故障排除
- 常用命令
🛠️ 环境要求
必需软件
- OpenOCD: 用于调试和烧录
- ARM GCC 工具链: 用于编译 STM32 程序
- Python 3.x: 用于运行烧录脚本
- CMake: 用于构建系统
- ST-Link 驱动: 用于硬件连接
硬件要求
- STM32F103RE 开发板或芯片
- ST-Link v2 或兼容的调试器
- USB 连接线
📁 文件结构
tigerControl/
├── openocd.cfg # OpenOCD 主配置文件
├── scripts/
│ ├── flash.py # Python 烧录脚本
│ └── flash.bat # Windows 批处理脚本
├── .vscode/
│ ├── tasks.json # Cursor/VSCode 任务配置
│ └── launch.json # 调试配置
└── build/Debug/└── tigerControl.elf # 编译生成的可执行文件
⚙️ 配置步骤
1. 修改路径配置
根据您的实际安装路径,修改以下文件中的路径:
scripts/flash.bat
set OPENOCD_PATH=D:\program\xpack-openocd\openocd\bin\openocd.exe
.vscode/tasks.json
和 .vscode/launch.json
"openOCDPath": "D:/program/xpack-openocd/openocd/bin/openocd.exe",
"armToolchainPath": "D:/program/gcc-arm-none-eabi/bin"
2. 验证 OpenOCD 配置
运行以下命令测试 OpenOCD 连接:
openocd -f openocd.cfg
如果连接成功,您应该看到类似输出:
Open On-Chip Debugger 0.12.0
Info : The selected transport took over low-level target control.
Info : clock speed 1000 kHz
Info : STLINK V2J17S4 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.240000
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 3333
🚀 使用方法
方法一:使用 Cursor 任务 (推荐)
- 打开命令面板:
Ctrl+Shift+P
- 运行任务: 输入
Tasks: Run Task
- 选择任务:
构建并烧录
: 自动构建项目并烧录到 STM32烧录程序 (OpenOCD)
: 仅烧录已构建的程序构建项目 (Debug)
: 仅构建项目
方法二:使用 Python 脚本
# 基本烧录
python scripts/flash.py# 指定构建目录
python scripts/flash.py --build-dir build/Release# 指定 ELF 文件
python scripts/flash.py --elf build/Debug/tigerControl.elf# 跳过验证
python scripts/flash.py --no-verify
方法三:使用批处理脚本
双击运行 scripts/flash.bat
或在终端中执行:
scripts\flash.bat
方法四:手动命令行
# 一键烧录命令
openocd -f openocd.cfg -c "init" -c "reset halt" -c "wait_halt" -c "flash write_image erase build/Debug/tigerControl.elf 0x08000000" -c "verify_image build/Debug/tigerControl.elf 0x08000000" -c "reset run" -c "shutdown"
🔧 调试功能
启动调试会话
- 构建项目: 确保项目已构建
- 设置断点: 在源代码中设置断点
- 启动调试: 按
F5
或选择调试配置 - 选择配置:
调试 STM32 (OpenOCD)
: 推荐,需要 Cortex-Debug 扩展调试 STM32 (手动 OpenOCD)
: 手动管理 OpenOCD 连接
调试功能
- 设置断点和观察点
- 单步执行 (F10) 和跳入函数 (F11)
- 查看变量和寄存器状态
- 内存查看器
- 调用堆栈跟踪
❌ 故障排除
常见错误及解决方案
1. Error: init mode failed (unable to connect to the target)
原因: 无法连接到目标设备
解决方案:
# 检查设备连接
st-info --probe# 如果连接失败,尝试复位连接
st-info --probe --connect-under-reset# 擦除固件(如果固件损坏)
st-flash --connect-under-reset erase
2. timeout waiting for algorithm
原因: 目标设备状态异常
解决方案:
- 按住复位按钮,重新执行烧录
- 在 OpenOCD 命令中添加
wait_halt
- 检查目标板供电是否正常
3. 找不到 OpenOCD 可执行文件
解决方案:
- 检查 OpenOCD 安装路径
- 修改脚本中的
OPENOCD_PATH
变量 - 将 OpenOCD 添加到系统 PATH
4. 找不到 .elf 文件
解决方案:
- 确保项目已成功构建:
cmake --build build/Debug
- 检查构建输出目录是否正确
- 验证 CMakeLists.txt 配置
📚 常用命令参考
OpenOCD 连接命令
# 启动 OpenOCD 服务器
openocd -f openocd.cfg# 通过 telnet 连接控制台
telnet localhost 4444
OpenOCD 控制台命令
halt # 暂停目标
reset halt # 复位并暂停
reset run # 复位并运行
flash list # 列出 flash 设备
flash info 0 # 显示 flash 信息
flash erase_sector 0 0 last # 擦除所有扇区
poll # 查询目标状态
GDB 调试命令
# 连接到 OpenOCD
target extended-remote localhost:3333# 加载程序
load# 设置断点
break main
break *0x08000000# 运行控制
continue # 继续执行
step # 单步执行
next # 执行下一行
finish # 执行到函数返回# 查看信息
info registers # 查看寄存器
print variable_name # 打印变量值
x/10x 0x20000000 # 查看内存内容
⚡ 高级配置
自定义 OpenOCD 配置
如果需要特殊配置,可以修改 openocd.cfg
:
# 修改适配器速度
adapter speed 2000# 添加自定义初始化脚本
$_TARGETNAME configure -event reset-init {# 自定义初始化代码mww 0x40021004 0x12345678 # 设置时钟配置
}# 启用 SWO 跟踪
tpiu config internal swodump.log uart off 72000000
批量操作脚本
创建 scripts/batch_flash.py
用于批量烧录:
# 批量烧录多个目标
targets = ["board1", "board2", "board3"]
for target in targets:flash_firmware(f"build/{target}.elf")
📞 技术支持
如果遇到问题,请检查:
- 硬件连接: ST-Link 连接是否正常
- 驱动程序: ST-Link 驱动是否已安装
- 软件版本: OpenOCD 和工具链版本兼容性
- 权限问题: 确保有足够的系统权限
- 防火墙设置: 确保防火墙不阻止调试端口
📝 更新日志
- v1.0.0: 初始版本,支持基本烧录和调试功能
- v1.1.0: 添加批处理脚本和 Python 脚本支持
- v1.2.0: 完善调试配置和错误处理
#openocd.cfg
# OpenOCD 配置文件 - STM32F103RE
# 接口配置 - ST-Link v2,在程序所在文件中查找,路径可指定
source [find interface/stlink-v2.cfg]# 目标芯片配置 - STM32F1x 系列
source [find target/stm32f1x.cfg]# 适配器速度设置 (可选,默认即可)
adapter speed 1000# 复位配置
reset_config srst_only srst_nogate# 初始化后的配置
init# 目标芯片特定配置
$_TARGETNAME configure -event reset-init {# STM32F1 系列无需特殊配置,使用默认即可
}
# flash.bat
@echo off
REM STM32 程序烧录批处理脚本
REM 使用 OpenOCD 烧录程序到 STM32F103REsetlocal EnableDelayedExpansionecho ========================================
echo STM32F103RE 程序烧录工具
echo ========================================REM 设置 OpenOCD 路径(根据您的安装路径调整)
set OPENOCD_PATH=D:\program\xpack-openocd\openocd\bin\openocd.exe
set OPENOCD_SCRIPTS=D:\program\xpack-openocd\openocd\scriptsREM 检查 OpenOCD 是否存在
if not exist "%OPENOCD_PATH%" (echo 错误: 找不到 OpenOCD 在路径: %OPENOCD_PATH%echo 请检查并修改脚本中的 OPENOCD_PATH 变量pauseexit /b 1
)REM 查找 ELF 文件
set ELF_FILE=
for %%f in (build\Debug\*.elf) do (set ELF_FILE=%%fgoto :found_elf
):found_elf
if "%ELF_FILE%"=="" (echo 错误: 在 build\Debug 目录中找不到 .elf 文件echo 请先构建项目pauseexit /b 1
)echo 找到 ELF 文件: %ELF_FILE%REM 检查配置文件
if not exist "openocd.cfg" (echo 错误: 找不到 openocd.cfg 配置文件echo 请确保配置文件存在于项目根目录pauseexit /b 1
)echo 开始烧录程序...
echo.REM 执行烧录命令
"%OPENOCD_PATH%" ^-f openocd.cfg ^-c "init" ^-c "reset halt" ^-c "wait_halt" ^-c "flash write_image erase %ELF_FILE% 0x08000000" ^-c "verify_image %ELF_FILE% 0x08000000" ^-c "reset run" ^-c "shutdown"if %ERRORLEVEL% EQU 0 (echo.echo ========================================echo ✅ 烧录成功!echo ========================================
) else (echo.echo ========================================echo ❌ 烧录失败! 错误代码: %ERRORLEVEL%echo ========================================echo 常见问题解决方案:echo 1. 检查 ST-Link 连接是否正常echo 2. 确保目标板供电正常echo 3. 尝试按住复位按钮重新烧录echo 4. 检查 OpenOCD 配置文件
)echo.
pause
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"""
STM32 程序烧录脚本
使用 OpenOCD 自动烧录程序到 STM32F103RE
"""import os
import sys
import subprocess
import argparse
from pathlib import Pathdef find_openocd():"""查找 OpenOCD 可执行文件"""# 常见的 OpenOCD 安装路径possible_paths = ["D:/program/xpack-openocd/openocd/bin/openocd.exe","D:/program/OpenOCD/bin/openocd.exe","C:/Program Files/OpenOCD/bin/openocd.exe","openocd.exe", # 系统 PATH 中"openocd" # Linux/Mac]for path in possible_paths:if os.path.exists(path) or subprocess.run(["where", path], capture_output=True).returncode == 0:return pathprint("错误: 找不到 OpenOCD 可执行文件")print("请确保 OpenOCD 已正确安装并在 PATH 中")sys.exit(1)def find_elf_file(build_dir="build/Debug"):"""查找 ELF 文件"""build_path = Path(build_dir)elf_files = list(build_path.glob("*.elf"))if not elf_files:print(f"错误: 在 {build_dir} 目录中找不到 .elf 文件")print("请先构建项目")sys.exit(1)if len(elf_files) > 1:print(f"找到多个 .elf 文件: {[f.name for f in elf_files]}")print(f"使用第一个: {elf_files[0].name}")return str(elf_files[0])def flash_firmware(elf_file, openocd_path, config_file="openocd.cfg", verify=True):"""烧录固件到 STM32"""print(f"开始烧录固件: {elf_file}")# 构建 OpenOCD 命令cmd = [openocd_path,"-f", config_file,"-c", "init","-c", "reset halt","-c", "wait_halt","-c", f"flash write_image erase {elf_file} 0x08000000",]if verify:cmd.extend(["-c", f"verify_image {elf_file} 0x08000000"])cmd.extend(["-c", "reset run","-c", "shutdown"])try:print("执行命令:")print(" ".join(cmd))print("-" * 50)result = subprocess.run(cmd, capture_output=False, text=True)if result.returncode == 0:print("-" * 50)print("✅ 烧录成功!")else:print("-" * 50)print("❌ 烧录失败!")return Falseexcept Exception as e:print(f"❌ 执行失败: {e}")return Falsereturn Truedef main():parser = argparse.ArgumentParser(description="STM32 程序烧录工具")parser.add_argument("--elf", help="指定 ELF 文件路径")parser.add_argument("--build-dir", default="build/Debug", help="构建目录 (默认: build/Debug)")parser.add_argument("--config", default="openocd.cfg", help="OpenOCD 配置文件 (默认: openocd.cfg)")parser.add_argument("--no-verify", action="store_true", help="跳过验证步骤")args = parser.parse_args()# 查找 OpenOCDopenocd_path = find_openocd()print(f"使用 OpenOCD: {openocd_path}")# 查找 ELF 文件if args.elf:elf_file = args.elfif not os.path.exists(elf_file):print(f"错误: 找不到指定的 ELF 文件: {elf_file}")sys.exit(1)else:elf_file = find_elf_file(args.build_dir)print(f"使用 ELF 文件: {elf_file}")print(f"使用配置文件: {args.config}")# 检查配置文件if not os.path.exists(args.config):print(f"错误: 找不到配置文件: {args.config}")sys.exit(1)# 执行烧录success = flash_firmware(elf_file, openocd_path, args.config, not args.no_verify)if success:print("程序烧录完成!")sys.exit(0)else:print("程序烧录失败!")sys.exit(1)if __name__ == "__main__":main()
# Makefile
# STM32F103RE 项目 Makefile
# 提供快速构建和烧录命令# 项目配置
PROJECT_NAME = tigerControl
BUILD_DIR = build/Debug
OPENOCD_CFG = openocd.cfg# 默认目标
.PHONY: all build flash clean debug help# 默认构建 Debug 版本
all: buildhelp:@echo "可用的 Make 目标:"@echo " all - 构建项目 (默认)"@echo " build - 构建 Debug 版本"@echo " flash - 烧录程序到 STM32"@echo " clean - 清理构建文件"@echo " rebuild - 重新构建项目"@echo " debug - 启动 OpenOCD 调试服务器"@echo " erase - 擦除 Flash 存储器"@echo " info - 显示项目信息"# 配置和构建项目
build:@echo "正在配置 CMake..."cmake --preset Debug@echo "正在构建项目..."cmake --build $(BUILD_DIR)# 烧录程序
flash: build@echo "正在烧录程序到 STM32..."python scripts/flash.py# 使用批处理脚本烧录
flash-bat: build@echo "使用批处理脚本烧录程序..."scripts/flash.bat# 清理构建文件
clean:@echo "正在清理构建文件..."cmake --build $(BUILD_DIR) --target clean# 重新构建
rebuild: clean build# 启动 OpenOCD 调试服务器
debug:@echo "启动 OpenOCD 调试服务器..."@echo "使用 telnet localhost 4444 连接控制台"@echo "使用 Ctrl+C 停止服务器"openocd -f $(OPENOCD_CFG)# 擦除 Flash
erase:@echo "正在擦除 Flash 存储器..."openocd -f $(OPENOCD_CFG) -c "init" -c "reset halt" -c "wait_halt" -c "flash erase_sector 0 0 last" -c "shutdown"# 显示项目信息
info:@echo "项目信息:"@echo " 项目名称: $(PROJECT_NAME)"@echo " 构建目录: $(BUILD_DIR)"@echo " 配置文件: $(OPENOCD_CFG)"@echo " 目标芯片: STM32F103RE"@echo " Flash 起始地址: 0x08000000"@echo ""@echo "ELF 文件信息:"@if [ -f "$(BUILD_DIR)/$(PROJECT_NAME).elf" ]; then \arm-none-eabi-size $(BUILD_DIR)/$(PROJECT_NAME).elf; \else \echo " 未找到 ELF 文件,请先构建项目"; \fi# 检查 OpenOCD 连接
check:@echo "检查 OpenOCD 连接..."openocd -f $(OPENOCD_CFG) -c "init" -c "targets" -c "shutdown"# 生成编译数据库 (用于代码编辑器)
compile-db: build@echo "生成编译数据库..."@if [ -f "$(BUILD_DIR)/compile_commands.json" ]; then \cp $(BUILD_DIR)/compile_commands.json .; \echo "编译数据库已更新"; \else \echo "未找到编译数据库文件"; \fi