概要
インサーキットデバッガ(In-Circuit Debugger:ICD、またはIn-Circuit Emulator:ICEの現代版)とは、動作中の組み込みシステム(実回路)に接続し、プログラムの実行を制御・監視するデバッグ装置である。PCなどのホスト環境とターゲットデバイス(マイコン)の間に接続し、ブレークポイントでの停止、ステップ実行、レジスタやメモリの読み書きなどを実現する。
組み込み開発でのデバッグは、一般的なPCアプリ開発と異なり、デバッガを直接ターゲットで動かすことが難しいため、外部のデバッグ装置を使ったハードウェアレベルのデバッグが必要になる。インサーキットデバッガは、このギャップを埋める不可欠なツールである。
現代の主流はJTAG(Joint Test Action Group)またはSWD(Serial Wire Debug)インターフェースを介して接続するプローブ型のデバッガである。
歴史・背景
1980年代〜1990年代の初期には、ICE(In-Circuit Emulator)と呼ばれる装置が使われていた。ICEはターゲットMCUと同じCPUコアをデバッグ装置に内蔵し、ターゲット基板のMCUソケットに差し込んで動作を完全に模倣・制御するものだった。高精度だが非常に高価(数百万円)で、MCUを完全に置き換えるため、デバイスのパッケージや配線に制約が生じた。
JTAGインターフェース(IEEE 1149.1、1990年)の普及により、ICEは廃れ、MCU内部のデバッグロジック(ARM CoreSightなど)をJTAG経由で制御する小型・低価格のデバッグプローブが主流となった。
ARMがSWD(Serial Wire Debug)を導入したことで、ピン数の少ない小型マイコンでも2本の信号線でデバッグが可能になり、2000年代以降のCortex-Mマイコンの普及とともに一般化した。
現在では数千円〜数万円のデバッグプローブが広く販売されており、オープンソースのOpenOCDにより多様なプローブとMCUの組み合わせをサポートしている。
技術仕様
主要なインサーキットデバッガの比較
| デバッガ | 接続方式 | 速度 | 価格 | 特徴 |
|---|---|---|---|---|
| SEGGER J-Link BASE | JTAG/SWD | 最高速 | ~3万円 | 業界標準、最も広くサポート |
| SEGGER J-Link EDU | JTAG/SWD | 高速 | ~8千円 | 教育・非商用向け |
| ST-Link V3 | JTAG/SWD | 高速 | ~4千円 | STM32専用、公式プローブ |
| CMSIS-DAPプローブ各種 | JTAG/SWD | 中速 | 数百円〜 | オープン規格、多種あり |
| NXP LPC-Link2 | JTAG/SWD | 中速 | ~3千円 | NXP公式 |
| PICkit 4 | ICSP/JTAG | 中速 | ~7千円 | Microchip PIC/AVR向け |
| ESP-Prog | JTAG | 中速 | ~3千円 | ESP32向け |
| Black Magic Probe | JTAG/SWD | 中速 | ~1万円 | GDBサーバを内蔵 |
| Raspberry Pi Debug Probe | SWD/UART | 中速 | ~1200円 | Raspberry Pi Pico向け |
JTAG/SWD接続の信号線
JTAG(5ピン):
| ピン | 信号名 | 方向 | 説明 |
|---|---|---|---|
| 1 | TDI | ホスト→ターゲット | テストデータ入力 |
| 2 | TDO | ターゲット→ホスト | テストデータ出力 |
| 3 | TCK | ホスト→ターゲット | テストクロック |
| 4 | TMS | ホスト→ターゲット | テストモード選択 |
| 5 | nTRST | ホスト→ターゲット | テストリセット(オプション) |
SWD(2ピン):
| ピン | 信号名 | 説明 |
|---|---|---|
| 1 | SWDIO | 双方向データ |
| 2 | SWDCLK | クロック |
SWDはJTAGを2ピンに簡略化したARMの独自規格で、小型マイコンのデバッグに適している。
動作原理
デバッグシステムの全体構成
[ホストPC]
IDE/GDB
|
| USB
|
[デバッグプローブ]
(J-Link/ST-Link等)
|
| JTAG/SWD
|
[ターゲットMCU]
┌────────────────────────┐
│ CPU Core │
│ ┌──────────────────┐ │
│ │ ARM CoreSight │ │
│ │ デバッグロジック │ │
│ │ ・ブレークポイント│ │
│ │ ・ウォッチポイント│ │
│ │ ・ステップ実行 │ │
│ └──────────────────┘ │
│ Flash / RAM / Periph │
└────────────────────────┘
OpenOCDによるデバッグサーバの仕組み
OpenOCD(Open On-Chip Debugger)は、デバッグプローブとGDBの間を仲介するオープンソースのデバッグサーバである:
GDB (arm-none-eabi-gdb)
|
| GDBリモートシリアルプロトコル (TCP:3333)
|
OpenOCD (デバッグサーバ)
|
| USB (libusb)
|
J-Link / ST-Link
|
| JTAG/SWD
|
ターゲットMCU
OpenOCDの設定ファイル例(STM32F4 + ST-Link):
# openocd.cfg
# デバッグプローブの設定
source [find interface/stlink.cfg]
# ターゲットMCUの設定
source [find target/stm32f4x.cfg]
# フラッシュ速度の設定
adapter speed 4000
# リセット設定
reset_config srst_only
# OpenOCDの起動
openocd -f openocd.cfg &
# GDBで接続
arm-none-eabi-gdb firmware.elf
(gdb) target remote localhost:3333 # OpenOCDに接続
(gdb) monitor reset halt # ターゲットをリセットして停止
(gdb) load # ファームウェアをフラッシュに書き込み
(gdb) break main # main関数にブレークポイント
(gdb) continue # 実行開始
ハードウェアブレークポイントの仕組み
ARM Cortex-MではFPB(Flash Patch and Breakpoint)ユニットが最大8個のハードウェアブレークポイントを提供する。ハードウェアブレークポイントはコードの改変なしに動作するため、フラッシュ上の任意のアドレスに設定できる:
FPB Unit
├── COMP0: 0x08001234 ← ここでブレーク(main()の先頭)
├── COMP1: 0x08002000 ← ここでブレーク(interrupt handler)
└── ... (最大8個)
実行時: CPUがCOMP0に達すると自動的にホルトし、デバッガに通知
用途・ユースケース
開発中のデバッグ(最も一般的):
# VS Code + Cortex-Debug拡張での操作例
# F5でデバッグ開始 → ブレークポイントで自動停止
# 変数ウォッチウィンドウで実行時の変数値を確認
# ペリフェラルビューでGPIO/タイマレジスタの値を確認
フラッシュメモリへの書き込み:
# OpenOCDを使ったフラッシュ書き込み
openocd -f openocd.cfg \
-c "program firmware.elf verify reset exit"
# J-Link Commanderを使った書き込み
JLinkExe -device STM32F407VG -if SWD -speed 4000 \
-CommandFile flash.jlink
SWO/ITMトレースによるリアルタイムログ:
ARM Cortex-MのSWO(Serial Wire Output)ピンを使うことで、printf相当のログ出力をリアルタイムに受信できる(UART不要):
// ITM(Instrumentation Trace Macrocell)経由でログ出力
void ITM_SendChar(uint32_t ch) {
if ((ITM->TCR & ITM_TCR_ITMENA_Msk) &&
(ITM->TER & (1UL << 0))) {
while (ITM->PORT[0].u32 == 0);
ITM->PORT[0].u8 = (uint8_t)ch;
}
}
// printf をITM経由にリダイレクト
int _write(int fd, char *ptr, int len) {
for (int i = 0; i < len; i++) {
ITM_SendChar(*ptr++);
}
return len;
}
量産工程でのフラッシュプログラミング:
製品製造時にJ-Linkなどを使って自動でファームウェアを書き込む:
#!/bin/bash
# 量産ライン向けフラッシュスクリプト
jlink_script="
connect
loadfile firmware_v1.2.0.hex
verifyfile firmware_v1.2.0.hex
r
exit
"
echo "$jlink_script" | JLinkExe -device STM32F407VG -if SWD -speed 4000 -autoconnect 1
echo "Flash programming: $?"
実装・開発のポイント
1. SWD vs JTAGの選択
小型マイコンや基板スペースが限られる場合はSWD(2ピン)を選ぶ。複数チェーンのデバッグやより高度な機能(ETM命令トレースなど)が必要な場合はJTAG(5ピン)を使う。
2. デバッグヘッダの設計
基板設計時に、製品には不要でも開発・保守用のデバッグヘッダ(JTAG/SWDコネクタ)をランドとして残しておくことが重要である。ARM推奨の10ピンSWDコネクタか、スペースが限られる場合は7ピン/5ピンのTagConnectを使うことが多い。
[標準10ピンSWDコネクタのピン配置]
1: VTref (3.3V) 2: SWDIO
3: GND 4: SWDCLK
5: GND 6: SWO(オプション)
7: KEY(なし) 8: nTRST(オプション)
9: GND 10: nRESET
3. デバッグロックとセキュリティ
量産品ではJTAG/SWDポートをRDPL(Read Protection Level)で無効化してリードバックを防ぐ。開発中は解除して使用する:
// STM32のRDP設定(OptionBytes)
// Level 0: デバッグ有効(開発時)
// Level 1: フラッシュ読み出し禁止
// Level 2: デバッグ完全無効(量産品・不可逆)
他技術との比較
| 比較項目 | インサーキットデバッガ | printfデバッグ | ロジックアナライザ |
|---|---|---|---|
| ハードウェア改変 | 不要 | 不要 | プローブ接続が必要 |
| リアルタイム性 | 停止して観測 | 出力遅延あり | リアルタイム |
| 見える情報 | CPU内部すべて | 明示的に出力したもの | 外部信号波形のみ |
| タイミング影響 | 停止させるため影響あり | printfがリアルタイム性に影響 | 観測による影響なし |
| 設定の複雑さ | 中程度 | 簡単 | 中程度 |
ブレークポイントはインサーキットデバッガの中核機能であり、特定のアドレスで実行を停止させることができる。IDEはインサーキットデバッガをグラフィカルに操作するためのフロントエンドを提供する。