Raspberry pi pico(以降raspico)にESP32のESPtoolの様に、pico probeを使って量産書き込みをするための環境を作ってみました。「VScode+platformIO版」とポータブル構成でコマンドラインで書き込む「スタンドアロン版」の両方作りました。今回は前者「VScode+PlatformIO版」の覚書です
まあ、作ってみた、といっても大部分AI頼りですが・・・
PlatformIO版OpenOCDを使う。パスを通しておく
openocd.exeはPlatformIO版を使います。まずこれを探します。
VScodeにPlatformIO拡張機能をインストールしてあることが必須で、raspico開発モジュールも必須です。私の環境では下記のパスになりました。バージョンによっても変わる可能性がありますので、ご自分で確認してください。
RP2350対応に関してはmaxgerhardt版のplatform-raspberrypiのインストールも必要かもしれません
C:\Users\<ユーザー名>\.platformio\packages\tool-openocd-rp2040-earlephilhower\binにopenocd.exeがあるのを確認して環境変数に登録しておきます
パスの設定は、PowerShellで
setx OPENOCD_PATH "C:\Users\[ユーザー名]\.platformio\packages\tool-openocd-rp2040-earlephilhower\bin\openocd.exe"
書き込みプログラム専用のフォルダを作る
VScodeで実行するためのフォルダを作ります。フォルダ名は何でも構いませんが私はPicoFlashとし、そこにファームウエアfirmware.elfを置きます(raspico開発ではVScodeのプロジェクトフォルダ\.pio\build\rpipicoにできています)これだけは手動でコピーします
その下にflash_onlyというフォルダを作成します
そのフォルダ構成は
C:.
│ firmware.elf
└─flash_only
│ flash_dual.py
│ platformio.ini
├─.pio
└─.vscode
c_cpp_properties.json
extensions.json
launch.json
tasks.json
VScode上のターミナルでコマンドライン打ち込みで行う分には、.vscodeフォルダやjsonファイルは不要です
platformio.ini
[env:rpipico]
platform = raspberrypi
board = rpipico
framework = arduino
upload_protocol = picoprobe
debug_tool = picoprobe
プログラマ本体「flash_dual.py」
import subprocess
import sys
import os
import shutil
# === ベースディレクトリ ===
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))).replace("\\", "/")
def find_openocd():
local_path = os.path.join(base_dir, "openocd.exe")
if os.path.isfile(local_path):
print(f"✅ ローカル版 OpenOCD 使用: {local_path}")
return local_path
env_path = os.environ.get("OPENOCD_PATH")
if env_path and os.path.isfile(env_path):
print(f"✅ 環境変数版 OpenOCD 使用: {env_path}")
return os.path.abspath(env_path)
which_path = shutil.which("openocd")
if which_path:
print(f"⚠️ PATH上の OpenOCD 使用: {which_path}")
return os.path.abspath(which_path)
print("❌ openocd.exe が見つかりません。")
sys.exit(2)
def find_scripts(openocd_path):
base = os.path.dirname(openocd_path)
candidates = [
os.path.join(base, "scripts"),
os.path.join(base, "share", "openocd", "scripts"),
os.path.join(os.path.dirname(base), "share", "openocd", "scripts"),
os.path.join(base_dir, "scripts"),
]
for c in candidates:
if os.path.isdir(c):
return os.path.abspath(c)
print("⚠️ scripts フォルダが見つかりません。")
sys.exit(3)
# === RP2040 / RP2350 自動判定 ===
def detect_target_chip(openocd, scripts):
print("\n🔍 デバイス自動検出中...")
for name, cfg in [("RP2040", "target/rp2040.cfg"), ("RP2350", "target/rp2350.cfg")]:
cmd_probe = [
openocd,
"-s", scripts,
"-f", "interface/cmsis-dap.cfg",
"-f", cfg,
"-c", "adapter speed 5000", # 安定通信のため低速
"-c", "init; shutdown"
]
result = subprocess.run(cmd_probe, capture_output=True, text=True)
if result.returncode == 0:
print(f"✅ {name} デバイスを検出しました(正常応答)。")
return cfg
else:
print(f"ℹ️ {name} では応答なし(returncode={result.returncode})")
print("⚠️ 自動判定に失敗。RP2040として続行します。")
return "target/rp2040.cfg"
# === 準備 ===
openocd = find_openocd()
scripts = find_scripts(openocd)
firmware = os.path.join(base_dir, "firmware.elf").replace("\\", "/")
# === 自動判定 ===
target_cfg = detect_target_chip(openocd, scripts)
speed = 20000
# === 書き込み ===
cmd_write = [
openocd,
"-s", scripts,
"-f", "interface/cmsis-dap.cfg",
"-f", target_cfg,
"-c", f"adapter speed {speed}",
"-c", f'init; program "{firmware}" verify; reset init; resume; shutdown'
]
print(f"\n=== Programming ({target_cfg.split('/')[-1].replace('.cfg','')}) @ {speed}kHz ===")
result = subprocess.run(cmd_write)
if result.returncode == 0:
print(f"✅ 書き込み+自動再起動完了!({target_cfg})")
else:
print("⚠️ 書き込みに失敗しました。")
sys.exit(result.returncode)
sys.exit(result.returncode)
VScodeでflash_onlyフォルダを開き、コマンドラインで打ち込み。RP2040/RP2350自動判別
VScode上のターミナルで
python flash_dual.py
と打ち込むことで書き込み+自動再起動します。また、RP2040/RP2350は自動判別します
書き込み終了のメッセージは下記

ターゲットも自動再起動します
F5ショートカットキー、F1によるタスクコマンドでも対応
.vscodeフォルダにjsonファイルを作成し格納します。この記事では省略しますが、ご希望の方おられたらメールいただけたら対応します(コメント欄のメッセージでも対応しますが、毎日チェックしておりませんので悪しからず)
pico probeはpico/pico2どちらもOK。当然、公式debug probeでも動く
ただし、現時点ではマルチ書き込み器には対応していないので、probeは一台です