はじめに
slintに興味津々なRust初学者のhermit4です。本格的な勉強を始めるにあたり、Raspberry Pi PicoとRustで遊ぶための環境を用意したいなと思って作業記録をつけておくことにします。OSは個人的な趣味でkubuntu 24.04となります。
なにかツッコミどころ、こうしたほうが効率的、これがおすすめなどあれば、ご意見をコメントしてくだされば助かります。
早速インストール手順
OS環境の追加
sudo apt install build-essential libfontconfig-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libglu1-mesa-dev libudev-dev cmake ninja-build lldb openocd gdb-multiarch curl
ツール郡やslintのビルドで必要になるパッケージ類。
Rustのインストール
Rust環境はUbuntu公式からaptで入れる方法と、rustupから入れる方法の二通りがあります。公式のおすすめ手順ですし、curlからシェルを拾って入れる解説のほうが多いです。ここは素直に従っておきます。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
途中のプロンプトはデフォルトにしておきます。
1) Proceed with standard installation (default - just press enter)
2) Customize installation
3) Cancel installation
>
ターゲットの追加とコンポーネントの追加
. ~/.bashrc
rustup target add thumbv6m-none-eabi
rustup component add rust-analysis rust-src rust-analyzer
外部ツールの追加
cargo install --locked probe-rs-tools elf2uf2-rs flip-link cargo-generate cargo-binutils
probe-rsのセットアップ
wget https://probe.rs/files/69-probe-rs.rules
sudo install -o root -g root -m 644 69-probe-rs.rules /etc/udev/rules.d
sudo udevadm control --reload
Visual Studio Codeのインストール
wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt update
sudo apt install code
Visual Studio Codeのセットアップ
ここからはVisual Studio Codewo起動してVisual Studio Codeでの作業となります。
code
日本語化
英語環境のほうがカッコいいと言う人はskipしてどうぞ
- Ctrl+Shift+P
- displayと入力して出る候補から"Configure Display Language"を選択
- 日本語を選択
- ダイアログでRestartを実行
拡張のインストール
- Ctrl+Shift+X
- rustと入力しrustをインストール(以下の3つの拡張が入る)
- rust-analyzer
- crates
- Rust Syntax
- Debugger for probe-rsと入力してインストール
- tomlと入力してEven Better TOMLをインストール
- CodeLLDBと入力してインストール
- Serial Monitorと入力してインストール
フォーマッタの設定(この辺は好みの問題かな)
- Ctrl+Shift+P
- settingsと入力しユーザー設定を開く(JSON)を選択
{
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true,
"editor.inlayHints.enabled": "off",
"editor.tabSize": 4,
},
"rust-analyzer.rustfmt.rangeFormatting.enable": true,
"rust-analyzer.checkOnSave": true,
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.extraArgs": ["--", "-A", "clippy::needless_return"],
}
とりあえずホストマシンでHello Workd
プロジェクト生成
Ctrl+`でターミナルを開いで以下のコマンドを実行
mkdir devel && cd $_
cargo new hello && code -r $_
Hello Worldを出力するテンプレートが生成されます。
ビルド
- Ctrl+Shift+B
- rust: cargo buildを選択する
launch.jsonの生成(Host実行用LLDB)
- Ctrl+Shift+P
- Debug Add Configと入力しデバッグの構成を選択
- LLDBを選択
実行
- Ctrl+F5
デバッグ実行
- 事前にブレークポイントなどを貼っておく
- F5
本命のRaspberry Pi Pico上でLチカ
Raspberry Pi PicoとDebug Probeを配線する
ここからはRaspberry Pi PicoでのRust準備です。まずは接続します。利用した機材は以下の通り。
Raspberry Pi Debug Probe

Debug Probeはラズベリー財団が出している公式のSWD用のプローブです。SWDとUARTの機能が乗っています。SWDは、ARM Serial Wire Debugの略称で、JTAGの様にバウンダリスキャンなどはできず、単にチップ上のデバッグレジスタに読み書きするだけの簡単な機能を提供されています。
これを使うとデバッガを使ったデバッグが可能になります。
ちなみにUがUARTですが、Uの表記を正面に見て左から
色 | 機能 |
---|---|
橙 | UART TX |
黒 | GND |
黄 | UART RX |
という並びになっています。PicoのUART0はデフォルトで
pin | 機能 |
---|---|
1 | UART RX |
2 | UART TX |
3 | GND |
となっているので、Picoと接続じはちょっと捻って接続する形になります。
SWDの側は、コネクタがついていればそのまま指すだけなので簡単です。コネクタなしでかった場合は、ハンダつけ頑張るしかないでしょうけど。
以下公式の図です。
https://www.raspberrypi.com/documentation/microcontrollers/images/wiring.png
Pico Breadboard Kit
Pico Bread Board Kitはpicoを載せるソケットと、取り出し端子、スイッチ、LED、ブザー、ブレッドボードがセットになったボードです。使わない時はBeepとGNDを短絡しないとブザーが鳴り続けるという欠点はありますが、ちょっとしたお試しには便利です。
手持ちのPicoはWHで、オンボードLEDはライブラリを使わないとチカチカできないので、今回はGPIO-15と外部のLED1を結線して利用します。
Raspberry Pi Pico向けにプロジェクトを作る
- Ctrl+K F でフォルダを閉じる
- Ctrl+` でターミナルを開く
- ターミナルでプロジェクト作成を実行
cd devel
cargo generate --git https://github.com/rp-rs/rp2040-project-template --branch main --name pico-hello && code -r $_
probe-rsを使うので、フラッシュはprobe-rsを選択しておく。
cargo generateはネット上のテンプレートをベースに新しいプロジェクトを生成します。生成されたrp-rsのテンプレートはオンボードLED(GPIO25)のLチカコードになっています。こちらをGPIO15に変更します。
- let mut led_pin = pins.led.into_push_pull_output();
+ let mut led_pin = pins.gpio15.into_push_pull_output();
まずはコマンドラインでの確認
Debug Probeの認識
probe-rs list
The following debug probes were found:
[0]: Debug Probe (CMSIS-DAP) -- 2e8a:000c:nnnnnnnnnnnnnnnnn (CMSIS-DAP)
実行確認
cargo run
cargo runはビルドして、probe-rs経由でフラッシュして、実行を開始してくれます。
Visual Studio Codeからの実行・デバッグ
Host上での実行と同じくlaunch.jsonの設定が必要です。
- Ctrl+Shift+P
- Debug Add Configと入力しデバッグの構成を選択
- エラーになるものも含まれてるっぽいので、minimam設定になるように編集(programBinaryはプロジェクトに合わせて修正)
{
"version": "0.2.0",
"configurations": [
{
"preLaunchTask": "rust: cargo build",
"type": "probe-rs-debug",
"request": "launch",
"name": "rp2040-project",
"chip": "rp2040",
"connectUnderReset": false,
"flashingConfig": {
"flashingEnabled": true,
},
"coreConfigs": [
{
"programBinary": "target/thumbv6m-none-eabi/debug/pico-hello",
}
],
"consoleLogLevel": "Info", //Error, Warn, Info, Debug, Trace
"wireProtocol": "Swd"
}
]
}
これで、適当にブレークポイントをはってF5でデバッグ実行すれば、ソースコードを見ながらデバッグが可能になります。なお、停めたい場所でうまくブレークポイントが設定できないとか、止まらない場合は、cargo.tomlのopt-levelを見直してください。0にすれば止まるようになるかと思います。
ついでなのでUARTも試しておきましょう
#![no_std]
#![no_main]
use bsp::entry;
use bsp::hal::fugit::RateExtU32;
use defmt::*;
use defmt_rtt as _;
use embedded_hal::digital::OutputPin;
use panic_probe as _;
use rp_pico as bsp;
use bsp::hal::{
clocks::{init_clocks_and_plls, Clock},
pac,
sio::Sio,
uart::{DataBits, StopBits, UartConfig},
watchdog::Watchdog,
};
#[entry]
fn main() -> ! {
info!("Program start");
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let sio = Sio::new(pac.SIO);
let external_xtal_freq_hz = 12_000_000u32;
let clocks = init_clocks_and_plls(
external_xtal_freq_hz,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
let pins = bsp::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
let mut led_pin = pins.gpio15.into_push_pull_output();
let uart_pins = (pins.gpio0.into_function(), pins.gpio1.into_function());
let uart = bsp::hal::uart::UartPeripheral::new(pac.UART0, uart_pins, &mut pac.RESETS)
.enable(
UartConfig::new(9600.Hz(), DataBits::Eight, None, StopBits::One),
clocks.peripheral_clock.freq(),
)
.unwrap();
uart.write_full_blocking(b"Hello World!\n");
loop {
info!("on!");
led_pin.set_high().unwrap();
delay.delay_ms(500);
info!("off!");
led_pin.set_low().unwrap();
delay.delay_ms(500);
}
}
HALに便利なAPIが既にあるので、ピンを設定して、コンフィグレーションを指定して、そこに書き込むだけです。
UARTを9600Hzで設定したので、Visual Studio Codeのシリアルモニターをその様に設定して監視してF5でプログラムを実行します。書き込みを指定したHello Worldが出力されれば成功です。
簡単ですね。
2024/07/10 追記
probe-rsですが、templateからgenerateしたわけではない場合どうしたらよいのかというと、実際の設定は、project/.cargo/config.tomlに以下のように設定されます。
runner = "probe-rs run --chip RP2040 --protocol swd"
設定ファイルは
- projects/hoge/fuga/piyo/.cargo/config.toml
- projects/hoge/fuga/.cargo/config.toml
- projects/hoge/.cargo/config.toml
- projects/.cargo/config.toml
- .cargo/config.toml
- $HOME/.cargo/config.toml
と探索されていきます。pico向けにslintのデモとかを動かしたりカスタマイズしたりな人とかは
[target.thumbv6m-none-eabi]
runner = "probe-rs run --chip RP2040 --protocol swd"
とかしておくと楽になるのかもしれませんね。
まとめ
というわけで、備忘録がてらすごくざっくりVisual Studio CodeでDebug Probeを使ったデバックも可能なシリアル監視付き開発環境を構築しました。ま、こんなのでも残しておけば誰かの役には立つかもしれませんということで。
今後はつなげるデバイスを増やしつつ学習を続けていく予定です。