開発・デバッグ・テスト

インサーキットデバッガ

実機を止めて中身を調べるデバッグ装置。

概要

インサーキットデバッガ(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 BASEJTAG/SWD最高速~3万円業界標準、最も広くサポート
SEGGER J-Link EDUJTAG/SWD高速~8千円教育・非商用向け
ST-Link V3JTAG/SWD高速~4千円STM32専用、公式プローブ
CMSIS-DAPプローブ各種JTAG/SWD中速数百円〜オープン規格、多種あり
NXP LPC-Link2JTAG/SWD中速~3千円NXP公式
PICkit 4ICSP/JTAG中速~7千円Microchip PIC/AVR向け
ESP-ProgJTAG中速~3千円ESP32向け
Black Magic ProbeJTAG/SWD中速~1万円GDBサーバを内蔵
Raspberry Pi Debug ProbeSWD/UART中速~1200円Raspberry Pi Pico向け

JTAG/SWD接続の信号線

JTAG(5ピン):

ピン信号名方向説明
1TDIホスト→ターゲットテストデータ入力
2TDOターゲット→ホストテストデータ出力
3TCKホスト→ターゲットテストクロック
4TMSホスト→ターゲットテストモード選択
5nTRSTホスト→ターゲットテストリセット(オプション)

SWD(2ピン):

ピン信号名説明
1SWDIO双方向データ
2SWDCLKクロック

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はインサーキットデバッガをグラフィカルに操作するためのフロントエンドを提供する。

関連用語

参考リンク