組み込みLinuxにおける割り込み障害の体系的トラブルシューティング

割り込み関連のエラーは、システムクラッシュ、応答不能、パフォーマンス低下を引き起こす可能性があります。以下に、段階的な調査手順を示します。

1. 割り込み登録状態の確認

# 全割り込み統計の表示
cat /proc/interrupts

# 特定デバイスの割り込み確認(例:GPIO)
grep gpio /proc/interrupts

確認ポイント

  • IRQ番号がデバイスツリーと一致しているか
  • 割り込み発生回数に異常がないか
  • 各CPUコアに割り込みが均等に分散されているか

2. 割り込み処理レイテンシの測定

ftraceを利用した遅延計測:

echo function_graph > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/events/irq/enable
echo 1 > /sys/kernel/debug/tracing/tracing_on
# 割り込み発生後に以下のコマンドで確認
cat /sys/kernel/debug/tracing/trace

異常の目安

  • 割り込み処理に100μs以上かかる場合は最適化が必要
  • iret_exceptionが頻発する場合はスタックオーバーフローの可能性

3. よくあるエラータイプとその調査

現象調査項目
システムフリーズ割り込み処理内のブロッキング処理を確認
デバイス応答なし割り込み線が誤って共有されていないか検証
データ消失割り込みストーム(次項参照)の有無を確認
ランダムクラッシュkmemleakを使いメモリ破壊を調査

4. 割り込みストームの診断

watch -n 0.5 "cat /proc/interrupts | grep [IRQ]"

対策

  1. ハードウェア:電気的ノイズや信号品質をチェック
  2. ドライバ:割り込みステータスレジスタのクリア処理を確認
  3. カーネル設定:CONFIG_DEBUG_SHIRQを有効化

5. 割り込みコンテキストの問題検出

禁止操作リスト

  • spin_lock_irqsave()の使用が必要
  • kmalloc(GFP_KERNEL)などスリープ可能な関数の呼び出し
  • 10μsを超える長時間処理

デバッグコード例

// 割り込みハンドラ内で使用
if (in_interrupt())
    printk("現在割り込みコンテキストで実行中\n");

6. デバイスツリー設定の検証

デバイスツリーノード例:

my_device {
    compatible = "vendor,device";
    interrupt-parent = <&gpio>;
    interrupts = <14 IRQ_TYPE_EDGE_RISING>;
};

確認項目

  1. interruptsパラメータがハードウェア仕様に合致しているか
  2. dtc -I dtb -O dts /proc/device-treeで逆コンパイルし実機と比較

7. 高度なデバッグツール

  • GDB + JTAG:割り込みベクタテーブルの異常を捉える
  • perfperf record -e irq:irq_handler_entryでプロファイル
  • SysRqマジックキーecho t > /proc/sysrq-triggerでスタックトレース取得

非常時対応
システムが完全に応答しない場合、ハードウェアリセット後にCONFIG_DEBUG_LLを有効にしたカーネルをロードし、シリアル経由でoopsメッセージを確認します。

これらの手順で、大半の割り込み問題(約90%)の原因を特定できます。ハードウェアの信号計測とソフトウェアログの解析を併用することが成功の鍵です。複雑な問題では、オシロスコープで割り込み信号のタイミングを観測する必要がある場合もあります。

タグ: 組み込みLinux 割り込み処理 ftrace デバイスツリー カーネルデバッグ

6月1日 00:21 投稿