PyOCD 完整使用手册

目录

  1. 概述

  2. 安装与快速入门

  3. 基本命令结构

  4. 设备连接与配置

  5. 固件烧录操作

  6. 内存操作与调试

  7. GDB服务器

  8. Commander交互模式

  9. RTT实时数据传输

  10. 实用示例

  11. 常见问题与解决方案

  12. 附录


概述

项目中需使用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

快速入门示例

  1. 查看可用设备

python -m pyocd list
   
  1. 烧录固件

python -m pyocd load firmware.bin -t target_name

# target_name就是你的芯片型号,例如STM32G431CBU6

  1. 启动调试器

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. 故障排除清单

连接问题清单

  • [ ] USB线缆连接正常

  • [ ] 调试器驱动安装正确

  • [ ] 目标设备供电正常

  • [ ] SWD/JTAG连接正确

  • [ ] 目标设备未进入低功耗模式

  • [ ] 调试接口未被占用

烧录问题清单

  • [ ] 目标芯片型号正确

  • [ ] Flash地址正确

  • [ ] 文件格式正确

  • [ ] Flash未锁定

  • [ ] 电源供应稳定

  • [ ] 调试频率适中

调试问题清单

  • [ ] GDB服务器启动正常

  • [ ] 端口未被占用

  • [ ] 防火墙设置正确

  • [ ] ELF文件匹配

  • [ ] 符号信息完整

  • [ ] 断点设置正确

6. 支持和资源

官方资源

  • 项目主页: https://github.com/pyocd/pyOCD

  • 文档: https://pyocd.io/docs/

  • 问题反馈: https://github.com/pyocd/pyOCD/issues

社区资源

  • 讨论论坛: GitHub Discussions

  • Stack Overflow: 标签 pyocd

  • 博客和教程: 各种嵌入式开发社区

相关工具

  • OpenOCD: 另一个开源调试工具

  • J-Link: SEGGER商业调试工具

  • ST-Link Utility: ST官方工具

  • Keil MDK: ARM官方开发环境