の続きです。Raspberry Pi Pico(以下Pico)をWSLのコマンドラインでgdbを使ってデバッグできるようになったので、今度はこれをVisual Studio Codeから使えるようにします。
実は現時点ではまだ不完全な点があって、事前にブレークポイントを置いてそこに止めることはできる一方で、実行中のプログラムを停止させることができていません(コマンドラインでgdbを使う際は普通にCtrl+Cで止まるのに…)。
とは言え、VSCodeのGUI上でのデバッグができると便利なことは確かなので、不完全ではありますが情報として公開したいと思います。
(実行環境のWSLはWSL2を前提としています。WSL1の場合はWindows側のIPアドレスを指定している箇所を削除するなどすれば動くと思います)
実行前の準備
- 以下のシェルスクリプトを
gdb-pico
というファイル名でパスの通った箇所に置きます。
(ここ で書いたものから少しだけ変わっています)
gdb-pico
# !/bin/sh
killall -q gdb-multiarch
gdb-multiarch -ex "target remote `tail -1 /etc/resolv.conf|awk '{print $2}'`:3333" $*
- Pico SDKで動かすプログラムのあるフォルダをVSCodeのRemote WSLでワークスペースとして開き、そのルートに
.vscode
というフォルダを作成して以下のファイルlaunch.json
を置きます。- (pico-examplesの場合は pico-examples/.vscode/launch.json)
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb)",
"type": "cppdbg",
"request": "launch",
"targetArchitecture": "arm",
"program": "${workspaceFolder}/build/${relativeFileDirname}/${fileBasenameNoExtension}.elf",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"MIMode": "gdb",
"miDebuggerPath": "${env:HOME}/bin/gdb-pico",
"launchCompleteCommand": "exec-continue",
"setupCommands": [
{
"text": "load ${workspaceFolder}/build/${relativeFileDirname}/${fileBasenameNoExtension}.elf"
}
]
}
]
}
VSCodeでのデバッグ
- WSLのシェルから以下のコマンドを実行しておきます。
openocd.exe -f interface/picoprobe.cfg -f target/rp2040.cfg -c 'bindto 0.0.0.0'
- VSCodeでデバッグしたいアプリをビルドしておき、そのソースコード (ここではblink/blink.c) を開きます。
-
main()
の最初の行の行番号の左をクリックして、ブレークポイントを置きます(赤い丸が付く)。 -
F5
または実行(R)
-デバッグの開始
で、gdbが動いて事前に実行していたopenocdに接続し、ブレークポイントに止まることでデバッグを開始します。
- ブレークポイントを置かずに
続行(F5)
すると止められなくなってしまうことだけ注意が必要ですが、その他通常のデバッグ操作は普通にできます。- 続行するとgdbがVSCodeの制御を離れて動きっぱなしになってしまうのですが、停止して再度デバッグを開始する際は、
gdb-pico
スクリプトに入れたkillallで削除されるようにしています。
- 続行するとgdbがVSCodeの制御を離れて動きっぱなしになってしまうのですが、停止して再度デバッグを開始する際は、
(おまけ) cmake/make等を行うtasks.json
Getting StartedではVSCodeを使う際はCMake Tools機能拡張を使うように書いてありますが、私は以下のようなtasks.json
を.vscode
に置いて使っています。
ソースコードを開いてCtrl+Shift+B
またはターミナル
-ビルド タスクの実行
で以下の内容を実行することができます。
- cmake
- プロジェクトのルートにbuild/ディレクトリを掘ってcmakeを実行します
- distclean
- build/ディレクトリを削除します
- make
- make (verbose)
- 開いているソースコードのアプリをビルドします
- clean
- ビルドの生成物を削除します
- install
- ビルドでできた*.uf2ファイルをPicoにインストールします。以下の記事で説明した
pico-install
スクリプトを用意してパスを通しておく必要があります
- ビルドでできた*.uf2ファイルをPicoにインストールします。以下の記事で説明した
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "make",
"type": "shell",
"command": "make -j4",
"options": {
"cwd": "${workspaceFolder}/build/${relativeFileDirname}"
},
"presentation": {
"revealProblems": "onProblem"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
},
{
"label": "make (verbose)",
"type": "shell",
"command": "make VERBOSE=1",
"options": {
"cwd": "${workspaceFolder}/build/${relativeFileDirname}"
},
"presentation": {
"revealProblems": "onProblem"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
},
{
"label": "clean",
"type": "shell",
"command": "make clean",
"options": {
"cwd": "${workspaceFolder}/build/${relativeFileDirname}"
},
"problemMatcher": [],
"group": "build"
},
{
"label": "install",
"type": "shell",
"command": "pico-install",
"args": [
"*.uf2"
],
"options": {
"cwd": "${workspaceFolder}/build/${relativeFileDirname}"
},
"problemMatcher": [],
"group": "build"
},
{
"label": "distclean",
"type": "shell",
"command": "rm -rf ${workspaceFolder}/build",
"problemMatcher": [],
"group": "build"
},
{
"label": "cmake",
"type": "shell",
"command": "mkdir build; (cd build; cmake .. -DCMAKE_BUILD_TYPE=${input:buildType} -DPICO_DEFAULT_BINARY_TYPE=${input:binaryType})",
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [],
"group": "build"
},
],
"inputs": [
{
"type": "pickString",
"id": "buildType",
"description": "Build Type",
"options": [
"Release",
"Debug"
],
"default": "Debug"
},
{
"type": "pickString",
"id": "binaryType",
"description": "Binary Type",
"options": [
"default",
"no_flash",
"copy_to_ram",
"blocked_ram"
],
"default": "default"
}
]
}