コンテンツにスキップ

defmt + RTT でデバッグログを出力する

組み込み開発では println! や標準出力が使えないため、デバッグログの仕組みを別途用意する必要があります。defmt(delayed formatting)と RTT(Real-Time Transfer)を組み合わせると、帯域を節約しながら高速にログをホスト PC に転送できます。

クレート役割
defmt高効率なログフォーマット(バイナリ側)
defmt-rttRTT バックエンド(probe 経由でホストへ)
panic-probepanic 時に defmt 経由で情報を出力
[dependencies]
defmt = "1"
defmt-rtt = "1"
panic-probe = { version = "1", features = ["print-defmt"] }
[profile.release]
debug = 2

debug = 2 を指定することで、リリースビルドでも defmt のシンボル情報が保持されます。

#![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!エラー
Terminal window
# ログをリアルタイムで表示
probe-rs run --chip STM32F401CCU6 target/thumbv7em-none-eabihf/release/firmware

cargo run を使う場合(runner 経由)

Section titled “cargo run を使う場合(runner 経由)”
Terminal window
# defmt ログを表示しながら実行
cargo run --release

Cargo.toml または環境変数でログレベルをフィルタできます。

Terminal window
# 環境変数で制御(モジュールごとも可能)
DEFMT_LOG=debug cargo run --release

従来の文字列フォーマット(format!)は文字列全体をターゲットに保持しますが、defmt はフォーマット文字列をホスト側に置き、引数のみをバイナリで転送します。これにより:

  • フラッシュメモリの消費を大幅に削減
  • 転送データ量を最小化
  • {:?} デバッグフォーマットもコンパイル時に処理
  1. DEFMT_LOG 環境変数でレベルが十分か確認
  2. defmt-rtt が dependencies に含まれているか確認
  3. probe の接続状態を確認

defmt-rtt と別のロガー(defmt-itm 等)が同時に有効になっていないか確認してください。