PyOCD使用指南
PyOCD 完整使用手册
目录
概述
项目中需使用PyOCD,故作此篇,参考官方帮助文档。
pip安装不会写入系统环境变量,故下方演示命令以python -m开头。
PyOCD 是一个基于 Python 的开源调试工具,专为 ARM Cortex 微控制器设计。它提供了完整的调试和烧录功能,支持多种调试器和目标设备。
主要特性
-
跨平台支持:Windows、Linux、macOS
-
多调试器支持:CMSIS-DAP、J-Link、ST-Link等
-
丰富功能:烧录、调试、RTT、GDB服务器
-
灵活配置:支持配置文件和命令行参数
-
开源免费:完全开源,商业友好的许可证
支持的调试器
-
CMSIS-DAP(DAPLink、J-Link OB等)
-
SEGGER J-Link
-
ST-LINK
-
Picoprobe
-
其他兼容的SWD/JTAG调试器
支持的目标设备
-
ARM Cortex-M系列(M0/M0+/M3/M4/M7/M23/M33)
-
ARM Cortex-A系列(部分)
-
支持数千种不同的微控制器型号
命令架构
PyOCD 采用模块化设计,包含以下主要子命令:
pyocd
├── commander (cmd) # 交互式命令控制台
├── erase # Flash擦除操作
├── load (flash) # 固件烧录操作
├── gdbserver (gdb) # GDB远程服务器
├── json # JSON格式信息输出
├── list # 列出设备信息
├── pack # CMSIS-Pack管理
├── reset # 目标复位
├── server # 调试探针服务器
└── rtt # SEGGER RTT查看器/记录器
全局选项
所有pyocd命令都支持以下全局选项:
-h, --help # 显示帮助信息
-V, --version # 显示版本信息
--help-options # 显示所有可用会话选项
安装与快速入门
安装要求
-
Python 3.7 或更高版本
-
USB调试器驱动(根据使用的调试器)
安装方法
使用pip安装(推荐)
pip install pyocd -i https://pypi.tuna.tsinghua.edu.cn/simple
从源码安装
git clone https://github.com/pyocd/pyOCD.git
cd pyOCD
pip install -e .
安装验证
# 检查安装
python -m pyocd --version
# 列出可用的调试器
python -m pyocd list
快速入门示例
- 查看可用设备
python -m pyocd list
- 烧录固件
python -m pyocd load firmware.bin -t target_name
# target_name就是你的芯片型号,例如STM32G431CBU6
- 启动调试器
python -m pyocd gdbserver -t target_name
基本命令结构
通用语法
python -m pyocd [全局选项] <子命令> [子命令选项] [参数]
常用全局选项
-v, --verbose # 增加详细输出级别
-q, --quiet # 减少输出级别
-L, --log-level LOGGERS=LEVEL # 设置日志级别
--color [{always,auto,never}] # 控制彩色日志输出
连接选项(多数命令支持)
-u, --uid UNIQUE_ID # 指定调试器ID
-t, --target TARGET # 指定目标芯片型号
-f, --frequency FREQUENCY # 设置SWD/JTAG时钟频率
-W, --no-wait # 不等待调试器连接
-M, --connect MODE # 连接模式(halt/pre-reset/under-reset/attach)
配置选项
-j, --project PATH # 设置项目目录
--config PATH # 指定配置文件路径
--no-config # 不使用配置文件
-O OPTION=VALUE # 设置命名选项
--script PATH # 使用用户脚本
设备连接与配置
1. 列出可用设备
列出调试器
python -m pyocd list
列出支持的目标设备
python -m pyocd list --targets
列出已知开发板
python -m pyocd list --boards
2. 目标芯片选择
使用 -t 参数指定目标芯片:
python -m pyocd -t gd32f103cb load firmware.bin
常用目标芯片型号:
-
stm32f103c8- STM32F103C8T6 -
stm32f407vg- STM32F407VGT6 -
gd32f103cb- GD32F103CBT6 -
nrf51822- Nordic nRF51822 -
lpc1768- NXP LPC1768
3. 调试器选择
当有多个调试器时,使用 -u 参数指定:
python -m pyocd -u 0672FF48 -t stm32f103c8 load firmware.bin
调试器ID可以通过 pyocd list 命令查看。
4. 连接模式
使用 -M 参数选择连接模式:
python -m pyocd -M halt load firmware.bin # 连接时暂停核心
python -m pyocd -M pre-reset load firmware.bin # 复位前连接
python -m pyocd -M under-reset load firmware.bin # 在复位状态下连接
python -m pyocd -M attach load firmware.bin # 附加到运行中的设备
5. 频率设置
使用 -f 参数设置调试时钟频率:
python -m pyocd -f 1mhz load firmware.bin # 1MHz
python -m pyocd -f 2000khz load firmware.bin # 2MHz
python -m pyocd -f 4000000 load firmware.bin # 4MHz
频率单位支持:
-
无单位:Hz(如
4000000) -
khz:千赫(如2000khz) -
mhz:兆赫(如1mhz)
6. 配置文件
创建 pyocd.yaml 配置文件:
# pyocd.yaml 示例
target: stm32f103c8
board: stm32f103c8_tst
frequency: 2000000
connect_mode: halt
# Flash配置
flash:
chip_erase: sector
# GDB服务器配置
gdbserver:
gdb_port: 3333
telnet_port: 4444
# RTT配置
rtt:
enabled: true
address: 0x20000000
size: 0x1000
使用配置文件:
python -m pyocd load firmware.bin # 自动使用pyocd.yaml
python -m pyocd --config my_config.yaml load firmware.bin
7. 用户脚本
创建 pyocd_user.py 自定义脚本:
# pyocd_user.py 示例
def pyocd_user_script(session):
"""用户自定义脚本"""
target = session.target
print(f"目标设备: {target.target_type}")
# 自定义初始化
if target.target_type.startswith("stm32"):
# STM32特定初始化
pass
# 设置断点
target.set_breakpoint(0x08000100)
固件烧录操作
1. 基本烧录命令
load命令基础用法
# 基本烧录
python -m pyocd load firmware.bin -t target_name
# 指定地址烧录
python -m pyocd load firmware.bin -a 0x08000000 -t target_name
# 烧录多个文件
python -m pyocd load bootloader.bin app.bin -t target_name
支持的文件格式
-
BIN:原始二进制文件(默认)
-
HEX:Intel HEX格式
-
ELF:可执行链接格式
# 指定文件格式
python -m pyocd load firmware.hex --format hex -t target_name
python -m pyocd load firmware.elf --format elf -t target_name
2. 烧录选项详解
擦除选项
# 扇区擦除(默认)
python -m pyocd load firmware.bin -e sector -t target_name
# 自动选择擦除方式
python -m pyocd load firmware.bin -e auto -t target_name
# 整片擦除
python -m pyocd load firmware.bin -e chip -t target_name
验证选项
# 烧录后验证
python -m pyocd load firmware.bin --verify -t target_name
# 仅CRC验证(更快速)
python -m pyocd load firmware.bin --trust-crc -t target_name
复位控制
# 烧录后不复位
python -m pyocd load firmware.bin --no-reset -t target_name
# 烧录后复位(默认行为)
python -m pyocd load firmware.bin -t target_name
高级选项
# 跳过前N字节不烧录
python -m pyocd load firmware.bin --skip 1024 -t target_name
# 设置基地址(仅单个文件)
python -m pyocd load firmware.bin --base-address 0x08000000 -t target_name
# 快速编程模式
python -m pyocd load firmware.bin -O fast_program=true -t target_name
3. 实用烧录示例
IAP固件烧录
# 烧录引导程序(24KB)
python -m pyocd load bootloader.bin -a 0x08000000 -t gd32f103cb
# 烧录应用程序
python -m pyocd load app.bin -a 0x08006000 -t gd32f103cb
# 烧录合并固件
python -m pyocd load combined.bin -a 0x08000000 -t gd32f103cb --verify
批量烧录脚本
#!/bin/bash
# 批量烧录脚本示例
TARGET="stm32f103c8"
FIRMWARE_DIR="./firmware"
# 烧录引导程序
echo "烧录引导程序..."
python -m pyocd load "$FIRMWARE_DIR/bootloader.bin" -a 0x08000000 -t $TARGET
# 烧录应用程序
echo "烧录应用程序..."
python -m pyocd load "$FIRMWARE_DIR/app.bin" -a 0x08004000 -t $TARGET --verify
# 验证烧录结果
echo "验证烧录结果..."
python -m pyocd commander -t $TARGET -c "cmp 0x08000000 $(stat -c%s "$FIRMWARE_DIR/bootloader.bin") $FIRMWARE_DIR/bootloader.bin" -c "exit"
echo "烧录完成!"
4. 擦除操作
erase命令详解
# 擦除整个芯片
python -m pyocd erase -t target_name
# 擦除指定扇区范围
python -m pyocd erase 0x08008000 8 -t target_name # 擦除从0x08008000开始的8个扇区
# 擦除指定地址范围
python -m pyocd erase --address 0x08008000 --count 32768 -t target_name # 擦除32KB
擦除选项
# 芯片擦除
python -m pyocd erase --chip -t target_name
# 扇区擦除(默认)
python -m pyocd erase --sector -t target_name
# 强制擦除
python -m pyocd erase --force -t target_name
内存操作与调试
1. 复位操作
reset命令详解
# 基本复位
python -m pyocd reset -t target_name
# 复位并暂停核心
python -m pyocd reset -halt -t target_name
# 指定复位类型
python -m pyocd reset --type sw_system -t target_name
python -m pyocd reset --type hw -t target_name
复位类型选项
-
default:默认复位类型 -
hw:硬件复位 -
sw:软件复位 -
sw_system:系统级软件复位 -
sw_core:核心级软件复位 -
sw_sysresetreq:SYSRESETREQ复位 -
sw_vectreset:VECTRESET复位 -
sw_emulated:模拟复位 -
system:系统复位 -
core:核心复位 -
sysresetreq:SYSRESETREQ -
vectreset:VECTRESET -
emulated:模拟复位
2. 信息查询
JSON输出格式
# 列出调试器(JSON格式)
python -m pyocd json --probes
# 列出目标设备(JSON格式)
python -m pyocd json --targets
# 列出开发板(JSON格式)
python -m pyocd json --boards
# 列出功能和选项(JSON格式)
python -m pyocd json --features
示例输出
{
"probes": [
{
"unique_id": "ATK-03262021",
"description": "ATK ATK-FS-HID-CMSIS-DAP",
"is_connected": true,
"supports_access_ports": true,
"wire_protocol": "swd",
"pack_support": false
}
]
}
3. CMSIS-Pack管理
pack命令详解
# 更新包索引
python -m pyocd pack update
# 显示已安装的包
python -m pyocd pack show
# 查找包含特定设备的包
python -m pyocd pack find "stm32f103*"
# 安装包含特定设备的包
python -m pyocd pack install "stm32f103*"
# 仅显示将要安装的包(不实际下载)
python -m pyocd pack install "stm32f103*" --no-download
# 清理所有包和索引
python -m pyocd pack clean
Pack子命令详解
# pack update - 更新包索引
python -m pyocd pack update
# pack show - 显示已安装的包
python -m pyocd pack show
# pack find - 查找设备包
python -m pyocd pack find GLOB_PATTERN
# pack install - 安装设备包
python -m pyocd pack install GLOB_PATTERN
# pack clean - 清理包
python -m pyocd pack clean
GDB服务器
1. 启动GDB服务器
gdbserver命令基础用法
# 基本启动
python -m pyocd gdbserver -t target_name
# 指定端口
python -m pyocd gdbserver -t target_name --gdb-port 3333 --telnet-port 4444
# 后台运行
python -m pyocd gdbserver -t target_name --persist
2. GDB服务器选项
端口配置
# 设置GDB端口
python -m pyocd gdbserver -t target_name --gdb-port 3333
# 设置Telnet端口(用于semihosting)
python -m pyocd gdbserver -t target_name --telnet-port 4444
# 设置SWV端口
python -m pyocd gdbserver -t target_name --swv-port 2332
连接选项
# 设置连接模式
python -m pyocd gdbserver -t target_name --connect halt
# 设置频率
python -m pyocd gdbserver -t target_name --frequency 2000000
# 设置复位类型
python -m pyocd gdbserver -t target_name --reset-type sw_system
调试选项
# 启用semihosting
python -m pyocd gdbserver -t target_name --enable-semihosting
# 启用SWV
python -m pyocd gdbserver -t target_name --enable-swv --swv-system-clock 72000000
# 启用RTOS感知调试
python -m pyocd gdbserver -t target_name --rtos-name FreeRTOS
# 断开连接时运行目标
python -m pyocd gdbserver -t target_name --resume-on-disconnect
3. 实用GDB配置
GDB客户端配置文件
# .gdbinit 示例
target remote localhost:3333
file firmware.elf
monitor reset halt
load
monitor reset init
# 设置断点
break main
continue
多核调试配置
# 启动多核调试
python -m pyocd gdbserver -t stm32h743zi --enable-multicore-debug
# 选择特定核心
python -m pyocd gdbserver -t stm32h743zi --primary-core 1
Commander交互模式
1. Commander基础用法
进入交互模式
# 基本交互模式
python -m pyocd commander -t target_name
# 执行命令后进入交互模式
python -m pyocd commander -t target_name -c "help" -i
# 从文件执行命令
python -m pyocd commander -t target_name -x commands.txt
Commander选项详解
# 连接选项
python -m pyocd commander -t target_name --halt # 连接时暂停核心
python -m pyocd commander -t target_name --no-init # 不初始化调试系统
python -m pyocd commander -t target_name --elf firmware.elf # 指定ELF文件
# 命令执行选项
python -m pyocd commander -t target_name -c "reset" # 执行单个命令
python -m pyocd commander -t target_name -c "reset" -c "status" # 执行多个命令
python -m pyocd commander -t target_name -x script.txt # 从文件执行命令
# 交互模式选项
python -m pyocd commander -t target_name -i # 保持交互模式
2. Commander命令详解
内存操作命令
内存读取
# 读取8位数据
rb 0x20000000 64 # 读取64字节
rb 0x08000000 # 读取默认长度
# 读取16位数据
rh 0x20000000 32 # 读取32个半字
rh 0x20000000 # 读取默认长度
# 读取32位数据
rw 0x20000000 16 # 读取16个字
rw 0x20000000 # 读取默认长度
# 读取64位数据
rd 0x20000000 8 # 读取8个双字
内存写入
# 写入8位数据
wb 0x20000000 0x12 0x34 0x56 0x78
# 写入16位数据
wh 0x20000000 0x1234 0x5678
# 写入32位数据
ww 0x20000000 0x12345678 0x87654321
# 写入64位数据
wd 0x20000000 0x1234567887654321
内存填充和搜索
# 填充内存区域
fill 0x20000000 1024 0xFF # 填充1KB的0xFF
fill 32 0x20000000 256 0x00 # 以32位格式填充256字节的0x00
# 搜索内存
find 0x20000000 1024 0x1234 # 在1KB范围内搜索0x1234
find -n 0x20000000 1024 0x12 0x34 # 搜索多个字节
文件操作命令
读取文件到内存
# 加载二进制文件到内存
loadmem 0x20000000 firmware.bin
loadmem 0x08000000 bootloader.bin
# 加载ELF文件
load firmware.elf
保存内存到文件
# 保存内存区域到文件
savemem 0x08000000 65536 backup.bin
savemem 0x20000000 1024 ram_dump.bin
比较内存和文件
# 比较内存和文件
cmp 0x08000000 32768 firmware.bin
cmp 0x20000000 1024 ram_content.bin
Flash操作命令
Flash擦除
# 擦除整个Flash
erase
# 擦除指定扇区
erase 0x08008000 4 # 擦除从0x08008000开始的4个扇区
erase 0x08010000 # 擦除指定地址的扇区
Flash编程
# 烧录文件到Flash
load firmware.bin
load firmware.bin 0x08000000 # 指定地址
load firmware.hex # 烧录HEX文件
load firmware.elf # 烧录ELF文件
调试控制命令
复位和运行控制
# 复位操作
reset # 复位设备
reset halt # 复位并暂停
reset -halt # 复位并暂停(另一种语法)
reset sw_system # 软件复位
# 运行控制
halt # 暂停核心
continue # 继续运行
go # 继续运行(别名)
step # 单步执行
step 10 # 单步执行10条指令
断点操作
# 设置断点
break 0x08000100 # 在指定地址设置断点
break 0x08000100 0x08000100 # 设置断点范围
# 列出断点
lsbreak
# 删除断点
rmbreak 0x08000100 # 删除指定地址的断点
观察点操作
# 设置观察点
watch 0x20000000 # 读写观察点
watch 0x20000000 r # 读观察点
watch 0x20000000 w # 写观察点
watch 0x20000000 r 4 # 4字节读观察点
# 列出观察点
lswatch
# 删除观察点
rmwatch 0x20000000
rmwatch 0x20000000 w 2 # 删除2字节写观察点
寄存器操作命令
查看寄存器
# 查看所有寄存器
reg
rr # 别名
# 查看特定寄存器
reg r0 r1 r2 pc
reg pc
reg sp
# 查看寄存器组
reg -f core
reg -f fpu
修改寄存器
# 修改寄存器值
wreg pc 0x08000100
wreg r0 0x12345678
wreg sp 0x20001000
反汇编命令
反汇编内存
# 反汇编指定地址和长度
d 0x08000000 64
# 反汇编并居中显示
d -c 0x08000100 32
# 反汇编指定长度
d 0x08000000 0x100
信息查看命令
系统信息
# 显示目标状态
st
status # 别名
# 显示目标信息
show target
show map # 显示内存映射
show cores # 显示核心信息
show peripherals # 显示外设信息
符号信息(需要ELF文件)
# 显示符号值
symbol main
symbol printf
# 显示地址对应的符号
where 0x08000100
where pc
AP和DP寄存器操作
DP寄存器操作
# 读取DP寄存器
readdp 0x0
readdp 0x4
# 写入DP寄存器
writedp 0x0 0x12345678
AP寄存器操作
# 读取AP寄存器
readap 0x0
readap 0x1 0x0
# 写入AP寄存器
writeap 0x0 0x12345678
writeap 0x1 0x0 0x87654321
实用工具命令
延时和脚本执行
# 延时(毫秒)
sleep 1000 # 延时1秒
sleep 500 # 延时500毫秒
# 执行Python表达式
$ print("Hello World")
$ hex(0x1234)
# 执行系统命令
! ls
! dir
设置和显示选项
# 设置选项
set frequency 2000000
set log_level debug
# 显示选项
show frequency
show log_level
show option
3. Commander脚本示例
批量操作脚本
# commands.txt - 批量操作示例
echo "开始批量操作..."
reset halt
load firmware.bin
verify 0x08000000 $(stat -c%s firmware.bin) firmware.bin
echo "操作完成!"
exit
自动化测试脚本
# test_commands.txt - 自动化测试示例
echo "开始自动化测试..."
# 连接设备
connect
show target
# 擦除Flash
erase
# 烧录测试固件
load test_firmware.bin
# 验证烧录
cmp 0x08000000 32768 test_firmware.bin
# 设置断点
break 0x08000100
# 运行测试
continue
# 等待测试完成
sleep 5000
# 查看结果
status
reg pc
echo "测试完成!"
exit
内存分析脚本
# memory_analysis.txt - 内存分析示例
echo "开始内存分析..."
# 保存Flash内容
savemem 0x08000000 65536 flash_backup.bin
# 保存RAM内容
savemem 0x20000000 32768 ram_backup.bin
# 分析内存使用情况
echo "Flash分析:"
find 0x08000000 65536 0xFF 100 # 查找连续的0xFF
echo "RAM分析:"
find 0x20000000 32768 0x00 50 # 查找连续的0x00
# 显示关键寄存器
reg sp pc lr msp psp
echo "内存分析完成!"
4. Commander高级用法
多核心操作
# 切换核心
core 0 # 切换到核心0
core 1 # 切换到核心1
# 显示核心信息
show cores
GDB服务器控制
# 启动GDB服务器
gdbserver start
# 停止GDB服务器
gdbserver stop
# 查看GDB服务器状态
gdbserver status
探针服务器控制
# 启动探针服务器
probeserver start
# 停止探针服务器
probeserver stop
# 查看探针服务器状态
probeserver status
RTT实时数据传输
1. RTT基础用法
启动RTT查看器
# 基本RTT查看器
python -m pyocd rtt -t target_name
# 指定RTT控制块地址
python -m pyocd rtt -t target_name --address 0x20000000
# 指定搜索范围大小
python -m pyocd rtt -t target_name --address 0x20000000 --size 0x1000
RTT选项详解
# 连接选项
python -m pyocd rtt -t target_name -u probe_id # 指定调试器
python -m pyocd rtt -t target_name -f 2000000 # 设置频率
python -m pyocd rtt -t target_name -M halt # 连接模式
# RTT配置选项
python -m pyocd rtt -t target_name --up-channel-id 0 # 上行通道ID
python -m pyocd rtt -t target_name --down-channel-id 0 # 下行通道ID
# 日志选项
python -m pyocd rtt -t target_name -d rtt_log.txt # 日志文件
python -m pyocd rtt -t target_name -v # 详细输出
2. RTT配置和使用
在目标代码中配置RTT
// RTT配置示例
#include "SEGGER_RTT.h"
// RTT控制块定义
SEGGER_RTT_CB _SEGGER_RTT;
// RTT缓冲区定义
char rtt_up_buffer[1024];
char rtt_down_buffer[16];
int main(void) {
// 初始化RTT
SEGGER_RTT_Init();
// 配置上行通道
SEGGER_RTT_ConfigUpBuffer(0, "Terminal", rtt_up_buffer, sizeof(rtt_up_buffer), SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
// 配置下行通道
SEGGER_RTT_ConfigDownBuffer(0, "Terminal", rtt_down_buffer, sizeof(rtt_down_buffer), SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
// 发送数据
SEGGER_RTT_WriteString(0, "Hello RTT!\r\n");
while(1) {
// 主循环
SEGGER_RTT_printf(0, "Counter: %d\r\n", counter++);
HAL_Delay(1000);
}
}
RTT通道管理
# 使用特定通道
python -m pyocd rtt -t target_name --up-channel-id 1 --down-channel-id 1
# 查看可用通道
python -m pyocd commander -t target_name -c "show rtt" -c "exit"
实用示例
1. 完整的IAP烧录流程
引导程序烧录
#!/bin/bash
# IAP引导程序烧录脚本
TARGET="gd32f103cb"
BOOTLOADER_FILE="bootloader.bin"
APP_FILE="app.bin"
echo "=== IAP固件烧录流程 ==="
# 步骤1:检查设备连接
echo "检查调试器连接..."
python -m pyocd list
if [ $? -ne 0 ]; then
echo "错误:未找到调试器!"
exit 1
fi
# 步骤2:擦除Flash
echo "擦除Flash..."
python -m pyocd erase -t $TARGET
# 步骤3:烧录引导程序
echo "烧录引导程序到 0x08000000..."
python -m pyocd load $BOOTLOADER_FILE -a 0x08000000 -t $TARGET --verify
# 步骤4:烧录应用程序
echo "烧录应用程序到 0x08006000..."
python -m pyocd load $APP_FILE -a 0x08006000 -t $TARGET --verify
# 步骤5:复位设备
echo "复位设备..."
python -m pyocd reset -t $TARGET
echo "=== 烧录完成 ==="
固件验证脚本
#!/bin/bash
# 固件验证脚本
TARGET="gd32f103cb"
COMBINED_FILE="combined.bin"
echo "=== 固件验证 ==="
# 烧录合并固件
echo "烧录合并固件..."
python -m pyocd load $COMBINED_FILE -t $TARGET --verify
# 验证引导程序部分
echo "验证引导程序部分..."
python -m pyocd commander -t $TARGET -c "cmp 0x08000000 24576 bootloader.bin" -c "exit"
# 验证应用程序部分
echo "验证应用程序部分..."
python -m pyocd commander -t $TARGET -c "cmp 0x08006000 34184 app.bin" -c "exit"
# 复位运行
echo "复位运行..."
python -m pyocd reset -t $TARGET
echo "=== 验证完成 ==="
2. 调试会话示例
启动调试会话
#!/bin/bash
# 启动调试会话
TARGET="stm32f103c8"
ELF_FILE="firmware.elf"
echo "=== 启动调试会话 ==="
# 后台启动GDB服务器
echo "启动GDB服务器..."
python -m pyocd gdbserver -t $TARGET --gdb-port 3333 --telnet-port 4444 &
GDB_PID=$!
# 等待GDB服务器启动
sleep 2
# 连接GDB客户端
echo "连接GDB客户端..."
arm-none-eabi-gdb $ELF_FILE -ex "target remote localhost:3333" -ex "load" -ex "break main" -ex "continue"
# 清理
kill $GDB_PID
echo "=== 调试会话结束 ==="
Commander调试脚本
# debug_session.txt - Commander调试会话
# 连接和初始化
echo "连接到目标设备..."
reset halt
show target
# 加载固件
echo "加载固件..."
load firmware.elf
# 设置断点
echo "设置断点..."
break main
break 0x08000100
# 开始调试
echo "开始运行..."
continue
# 等待用户操作
echo "按Enter键继续..."
read
# 查看状态
echo "查看当前状态..."
status
reg pc lr
3. 批量生产烧录脚本
生产烧录脚本
#!/bin/bash
# 生产环境批量烧录脚本
FIRMWARE_DIR="./firmware"
LOG_DIR="./logs"
TARGET="gd32f103cb"
# 创建日志目录
mkdir -p $LOG_DIR
# 日期时间戳
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$LOG_DIR/flash_$TIMESTAMP.log"
echo "=== 批量烧录开始 ===" | tee $LOG_FILE
echo "时间: $(date)" | tee -a $LOG_FILE
# 烧录计数器
COUNTER=0
SUCCESS_COUNT=0
FAIL_COUNT=0
while true; do
COUNTER=$((COUNTER + 1))
echo "" | tee -a $LOG_FILE
echo "=== 烧录 #$COUNTER ===" | tee -a $LOG_FILE
# 检查设备连接
echo "检查设备连接..." | tee -a $LOG_FILE
if ! python -m pyocd list | grep -q "CMSIS-DAP"; then
echo "错误:未找到调试器!" | tee -a $LOG_FILE
echo "请连接设备后按Enter继续,或按Ctrl+C退出..."
read
continue
fi
# 烧录固件
echo "开始烧录..." | tee -a $LOG_FILE
if python -m pyocd load "$FIRMWARE_DIR/production.bin" -t $TARGET --verify 2>&1 | tee -a $LOG_FILE; then
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
echo "烧录成功!" | tee -a $LOG_FILE
# 复位设备
python -m pyocd reset -t $TARGET
else
FAIL_COUNT=$((FAIL_COUNT + 1))
echo "烧录失败!" | tee -a $LOG_FILE
fi
# 显示统计信息
echo "统计: 成功 $SUCCESS_COUNT, 失败 $FAIL_COUNT, 总计 $COUNTER" | tee -a $LOG_FILE
# 询问是否继续
echo "继续烧录下一个设备?(y/n)"
read -r response
if [[ "$response" != "y" && "$response" != "Y" ]]; then
break
fi
done
echo "" | tee -a $LOG_FILE
echo "=== 批量烧录结束 ===" | tee -a $LOG_FILE
echo "总计: $COUNTER, 成功: $SUCCESS_COUNT, 失败: $FAIL_COUNT" | tee -a $LOG_FILE
echo "时间: $(date)" | tee -a $LOG_FILE
4. 自动化测试脚本
功能测试脚本
#!/bin/bash
# 自动化功能测试脚本
TARGET="stm32f103c8"
TEST_FIRMWARE="test_firmware.bin"
TEST_RESULTS="./test_results"
# 创建测试结果目录
mkdir -p $TEST_RESULTS
echo "=== 自动化测试开始 ==="
# 测试1:Flash烧录测试
echo "测试1: Flash烧录测试"
python -m pyocd erase -t $TARGET
if python -m pyocd load $TEST_FIRMWARE -t $TARGET --verify; then
echo "✓ Flash烧录测试通过"
else
echo "✗ Flash烧录测试失败"
exit 1
fi
# 测试2:复位测试
echo "测试2: 复位测试"
python -m pyocd reset -t $TARGET
sleep 1
if python -m pyocd commander -t $TARGET -c "status" -c "exit" | grep -q "halted\|running"; then
echo "✓ 复位测试通过"
else
echo "✗ 复位测试失败"
fi
# 测试3:内存读写测试
echo "测试3: 内存读写测试"
TEST_ADDR=0x20000100
TEST_VALUE=0x12345678
python -m pyocd commander -t $TARGET -c "ww $TEST_ADDR $TEST_VALUE" -c "rw $TEST_ADDR 1" -c "exit" > $TEST_RESULTS/memory_test.txt
if grep -q "$TEST_VALUE" $TEST_RESULTS/memory_test.txt; then
echo "✓ 内存读写测试通过"
else
echo "✗ 内存读写测试失败"
fi
# 测试4:断点测试
echo "测试4: 断点测试"
python -m pyocd commander -t $TARGET -c "reset halt" -c "break 0x08000100" -c "continue" -c "status" -c "exit" > $TEST_RESULTS/breakpoint_test.txt
if grep -q "halted" $TEST_RESULTS/breakpoint_test.txt; then
echo "✓ 断点测试通过"
else
echo "✗ 断点测试失败"
fi
echo "=== 自动化测试完成 ==="
常见问题与解决方案
1. 连接问题
问题:无法找到调试器
# 错误信息
# No available probes found
# 解决方案
# 1. 检查USB连接
python -m pyocd list
# 2. 安装驱动程序(Windows)
# 安装CMSIS-DAP或ST-Link驱动
# 3. 检查设备权限(Linux)
sudo usermod -a -G dialout $USER
# 或使用sudo运行
sudo python -m pyocd list
问题:目标设备未识别
# 错误信息
# n/a
# 解决方案
# 1. 明确指定目标设备
python -m pyocd list --targets
python -m pyocd load firmware.bin -t stm32f103c8
# 2. 安装对应的CMSIS-Pack
python -m pyocd pack install "stm32f103*"
# 3. 使用通用目标
python -m pyocd load firmware.bin -t cortex_m
问题:连接超时
# 错误信息
# Timeout waiting for debug probe
# 解决方案
# 1. 降低调试频率
python -m pyocd load firmware.bin -t target_name -f 100000
# 2. 使用不同的连接模式
python -m pyocd load firmware.bin -t target_name -M under-reset
# 3. 增加超时时间
python -m pyocd load firmware.bin -t target_name -O connect_mode=pre-reset
2. 烧录问题
问题:烧录失败
# 错误信息
# Failed to program flash
# 解决方案
# 1. 先擦除Flash
python -m pyocd erase -t target_name
python -m pyocd load firmware.bin -t target_name
# 2. 使用整片擦除
python -m pyocd load firmware.bin -t target_name -e chip
# 3. 降低频率
python -m pyocd load firmware.bin -t target_name -f 500000
# 4. 禁用快速编程
python -m pyocd load firmware.bin -t target_name -O fast_program=false
问题:验证失败
# 错误信息
# Verification failed
# 解决方案
# 1. 检查Flash保护状态
python -m pyocd commander -t target_name -c "show locked" -c "exit"
# 2. 解锁Flash(如果被锁定)
python -m pyocd commander -t target_name -c "unlock" -c "exit"
# 3. 重新烧录并验证
python -m pyocd load firmware.bin -t target_name --verify
问题:地址不对齐
# 错误信息
# Address not aligned
# 解决方案
# 1. 检查文件格式和地址
hexdump -C firmware.bin | head
# 2. 使用正确的地址
python -m pyocd load firmware.bin -a 0x08000000 -t target_name
# 3. 确保地址按页对齐
# STM32F1:2KB页对齐
# STM32F4:128KB扇区对齐
3. 调试问题
问题:GDB连接失败
# 错误信息
# Connection refused
# 解决方案
# 1. 检查端口占用
netstat -an | grep 3333
# 2. 使用不同端口
python -m pyocd gdbserver -t target_name --gdb-port 3334
# 3. 检查防火墙设置
# 允许localhost:3333连接
问题:断点不工作
# 解决方案
# 1. 检查Flash区域
# 确保断点设置在可执行区域
# 2. 使用软件断点
python -m pyocd commander -t target_name -c "break 0x08000100" -c "exit"
# 3. 检查断点数量
# 硬件断点数量有限(通常6-8个)
python -m pyocd commander -t target_name -c "lsbreak" -c "exit"
4. 性能问题
问题:烧录速度慢
# 解决方案
# 1. 增加调试频率
python -m pyocd load firmware.bin -t target_name -f 4000000
# 2. 启用快速编程
python -m pyocd load firmware.bin -t target_name -O fast_program=true
# 3. 使用CRC验证
python -m pyocd load firmware.bin -t target_name --trust-crc
问题:RTT数据丢失
# 解决方案
# 1. 增加RTT缓冲区大小
# 在目标代码中增加缓冲区大小
# 2. 调整RTT通道配置
python -m pyocd rtt -t target_name --up-channel-id 0 --down-channel-id 0
# 3. 降低输出频率
# 在目标代码中降低printf频率
附录
1. 常用目标芯片型号
STM32系列
# STM32F1系列
stm32f100c8 # STM32F100C8T6
stm32f103c8 # STM32F103C8T6
stm32f103cb # STM32F103CBT6
stm32f103ze # STM32F103ZET6
# STM32F4系列
stm32f401xc # STM32F401XC
stm32f401xe # STM32F401XE
stm32f407vg # STM32F407VGT6
stm32f429zi # STM32F429ZIT6
# STM32H7系列
stm32h743zi # STM32H743ZIT6
stm32h750vb # STM32H750VBT6
# STM32L4系列
stm32l475vg # STM32L475VGT6
stm32l476rg # STM32L476RGT6
GD32系列
# GD32F1系列
gd32f103c8 # GD32F103C8T6
gd32f103cb # GD32F103CBT6
gd32f103re # GD32F103RET6
gd32f103ze # GD32F103ZET6
# GD32F3系列
gd32f303cct6 # GD32F303CCT6
# GD32F4系列
gd32f450ve # GD32F450VET6
Nordic系列
# nRF51系列
nrf51822 # nRF51822
nrf51422 # nRF51422
# nRF52系列
nrf52832 # nRF52832
nrf52840 # nRF52840
NXP系列
# LPC系列
lpc1768 # LPC1768
lpc1114 # LPC1114
lpc4088 # LPC4088
lpc54608 # LPC54608
# Kinetis系列
k64f # FRDM-K64F
k20d50m # K20D50M
k22f # FRDM-K22F
2. 配置文件示例
完整配置文件(pyocd.yaml)
# PyOCD完整配置文件示例
# 目标配置
target: stm32f103c8
board: stm32f103c8_tst
# 连接配置
frequency: 2000000
connect_mode: halt
reset_type: sw_system
# Flash配置
flash:
chip_erase: sector
fast_program: true
# GDB服务器配置
gdbserver:
gdb_port: 3333
telnet_port: 4444
persist: true
enable_semihosting: true
semihosting_console_type: telnet
rtos_name: "FreeRTOS"
# RTT配置
rtt:
enabled: true
address: 0x20000000
size: 0x1000
up_channel_id: 0
down_channel_id: 0
# 调试配置
debug:
enable_multicore_debug: false
vector_catch: "hard,mm,bus,usage"
step_into_interrupts: false
# 日志配置
logging:
level: "info"
color: "auto"
# 用户脚本
user_script: "pyocd_user.py"
3. 环境变量
PyOCD环境变量
# 设置包存储目录
export PYOCD_PACK_CACHE_DIR=~/.pyocd/packs
# 设置配置文件路径
export PYOCD_CONFIG_PATH=~/.pyocd/pyocd.yaml
# 设置日志级别
export PYOCD_LOG_LEVEL=debug
# 启用彩色输出
export PYOCD_COLOR=always
4. 性能调优建议
烧录性能优化
# 1. 使用最佳频率
# STM32F1: 2-4MHz
# STM32F4: 4-8MHz
# STM32H7: 8-16MHz
# 2. 启用快速编程
python -m pyocd load firmware.bin -t target_name -O fast_program=true
# 3. 选择合适的擦除方式
# 小文件:sector erase
# 大文件:chip erase
python -m pyocd load firmware.bin -t target_name -e auto
调试性能优化
# 1. 减少断点数量
# 使用较少的断点
# 使用条件断点
# 2. 调整RTT缓冲区
# 增加缓冲区大小
# 减少输出频率
# 3. 优化连接设置
# 使用合适的频率
# 选择正确的连接模式
5. 故障排除清单
连接问题清单
烧录问题清单
调试问题清单
6. 支持和资源
官方资源
社区资源
-
讨论论坛: GitHub Discussions
-
Stack Overflow: 标签
pyocd -
博客和教程: 各种嵌入式开发社区
相关工具
-
OpenOCD: 另一个开源调试工具
-
J-Link: SEGGER商业调试工具
-
ST-Link Utility: ST官方工具
-
Keil MDK: ARM官方开发环境

浙公网安备 33010602011771号