Skip to content

ChunPingWang/pico-debug-probe-tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

使用 Raspberry Pi Debug Probe 除錯 Pico 完整教學(繁體中文)

Build blink

本教學說明如何更新 Raspberry Pi Debug Probe 韌體,並使用它來燒錄與除錯 Raspberry Pi Pico / Pico 2(RP2040 / RP2350)。

參考資料:

📚 深入文件:OpenOCD 深入說明GDB 深入說明常用指令速查表


目錄

  1. 什麼是 Debug Probe
  2. 硬體介紹與接線
  3. 更新 Debug Probe 韌體
  4. 安裝除錯工具(OpenOCD / GDB / picotool)
  5. 用 Debug Probe 燒錄程式
  6. 用 OpenOCD + GDB 進行除錯
  7. 實測驗證 SWD 連線
  8. 在 VS Code 中除錯
  9. 使用內建 UART 序列埠
  10. 常見問題 FAQ

1. 什麼是 Debug Probe

Raspberry Pi Debug Probe 是一顆基於 RP2040 的官方除錯器,內含 debugprobe 韌體,對外提供兩大功能:

功能 說明 對應介面
CMSIS-DAP 除錯器 透過 SWD(Serial Wire Debug)燒錄與除錯目標 MCU USB Vendor 介面
USB-to-UART 橋接器 把目標板的 UART 訊號轉成電腦上的序列埠 USB CDC(/dev/ttyACM0

它在電腦上會辨識為 Raspberry Pi Debug Probe (CMSIS-DAP), USB 識別碼為 2e8a:000c

Debug Probe 出廠會附兩條 3-pin JST-SH 連接線

  • 橘色頭(D / SWD):接目標板的 SWCLK / SWDIO / GND(除錯用)
  • 黃色頭(U / UART):接目標板的 TX / RX / GND(序列埠用)

2. 硬體介紹與接線

2.0 Debug Probe 的三個埠

Debug Probe 外殼上有三個接頭:

        ┌──────────────────────────────┐
        │        Debug  Probe          │
        │                              │
  [USB]─┤ ●          (D)      (U)      │
        │  USB-C     橘框     黃框      │
        └──────────────────────────────┘
           │          │        │
        接電腦     SWD 除錯   UART 序列
接頭 標示 附的線 用途
USB-C USB 線 接電腦供電+資料
D(左) 橘色框 三色排線(橘框) SWD 除錯(燒錄 / 下中斷點)
U(右) 黃色框 三色排線(黃框) UART 序列埠printf 輸出)

附的 3-pin JST-SH 排線,接頭上通常標有 箭頭方向與顏色; 下面用「訊號名稱」對照,實際以你手上排線的絲印為準。


2.1 SWD 接線(D 埠,橘色排線)— 除錯 / 燒錄用

Debug Probe D 埠Pico target 底部 DEBUG 排針

Debug Probe D 埠 排線顏色 Pico target(DEBUG 排針)
SWCLK SWCLK
GND GND
SWDIO SWDIO

Pico / Pico 2 底部有一排 3-pin 除錯排針,絲印由左到右為:

   Pico 底部 DEBUG 排針(三個孔)
   ┌─────┬─────┬─────┐
   │SWCLK│ GND │SWDIO│
   └──┬──┴──┬──┴──┬──┘
      │     │     │
      橘    黑    黃      ← 來自 Debug Probe 的 D 埠

✅ SWD 是一對一直連(同名接同名):SWCLK→SWCLKGND→GNDSWDIO→SWDIO


2.2 UART 接線(U 埠,黃色排線)— 序列埠 / printf

⚠️ 重點:UART 必須「TX↔RX 交叉」接,不是同名直連!

Debug Probe U 埠 排線 Pico target
TX GP1(UART0 RX,實體第 2 腳)
RX GP0(UART0 TX,實體第 1 腳)
GND GND(例如實體第 3 腳)
   Debug Probe (U)              Pico target
   ┌──────────┐                ┌──────────┐
   │   TX ────┼────────────────┼──> GP1 (RX,pin 2)
   │   RX <───┼────────────────┼──── GP0 (TX,pin 1)
   │   GND ───┼────────────────┼──── GND      (pin 3)
   └──────────┘                └──────────┘
       Probe 的 TX 接目標的 RX,Probe 的 RX 接目標的 TX(交叉)

2.3 完整接線總表(Debug Probe ↔ Pico)

一次接好 SWD+UART(除錯與序列埠同時使用):

Debug Probe 排線 Pico target 腳位
SWCLK D 底部 DEBUG:SWCLK
GND D 底部 DEBUG:GND
SWDIO D 底部 DEBUG:SWDIO
TX U GP1 / UART0 RX(pin 2)
RX U GP0 / UART0 TX(pin 1)
GND U GND(pin 3)

💡 若只是要燒錄/下中斷點除錯,接 D 埠(SWD) 就夠了; 只有需要看 printf 序列輸出時才要另外接 U 埠(UART)

🔌 目標板(Pico)仍需自己的電源:可用另一條 USB 線供電, 或視情況從 Debug Probe/其他 3V3 來源供電(本教學不從 Probe 供電)。


3. 更新 Debug Probe 韌體

本節就是把 Debug Probe 內建的 debugprobe 韌體升級到最新版 (撰寫時最新為 debugprobe-v2.3.1)。

3.1 為什麼要更新

新版韌體修正了穩定度、支援 RP2350(Pico 2)目標、並提升 SWD 速度。 若你的 OpenOCD 連線常常斷線或速度慢,更新韌體通常能改善。

3.2 下載最新韌體

debugprobe Releases 下載對應檔案:

你的硬體 要下載的檔案
官方 Debug Probe(塑膠外殼那顆) debugprobe.uf2
用一顆 Pico 當除錯器 debugprobe_on_pico.uf2
用一顆 Pico 2 當除錯器 debugprobe_on_pico2.uf2

指令下載(本專案已幫你下載並放在 firmware/):

curl -L -o debugprobe.uf2 \
  https://github.com/raspberrypi/debugprobe/releases/download/debugprobe-v2.3.1/debugprobe.uf2

3.3 讓 Debug Probe 進入 BOOTSEL(大量儲存)模式

Debug Probe 沒有 picotool 的 reset 介面,無法用軟體指令重開進 BOOTSEL, 必須用實體 BOOTSEL 按鈕。

  1. 把 Debug Probe 的 USB 線拔掉
  2. 按住 Debug Probe 上的 BOOTSEL 按鈕(外殼上的小孔/小按鈕)。
  3. 一邊按住,一邊把 USB 線插回電腦
  4. 放開按鈕。此時電腦會出現一個名為 RPI-RP2 的隨身碟。

驗證是否進入 BOOTSEL:

lsusb | grep 2e8a
# 進入 BOOTSEL 前: 2e8a:000c  Raspberry Pi Debug Probe (CMSIS-DAP)
# 進入 BOOTSEL 後: 2e8a:0003  Raspberry Pi RP2 Boot   ← 出現這個就對了

3.4 燒錄韌體

方法 A:直接把 UF2 拖進 RPI-RP2 隨身碟(最簡單)

debugprobe.uf2 複製到 RPI-RP2 磁碟即可,複製完裝置會自動重開, 回到 CMSIS-DAP 模式。

cp firmware/debugprobe-v2.3.1.uf2 /run/media/$USER/RPI-RP2/
sync

方法 B:用 picotool 燒錄

sudo picotool load -x firmware/debugprobe-v2.3.1.uf2
# -x 代表燒完自動重開執行

本專案提供的自動燒錄腳本(會等你按 BOOTSEL 插入後自動複製):

./firmware/flash-probe.sh

3.5 確認更新成功

重新插上(正常模式)後:

lsusb | grep 2e8a
# 應該又變回: 2e8a:000c  Raspberry Pi Debug Probe (CMSIS-DAP)

# 查看版本(需要在 BOOTSEL 模式下才讀得到完整資訊)
sudo picotool info -a

4. 安裝除錯工具

Fedora / RHEL 系 為例(本機環境):

# OpenOCD(Raspberry Pi 版含 rp2040/rp2350 支援)與 GDB
sudo dnf install openocd gdb

# picotool(也可用 Homebrew)
brew install picotool

Debian / Ubuntu:

sudo apt install openocd gdb-multiarch

建議使用 Raspberry Pi 官方版 OpenOCDraspberrypi/openocd 分支), 內含 rp2040.cfgrp2350.cfgcmsis-dap.cfg,對 Debug Probe 支援最完整。

4.1 設定 udev 權限(免 sudo)

不設定的話,/dev/bus/usb/... 的探棒節點是 root:root 0664(一般使用者只能讀不能寫), OpenOCD 會出現 unable to find a matching CMSIS-DAP device,必須加 sudo

本專案已附好規則檔 udev/60-openocd-debugprobe.rules,一行安裝:

sudo cp udev/60-openocd-debugprobe.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger

規則內容(涵蓋正常模式與 RP2040/RP2350 的 BOOTSEL):

# Debug Probe (CMSIS-DAP, 正常模式)
SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE="0666", TAG+="uaccess"
# RP2040 BOOTSEL
SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0003", MODE="0666", TAG+="uaccess"
# RP2350 BOOTSEL
SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000f", MODE="0666", TAG+="uaccess"

安裝後把探棒重新插拔一次讓規則生效,之後 OpenOCD / picotool 就不用 sudo 了。

4.2 安裝 ARM 編譯器與 Pico SDK(要自己編譯程式才需要)

若你要自己編譯程式(而不是只燒別人給的 .uf2),需要三樣東西: CMake / NinjaARM GNU 編譯器Pico SDK

# 1) CMake + Ninja
brew install cmake ninja

# 2) ARM GNU Toolchain(arm-none-eabi)
#    ⚠️ Homebrew 的 arm-none-eabi-gcc 不含 newlib,編譯會出現
#       "cannot read spec file 'nosys.specs'"。請改用「官方版」:
#    到 https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
#    下載 arm-gnu-toolchain-*-x86_64-arm-none-eabi.tar.xz 解壓,
#    再把它的 bin/ 加進 PATH:
export PATH="$HOME/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/bin:$PATH"
arm-none-eabi-gcc --version   # 確認可執行

# 3) Pico SDK
git clone --depth 1 -b 2.1.1 https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk && git submodule update --init lib/tinyusb && cd ..
export PICO_SDK_PATH=$(pwd)/pico-sdk

4.3 永久設定 shell 環境(PATH / PICO_SDK_PATH)

把工具鏈的 bin/ 加進 PATH 後,arm-none-eabi-gccarm-none-eabi-gdbarm-none-eabi-size 等指令就能直接使用(GDB 也在同一個工具鏈裡,不必另裝)。 建議寫進 ~/.zshrc(bash 用 ~/.bashrc),開新終端機就自動生效:

# ~/.zshrc  —— Pico / Debug Probe 開發環境
export PATH="$HOME/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/bin:$PATH"
export PICO_SDK_PATH="$HOME/pico-sdk"

路徑請換成你實際解壓工具鏈與 clone SDK 的位置。

寫入後讓目前的終端機立即載入:

source ~/.zshrc
# 驗證:
command -v arm-none-eabi-gdb    # 應印出完整路徑
arm-none-eabi-gdb --version     # 應印出 GDB 版本
echo "$PICO_SDK_PATH"           # 應印出 SDK 路徑

arm-none-eabi-gdb: command not found,代表 PATH 沒設好或工具鏈路徑不對; 也可以直接用完整路徑執行:/你的路徑/bin/arm-none-eabi-gdb ...


5. 用 Debug Probe 燒錄程式

本專案附了一個可直接編譯的範例:examples/blink。 以下用它示範從編譯到燒錄的完整流程(已在真實 Pico 上實測成功)。

5.1 編譯範例

cd examples/blink
export PICO_SDK_PATH=/path/to/pico-sdk           # 見 4.2

cmake -B build -G Ninja -DPICO_BOARD=pico .       # Pico 2 用 -DPICO_BOARD=pico2
ninja -C build

編譯成功會在 build/ 產生:

build/blink.elf   ← 給 OpenOCD / GDB 用(含除錯資訊)
build/blink.uf2   ← 也可直接拖進 BOOTSEL 磁碟
build/blink.bin / .hex / .map

本專案實測輸出(RP2040):text=18448 data=0 bss=1212blink.elf / blink.uf2 均正常產生。

5.2 用 OpenOCD 一行燒錄

openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg \
  -c "adapter speed 5000" \
  -c "program build/blink.elf verify reset exit"

Pico 2(RP2350)改用 target/rp2350.cfg

實測成功輸出(重點):

Info : SWD DPIDR 0x0bc12477 ...
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
** Programming Started **
Info : Found flash device 'win w25q16jv' (ID 0x001540ef)
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **

看到 ** Verified OK ** + ** Resetting Target ** 就代表燒錄成功、程式已開始執行(板載 LED 開始閃)。

🔧 若出現 couldn't bind gdb to socket on port 3333: Address already in use, 代表有另一個 OpenOCD 還開著佔用 3333 埠。清除:pkill -f 'openocd.*rp2040' (若該程序是用 sudo 開的,需 sudo pkill ...)。這個警告不影響燒錄本身


6. 用 OpenOCD + GDB 進行除錯

6.1 先理解架構:為什麼要開兩個終端機

除錯時中間隔著兩層橋樑,需要同時跑 OpenOCD(伺服器)與 GDB(你下指令的地方):

  你打字        軟體橋樑              硬體橋樑          晶片
 ┌─────┐      ┌──────────┐         ┌───────────┐    ┌──────┐
 │ GDB │◄────►│ OpenOCD  │◄───USB──►│Debug Probe│◄SWD►│ Pico │
 └─────┘ TCP  │(GDB server)         └───────────┘    └──────┘
        :3333 └──────────┘
  • OpenOCD:跟探棒講話,在電腦開一個 port 3333 等 GDB 來接。
  • GDB:你實際設中斷點、看變數的地方;它連到 3333,透過 OpenOCD 控制晶片。
  • 因為兩個都要同時跑,所以用兩個終端機視窗

6.2 終端機 A:開 OpenOCD server(開著別關)

openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000"
# 停在 "Listening on port 3333 for gdb connections" 就代表 server 就緒,保持開著

6.3 終端機 B:開 GDB 連進去

arm-none-eabi-gdb examples/blink/build/blink.elf

blink.elf 換成你自己的程式檔;它含機器碼+除錯資訊(變數名、行號), GDB 才能對應到原始碼。用官方 ARM toolchain 的 arm-none-eabi-gdb (Ubuntu 也可用 gdb-multiarch)。

進到 (gdb) 後依序輸入:

target extended-remote localhost:3333   # 連到終端機 A 的 OpenOCD
monitor reset halt                       # 重置並停住 CPU
load                                      # 把 blink.elf 燒進 flash
break main                                # 在 main 設中斷點
continue                                  # 執行,會停在 main

接著逐行除錯:

指令 作用
next (n) 執行下一行(不進入函式)
step (s) 進入函式內部
print count 印出變數 count 的值
info registers 看暫存器
continue (c) 繼續執行(讓 LED 繼續閃)
monitor reset halt 重新重置並停住
quit (q) 離開 GDB

💡 一步到位:也可用 VS Code 的 Cortex-Debug(見第 8 節),按 F5 就自動做完 「開 OpenOCD → load → 停在 main」,用圖形介面下中斷點。


6.4 深入文件與速查表

OpenOCD 與 GDB 的完整用法(設定檔三層結構、埠、雙核心 multidrop、 中斷點/監看點、記憶體與暫存器檢視、常見錯誤等)已獨立成深入文件, 避免本篇過長:


7. 實測驗證 SWD 連線

以下是本教學用升級到 v2.3.1 的 Debug Probe 連接一顆 Pico (RP2040) 的實際驗證紀錄。

7.1 執行

Pico 用 D 埠接好 SWD(SWCLK/GND/SWDIO)並自行供電後,執行:

openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg \
  -c "adapter speed 5000" -c "init" -c "targets" -c "reset halt" -c "shutdown"

未設定 udev 權限前需加 sudo,並用 -s <openocd>/share/openocd/scripts 指定設定檔路徑。

7.2 成功的輸出(重點節錄)

Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E663B03597206F21
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : Listening on port 3333 for gdb connections
    TargetName         Type       Endian TapName            State
--  ------------------ ---------- ------ ------------------ ------------
 0* rp2040.core0       cortex_m   little rp2040.cpu         running
 1  rp2040.core1       cortex_m   little rp2040.cpu         running
[rp2040.core0] halted due to debug-request, current mode: Thread
xPSR: 0xf1000000 pc: 0x000000ea msp: 0x20041f00

7.3 怎麼判讀

訊息 代表
VID:PID=0x2e8a:0x000c 探棒被辨識(CMSIS-DAP 正常模式)
CMSIS-DAP: Interface Initialised (SWD) 探棒 SWD 介面初始化成功
SWD DPIDR 0x0bc12477 讀到 RP2040 的除錯埠 ID(電氣連線 OK)
[rp2040.core0/core1] Cortex-M0+ ... detected 偵測到雙核心
halted due to debug-request reset halt 成功停住 CPU
Listening on port 3333 GDB server 已就緒,可接 GDB/VS Code

💡 FW Version = 2.0.0 指的是 CMSIS-DAP 協定版本,不是 debugprobe 韌體版本(本教學韌體為 v2.3.1),兩者不同屬正常。

7.4 連不上時

若出現 Error: Failed to connect multidrop rp2040.dap0(讀不到目標),依序檢查:

  1. 目標 Pico 有沒有自己的電(D 埠不供電)。
  2. 接的是 D 埠(SWD)不是 U 埠(UART)。
  3. SWDIO 與 SWCLK 是否接反(最常見)、GND 是否有接。
  4. 板子若是 Pico 2 (RP2350) 要改用 target/rp2350.cfg
  5. 接線品質差時,把 adapter speed 降到 1000 再試。

8. 在 VS Code 中除錯

安裝 Cortex-Debug 擴充套件,在 .vscode/launch.json 加入:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Pico Debug (Debug Probe)",
      "type": "cortex-debug",
      "request": "launch",
      "servertype": "openocd",
      "cwd": "${workspaceFolder}",
      "executable": "${workspaceFolder}/build/blink.elf",
      "gdbPath": "gdb-multiarch",
      "device": "RP2040",
      "configFiles": [
        "interface/cmsis-dap.cfg",
        "target/rp2040.cfg"
      ],
      "openOCDLaunchCommands": [ "adapter speed 5000" ],
      "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
      "runToEntryPoint": "main"
    }
  ]
}

若使用官方 Raspberry Pi Pico VS Code 擴充套件, 它會自動偵測 Debug Probe,選 Debug(F5)即可直接下中斷點除錯。


9. 使用內建 UART 序列埠

Debug Probe 的 U 埠(黃線)接好後,會在電腦出現 /dev/ttyACM0

# minicom
minicom -b 115200 -D /dev/ttyACM0

# 或 screen
screen /dev/ttyACM0 115200

# 或 tio
tio /dev/ttyACM0

在 Pico 程式中用 printf() / stdio_uart 輸出的訊息就會出現在這裡。


10. 常見問題 FAQ

Q1:openocd 找不到裝置 / Error: unable to find CMSIS-DAP device

  • 確認 lsusb 有看到 2e8a:000c
  • 設定第 4.1 節的 udev 權限,或先用 sudo 測試。

Q2:更新韌體時找不到 RPI-RP2 磁碟

  • 確認 lsusb 顯示 2e8a:0003(RP2 Boot)。若有但沒自動掛載, 用 sudo mount 手動掛載,或改用 sudo picotool load

Q3:picotool 顯示 No accessible RP-series devices in BOOTSEL mode

  • Debug Probe 在正常模式下 picotool 讀不到,這是正常的; 只有進入 BOOTSEL(2e8a:0003)後 picotool 才看得到。

Q4:序列埠沒有輸出

  • 檢查 UART 是否交叉接線(Probe TX ↔ 目標 RX)。
  • 確認 baud rate(預設常見為 115200)。

Q5:SWD 連線不穩 / 速度慢

  • 降低 adapter speed(例如 2000)試試,接線越短越穩。
  • 更新到最新韌體(見第 3 節)通常有幫助。

發布 Release(自動附上 .uf2)

本專案有 .github/workflows/release.yml推一個 v* 版本 tag,CI 會自動 編譯 blink(pico + pico2),並建立 GitHub Release、附上以下檔案:

  • blink-pico.uf2 / blink-pico2.uf2(可直接拖進 BOOTSEL)
  • blink-pico.elf / blink-pico2.elf(給 OpenOCD / GDB 除錯)
  • debugprobe-v2.3.1.uf2(Debug Probe 韌體)

發布方式:

git tag v1.0.0
git push origin v1.0.0        # 觸發 release workflow

或到 GitHub 的 Actions → Release → Run workflow,手動輸入 tag 名稱執行。

已存在的 tag 會改為更新該 release 的附件(--clobber),不會重複建立。


附錄:本專案檔案

pico-debug-probe-tutorial/
├── README.md                            # 本教學
├── .github/workflows/
│   ├── build-blink.yml                  # CI:自動編譯 blink(pico / pico2)
│   └── release.yml                      # 推 v* tag 自動發 release 並附上 .uf2
├── docs/
│   ├── openocd.md                       # OpenOCD 深入說明
│   ├── gdb.md                           # GDB 深入說明
│   └── cheatsheet.md                    # 常用指令速查表
├── firmware/
│   ├── debugprobe-v2.3.1.uf2            # 已下載的最新韌體
│   └── flash-probe.sh                   # 自動燒錄腳本(等 BOOTSEL 後自動複製)
├── udev/
│   └── 60-openocd-debugprobe.rules      # 免 sudo 的 USB 權限規則(見 4.1)
└── examples/
    └── blink/                           # 可編譯範例:LED 閃爍 + UART printf
        ├── blink.c
        ├── CMakeLists.txt
        ├── pico_sdk_import.cmake
        ├── .vscode/launch.json          # VS Code (Cortex-Debug) 設定
        └── README.md                    # 範例的編譯→load→除錯步驟

韌體 SHA-256: aae9585f456c28c00865eb3df4d4bfc184f8e7ae60ebed3cc32a32512521a1b8

About

用 Raspberry Pi Debug Probe 升級韌體並除錯 Pico/Pico 2 的繁體中文完整教學(含 blink 範例與 CI)

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages