常用命令:
# 先连接OpenOCD到硬件调试器,打开powershell命令行窗口, 会输出连接端口信息# openocd -f <接口配置文件> -f <目标芯片配置文件>openocd -f D:/program/xpack-openocd/openocd/scripts/interface/stlink-v2.cfg -fD:/program/xpack-openocd/openocd/scripts/target/stm32f1x.cfg
# 三种端口连接协议方式:tcl 、 telnet 、gdbtelnet localhost 4444
# 目标芯片挂起,相当于关机halt
# 将文件下载到目标芯片flashflash write_image erase <xx.elf>
# 目标芯片复位reset
# 命令用于查询目标设备的当前状态,返回目标的xPSR: 0x81000000 pc: 0x080025be msp:0x200029a0poll
# 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 recommendedopenocd -f xxx/stlink.cfg -f xxx/stm32f1x.cfg -c init -c "reset halt; wait_halt; flash write_image erase xxx.elf 0x08000000" -c reset
openocd -f interface/ftdi/jtagkey.cfg -f myboard_EK390.cfg -c "init; targets;reset halt; wait_halt; poll; flash write_image erase unlock xxx.elf; flasherase_check 0; reset run; shutdown"
# ---> Error: init mode failed (unable to connect to the target)# 检查st-info --probe
> Failed to enter SWD mode# 解决 + press resetst-info --probe --connect-under-reset# 擦除固件st-flash --connect-under-reset eraseAI回答:
STM32 OpenOCD 烧录配置指南
跳转到“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. 修改路径配置
跳转到“1. 修改路径配置”根据您的实际安装路径,修改以下文件中的路径:
scripts/flash.bat
跳转到“scripts/flash.bat”set OPENOCD_PATH=D:\program\xpack-openocd\openocd\bin\openocd.exe.vscode/tasks.json 和 .vscode/launch.json
跳转到“.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 配置
跳转到“2. 验证 OpenOCD 配置”运行以下命令测试 OpenOCD 连接:
openocd -f openocd.cfg如果连接成功,您应该看到类似输出:
Open On-Chip Debugger 0.12.0Info : The selected transport took over low-level target control.Info : clock speed 1000 kHzInfo : STLINK V2J17S4 (API v2) VID:PID 0483:3748Info : Target voltage: 3.240000Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detectedInfo : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpointsInfo : starting gdb server for stm32f1x.cpu on 3333🚀 使用方法
跳转到“🚀 使用方法”方法一:使用 Cursor 任务 (推荐)
跳转到“方法一:使用 Cursor 任务 (推荐)”- 打开命令面板:
Ctrl+Shift+P - 运行任务: 输入
Tasks: Run Task - 选择任务:
构建并烧录: 自动构建项目并烧录到 STM32烧录程序 (OpenOCD): 仅烧录已构建的程序构建项目 (Debug): 仅构建项目
方法二:使用 Python 脚本
跳转到“方法二:使用 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)
跳转到“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 erase2. timeout waiting for algorithm
跳转到“2. timeout waiting for algorithm”原因: 目标设备状态异常
解决方案:
- 按住复位按钮,重新执行烧录
- 在 OpenOCD 命令中添加
wait_halt - 检查目标板供电是否正常
3. 找不到 OpenOCD 可执行文件
跳转到“3. 找不到 OpenOCD 可执行文件”解决方案:
- 检查 OpenOCD 安装路径
- 修改脚本中的
OPENOCD_PATH变量 - 将 OpenOCD 添加到系统 PATH
4. 找不到 .elf 文件
跳转到“4. 找不到 .elf 文件”解决方案:
- 确保项目已成功构建:
cmake --build build/Debug - 检查构建输出目录是否正确
- 验证 CMakeLists.txt 配置
📚 常用命令参考
跳转到“📚 常用命令参考”OpenOCD 连接命令
跳转到“OpenOCD 连接命令”# 启动 OpenOCD 服务器openocd -f openocd.cfg
# 通过 telnet 连接控制台telnet localhost 4444OpenOCD 控制台命令
跳转到“OpenOCD 控制台命令”halt # 暂停目标reset halt # 复位并暂停reset run # 复位并运行flash list # 列出 flash 设备flash info 0 # 显示 flash 信息flash erase_sector 0 0 last # 擦除所有扇区poll # 查询目标状态GDB 调试命令
跳转到“GDB 调试命令”# 连接到 OpenOCDtarget extended-remote localhost:3333
# 加载程序load
# 设置断点break mainbreak *0x08000000
# 运行控制continue # 继续执行step # 单步执行next # 执行下一行finish # 执行到函数返回
# 查看信息info registers # 查看寄存器print variable_name # 打印变量值x/10x 0x20000000 # 查看内存内容⚡ 高级配置
跳转到“⚡ 高级配置”自定义 OpenOCD 配置
跳转到“自定义 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 系列无需特殊配置,使用默认即可}@echo offREM STM32 程序烧录批处理脚本REM 使用 OpenOCD 烧录程序到 STM32F103RE
setlocal EnableDelayedExpansion
echo ========================================echo STM32F103RE 程序烧录工具echo ========================================
REM 设置 OpenOCD 路径(根据您的安装路径调整)set OPENOCD_PATH=D:\program\xpack-openocd\openocd\bin\openocd.exeset OPENOCD_SCRIPTS=D:\program\xpack-openocd\openocd\scripts
REM 检查 OpenOCD 是否存在if not exist "%OPENOCD_PATH%" ( echo 错误: 找不到 OpenOCD 在路径: %OPENOCD_PATH% echo 请检查并修改脚本中的 OPENOCD_PATH 变量 pause exit /b 1)
REM 查找 ELF 文件set ELF_FILE=for %%f in (build\Debug\*.elf) do ( set ELF_FILE=%%f goto :found_elf)
:found_elfif "%ELF_FILE%"=="" ( echo 错误: 在 build\Debug 目录中找不到 .elf 文件 echo 请先构建项目 pause exit /b 1)
echo 找到 ELF 文件: %ELF_FILE%
REM 检查配置文件if not exist "openocd.cfg" ( echo 错误: 找不到 openocd.cfg 配置文件 echo 请确保配置文件存在于项目根目录 pause exit /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 osimport sysimport subprocessimport argparsefrom pathlib import Path
def 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 path
print("错误: 找不到 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 False
except Exception as e: print(f"❌ 执行失败: {e}") return False
return True
def 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()
# 查找 OpenOCD openocd_path = find_openocd() print(f"使用 OpenOCD: {openocd_path}")
# 查找 ELF 文件 if args.elf: elf_file = args.elf if 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 = tigerControlBUILD_DIR = build/DebugOPENOCD_CFG = openocd.cfg
# 默认目标.PHONY: all build flash clean debug help
# 默认构建 Debug 版本all: build
help: @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)
# 擦除 Flasherase: @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来源:CSDN 原文,首次发布于 2025-07-02。