defmt + RTT でデバッグログを出力する
組み込み開発では println! や標準出力が使えないため、デバッグログの仕組みを別途用意する必要があります。defmt(delayed formatting)と RTT(Real-Time Transfer)を組み合わせると、帯域を節約しながら高速にログをホスト PC に転送できます。
必要なクレート
Section titled “必要なクレート”| クレート | 役割 |
|---|---|
defmt | 高効率なログフォーマット(バイナリ側) |
defmt-rtt | RTT バックエンド(probe 経由でホストへ) |
panic-probe | panic 時に defmt 経由で情報を出力 |
Cargo.toml の設定
Section titled “Cargo.toml の設定”[dependencies]defmt = "1"defmt-rtt = "1"panic-probe = { version = "1", features = ["print-defmt"] }
[profile.release]debug = 2debug = 2 を指定することで、リリースビルドでも defmt のシンボル情報が保持されます。
ログマクロの使用
Section titled “ログマクロの使用”#![no_std]#![no_main]
use {defmt_rtt as _, panic_probe as _};
#[cortex_m_rt::entry]fn main() -> ! { defmt::info!("システム起動");
let value: u32 = 42; defmt::debug!("センサ値: {}", value);
loop {}}| マクロ | 用途 |
|---|---|
defmt::trace! | 詳細なトレース情報 |
defmt::debug! | デバッグ用情報 |
defmt::info! | 一般的な情報 |
defmt::warn! | 警告 |
defmt::error! | エラー |
ログの読み取り
Section titled “ログの読み取り”probe-rs を使う場合
Section titled “probe-rs を使う場合”# ログをリアルタイムで表示probe-rs run --chip STM32F401CCU6 target/thumbv7em-none-eabihf/release/firmwarecargo run を使う場合(runner 経由)
Section titled “cargo run を使う場合(runner 経由)”# defmt ログを表示しながら実行cargo run --releaseフィルタリング
Section titled “フィルタリング”Cargo.toml または環境変数でログレベルをフィルタできます。
# 環境変数で制御(モジュールごとも可能)DEFMT_LOG=debug cargo run --releasedefmt の仕組み
Section titled “defmt の仕組み”従来の文字列フォーマット(format!)は文字列全体をターゲットに保持しますが、defmt はフォーマット文字列をホスト側に置き、引数のみをバイナリで転送します。これにより:
- フラッシュメモリの消費を大幅に削減
- 転送データ量を最小化
{:?}デバッグフォーマットもコンパイル時に処理
トラブルシューティング
Section titled “トラブルシューティング”ログが表示されない
Section titled “ログが表示されない”DEFMT_LOG環境変数でレベルが十分か確認defmt-rttが dependencies に含まれているか確認- probe の接続状態を確認
ビルドエラー: multiple defmt logger
Section titled “ビルドエラー: multiple defmt logger”defmt-rtt と別のロガー(defmt-itm 等)が同時に有効になっていないか確認してください。
次のステップ
Section titled “次のステップ”- probe-rs のセットアップ でデバッグ環境を整える
- Embassy で L チカ で実践的なコードを試す