PyOCD使用指南

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

连接问题清单

烧录问题清单

调试问题清单

6. 支持和资源

官方资源

社区资源

  • 讨论论坛: GitHub Discussions

  • Stack Overflow: 标签 pyocd

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

相关工具

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

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

  • ST-Link Utility: ST官方工具

  • Keil MDK: ARM官方开发环境


posted @ 2025-10-23 16:17  望兮  阅读(25)  评论(0)    收藏  举报