Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 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

💡 建議把 PATHPICO_SDK_PATH 兩行寫進 ~/.bashrc / ~/.zshrc,以後開終端機就自動有。


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