TL

ファームウェアデバッグ(JTAG・SWD)

printfを仕込めない・動かないファームの原因を、実機を止めて中身を覗いて突き止める術がわかる。JTAG/SWDでのブレーク、レジスタ・メモリ参照、ITM/ETMトレースまで、オンチップデバッグの仕組みを原理から押さえる。

応用組込みデバッグJTAGSWDトレースARM Cortex-M最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.JTAG/SWDはCPUコアに組み込まれたデバッグ回路をデバッガから操作するプロトコル。プログラムを止めずに実機のレジスタ・メモリを読み書きでき、printfを仕込めない起動直後や割り込み文脈も追える。
  • 2.ハードウェアブレークポイントはFlash上のコードにも仕掛けられる有限個の比較器、ウォッチポイントは特定アドレスへのアクセスで止まる仕組み。ソフトブレークと違いROMを書き換えない。
  • 3.ITMは低コストなprintf代替、ETMは全命令フローを外部へ吐く高機能トレース。実行を止めずに時系列を観測でき、タイミング依存や割り込み絡みの不具合に強い。

実機を「止めて覗く」という発想

PCのプログラムはOSとデバッガが協調し、ブレークポイントで止め、変数を覗き、一歩ずつ進められます。ところがマイコン(MCU)上のファームウェアには、その足場となるOSがありません。起動直後のスタートアップコードや割り込みハンドラの中では、まだ通信ペリフェラルすら初期化されておらず、printf を一行仕込むことさえできない——にもかかわらず、そこで止まって動かない、というのが組込みデバッグの日常です。

これを解決するのが オンチップデバッグ です。近年のMCUはCPUコアの内部に専用のデバッグ回路を内蔵しており、外部のデバッガ(デバッグプローブ)から数本の信号線でその回路を直接操作できます。この操作の口が JTAGSWD です。ファーム側に一切の細工を入れずとも、実行中のコアを任意の瞬間に停止させ、レジスタやメモリを直接読み書きできる——ソフトウェアの助けを借りずハードウェアで覗く、この発想が本稿の核心です。前提となるベアメタルの起動フローは /embedded/bare-metal-firmware/ を参照してください。

JTAGとSWD:デバッグ回路への配線

JTAG(Joint Test Action Group、IEEE 1149.1)はもともと基板の配線検査(バウンダリスキャン)向けに作られた規格で、TCK・TMS・TDI・TDO・(任意のTRST)という信号線を使い、複数チップを数珠つなぎ(デイジーチェーン)にして操作します。このシリアルの経路を使ってコアのデバッグレジスタへアクセスできるため、デバッグの標準インタフェースとしても広く使われてきました。

一方 SWD(Serial Wire Debug)はArmがCortex系向けに定めた2線式のインタフェースで、クロックのSWCLKと双方向データのSWDIOだけで同等のデバッグ機能を提供します。ピン数の少ないMCUで貴重なI/Oを節約でき、Cortex-Mでは事実上の標準です。JTAGとSWDは同じデバッグ回路(コアのデバッグポート)への異なる入口であり、多くのチップは両対応でピンを共用します。

観点JTAGSWD
信号線数TCK/TMS/TDI/TDO(+TRST)で4〜5本SWCLK/SWDIOの2本
多チップ接続デイジーチェーンで複数を数珠つなぎ1ターゲットが基本(マルチドロップで選択)
トレース連携TDO流用は低速SWO 1本でITMトレースを出せる
主な用途汎用・基板検査・非Arm含む広範Cortex系のピン節約デバッグ

信号の先にあるのは DP(Debug Port)とAP(Access Port) という階層です。DPがJTAG/SWDの物理層を受け、その先のAP(代表がMEM-AP)がチップ内部のバスに橋渡しします。デバッガはこのMEM-AP経由でメモリ空間の任意アドレスを読み書きし、CPUが止まっていてもフラッシュの内容やペリフェラルレジスタを覗けます。ペリフェラルレジスタがアドレス空間に見える仕組みは /embedded/memory-mapped-io/ を前提とします。

コアの停止・再開とレジスタ/メモリ参照

デバッグの基本操作は halt(停止)/run(再開)/step(単一ステップ) です。デバッガがコアのデバッグ制御レジスタへ停止要求を書くと、コアは実行中の命令を区切りのよいところまで進めて デバッグ状態 に入り、パイプラインを止めます。この状態では、汎用レジスタ・スタックポインタ・プログラムカウンタ・ステータスレジスタといったCPU内部の値をデバッガが直接読み出せます。「今どの行で、変数は何を指しているか」がこの参照で判明します。

メモリ参照はMEM-AP経由でバスへアクセスするため、コアが止まっていても、あるいは走ったままでも 行える点が強力です。走行中に周期的にあるアドレスを読み続ければ、実行を妨げずにセンサ値の推移を観測できます(後述のライブウォッチ)。単一ステップは、1命令だけ実行して即座に停止状態へ戻る操作で、内部的には「次の命令実行後に停止」を仕込んで再開する形で実現されます。

[デバッガによるhalt→参照→再開の流れ]

  デバッガ ──SWD/JTAG──> DP ──> MEM-AP ──> コア/バス

  1. halt要求を書く        → コアがデバッグ状態へ(PC・レジスタが凍結)
  2. コアレジスタを読む     → R0..R15, xPSR などの現在値を取得
  3. 任意アドレスを読む     → 変数・スタック・ペリフェラルレジスタを参照
  4. 値を書き換える(任意)   → 変数注入・レジスタ書換えでシナリオ再現
  5. step / run で再開      → 1命令だけ / 通常実行へ復帰
デバッガが止まっても割り込みタイマは動き続けることがある

コアを止めると、そのコアの命令実行は凍結されますが、独立して動くペリフェラル(タイマ、通信、DMA)はハード側で走り続ける設定のこともあります。停止中にタイマが満了しカウンタが溢れる、ウォッチドッグがリセットをかける、といった副作用が起こり得ます。多くのデバッガはブレーク時にウォッチドッグやタイマを一時停止させるオプション(デバッグ時フリーズ)を持つので、意図せぬリセットに悩んだらここを確認します。ウォッチドッグの原理は /embedded/watchdog-timer/ を参照。

ブレークポイントとウォッチポイント

ブレークポイント は「指定アドレスの命令を実行しようとしたら止まる」仕掛けで、実装は2種類あります。ソフトウェアブレークポイント は、対象命令を専用のブレーク命令(Cortex-Mなら BKPT)に一時的に書き換え、実行が到達すると例外的に停止状態へ入る方式です。命令を書き換えるためRAM上のコードには何個でも置けますが、Flash上のコードには使えません(Flashは1バイト単位で即書き換えできない)。

そこで起動直後のROMコードを止めるのに要るのが ハードウェアブレークポイント です。これはコア内蔵の比較器(Cortex-MではFPB=Flash Patch and Breakpoint)にアドレスを設定し、フェッチしたアドレスが一致した瞬間に停止させる方式で、コードを一切書き換えません。ただし比較器の数は有限(数個程度)で、これがハードブレークを置ける個数の上限になります。

ウォッチポイント(データブレークポイント) は視点が逆で、「特定アドレスへの読み書きが起きたら止まる」仕掛けです。Cortex-MではDWT(Data Watchpoint and Trace)ユニットの比較器を使い、あるグローバル変数が いつ・どのコードから 書き換えられたかを捕まえられます。原因不明の変数破壊——たとえば /embedded/interrupt-handling-isr/ で扱う競合状態や、配列外書き込みによるスタック破壊——の犯人を、書き込んだ瞬間で現行犯逮捕できるのが最大の武器です。

変数が壊れる不具合はまずウォッチポイント

「この変数がいつの間にか不正値になる」類の再現困難なバグは、値を後追いで調べても遅すぎます。当該アドレスにwrite型のウォッチポイントを張れば、書き換えた命令でコアが止まり、そのときのコールスタックとPCから犯人コードが即座に判明します。ブレークポイントが「どこで実行が来たか」を捉えるのに対し、ウォッチポイントは「どこでデータが変わったか」を捉える——両者を使い分けるのがデバッグ効率を分けます。

トレース:止めずに時系列を観る(ITM/ETM)

ブレークポイントは実行を止めてしまうため、モータ制御や通信のように 止めると状態が壊れる/タイミングが変わって再現しなくなる 不具合には無力です。そこで実行を止めずに内部の出来事を外部へ吐き出すのが トレース で、Cortex-Mでは主にITMとETMの2系統があります。

ITM(Instrumentation Trace Macrocell)は、ファームからレジスタへ書き込んだデータをタイムスタンプ付きで外部へ流す仕組みです。用途の花形が printfの代替 で、printf がUARTを占有し数百サイクルを食うのに対し、ITMは1ワード書くだけで済み、実行への影響(プローブ効果)が小さいのが利点です。出力はSWDと併用する SWO(Serial Wire Output)1本(JTAGのTDOピンを流用)でホストへ送れます。DWTと組み合わせれば、一定周期でPCの値をサンプリングして実行時間の偏りを可視化する プロファイリング にも使えます。

ETM(Embedded Trace Macrocell)はさらに強力で、CPUが実行した命令フローそのもの(分岐の履歴)を圧縮して外部へ連続出力します。これを専用の高速並列ポート(TPIU経由のトレースポート)や高速シリアルで受ければ、後から 実行を1命令単位で遡って再生 でき、「クラッシュ直前に何をどう通ったか」を完全に再構成できます。帯域が大きいぶん専用ピンと対応プローブが要り、ITMより高価です。

観点ITMETM
観測対象ファームが明示的に書いた値・イベント全命令の実行フロー(分岐履歴)
出力経路SWO 1本(低帯域で済む)並列トレースポート等(高帯域)
主な使い道printf代替・イベント記録・軽量プロファイル完全な実行再生・網羅的解析
コスト安価・追加ピンほぼ不要対応プローブとピンが必要で高価
観測が挙動を変える「プローブ効果」に注意

デバッグ手段は多かれ少なかれ対象の実行に影響します。printf は数百サイクルを消費してタイミングを崩し、割り込み間隔ぎりぎりの処理をあっさり破綻させます。ブレークで止めれば通信相手はタイムアウトします。トレース(特にITM)はこの影響が小さいため、タイミング依存の不具合ほどトレース系が有利です。「デバッグコードを入れたら直る/外すと再現する」という現象は、多くがこのプローブ効果——観測がタイミングを変えたことによるものだと疑ってください。

printfデバッグとの併用戦略

オンチップデバッグとprintfは対立するものではなく、得意分野が違う道具です。実務では両者を状況で使い分けます。ロジックの分岐や変数の値を腰を据えて追うなら、ブレークで止めてレジスタ・メモリを覗くのが確実です。一方、割り込みの発生順序や状態遷移の時系列、まれにしか起きない事象の記録には、止めずに流れを残せるITM(あるいはリングバッファへのログ蓄積)が向きます。

とりわけ 止められない領域 ——モータやインバータの制御ループ、通信のリアルタイム応答、ブートローダからアプリへの遷移(/embedded/bootloader-ota-update/ 参照)——では、ブレークが状態を壊すためトレースやログが主役になります。逆に、ハードフォルト後にコアが停止した状態からスタックを遡って原因アドレスを特定するような 事後解析 は、halt後のメモリ参照の独壇場です。

資格・面接で問われる勘どころ

「JTAGとSWDの違い」は『JTAGは4〜5線でデイジーチェーン可・汎用、SWDは2線でCortex系のピン節約版、どちらも同じデバッグ回路への入口』。「ハードとソフトのブレークポイントの違い」は『ソフトは命令をBKPTに書き換えるためFlash上コードに使えず個数無制限、ハードは比較器でアドレス一致検出しROMを書き換えないが個数有限』。「ウォッチポイントの用途」は『特定アドレスへのアクセスで停止させ、変数破壊の書き込み元を特定する』。「ITMとETMの違い」は『ITMは明示的に書いた値の軽量トレース(printf代替)、ETMは全命令フローの完全トレース』と押さえます。

まとめ

  • オンチップデバッグはCPUコア内蔵のデバッグ回路を外部プローブから操作する技術で、OSやprintfが使えない起動直後・割り込み文脈でも実機を止めて覗ける。
  • JTAG(4〜5線・汎用・デイジーチェーン)と SWD(2線・Cortex系のピン節約)は同じデバッグ回路への異なる入口で、DP→APを介してメモリ空間へアクセスする。
  • halt/run/step でコアを制御し、止まった状態でレジスタ・メモリを参照する。MEM-AP経由の参照は走行中でも可能。
  • ハードウェアブレークポイントは比較器でアドレス一致を検出しROMを書き換えない(個数有限)。ソフトブレークは命令をBKPTに書き換える(Flash不可・個数無制限)。ウォッチポイントはアドレスへのアクセスで止め、変数破壊の犯人を捕まえる。
  • ITMは軽量なprintf代替・イベントトレース(SWO 1本)、ETMは全命令フローの完全トレース。止めずに時系列を観られるため、タイミング依存や割り込み絡みの不具合に強い。
  • ブレーク系とトレース系、そしてprintfは対立せず、止めてよい局面と止められない局面で使い分けるのが実務の要諦。関連する起動・割り込み・I/Oの基礎は /embedded/bare-metal-firmware//embedded/interrupt-handling-isr//embedded/memory-mapped-io/ を参照。

組込み・IoT Article

ファームウェアデバッグ(JTAG・SWD)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

組込み

比較で見る軸

難易度: advanced / カテゴリ: 組込み・IoT / タグ数: 6

導入後に効く点

ハードウェアブレークポイントはFlash上のコードにも仕掛けられる有限個の比較器、ウォッチポイントは特定アドレスへのアクセスで止まる仕組み。ソフトブレークと違いROMを書き換えない。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
組込み・IoT
タグ数
6

判断チェックリスト

  • 自社の用途が「組込み / デバッグ」に近いか確認する。
  • 強みである「JTAG/SWDはCPUコアに組み込まれたデバッグ回路をデバッガから操作するプロトコル。プログラムを止めずに実機のレジスタ・メモリを読み書きでき、printfを仕込めない起動直後や割り込み文脈も追える。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

組込みデバッグJTAGSWDトレース組込みデバッグJTAG