mcpField
I
interrupts-and-exceptions-baremetal

interrupts-and-exceptions-baremetal

github.com/mohitmishra786開発269319 回インストール18 週間前に更新
リポジトリ

interrupts-and-exceptions-baremetal について

ARM Cortex-Mのベアメタル割り込み処理をエージェント向けに案内します。NVIC設定、ISRの制約、障害診断、遅延の考慮事項を扱います。

主な機能

  1. 01NVIC設定とIRQ優先度
  2. 02ブロックしないISRの作成
  3. 03HardFaultとBusFaultの診断
  4. 04クリティカルセクションと割り込みマスク
  5. 05遅延とテールチェイニングの分析

活用シーン

  1. 01周辺機器のIRQ優先度設定
  2. 02割り込み有効化後のHardFault調査
  3. 03ISRとメインループ間のデータ共有
  4. 04割り込み遅延の測定と最適化

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill interrupts-and-exceptions-baremetal

インストール後、Claude Code で/interrupts-and-exceptions-baremetalを入力して読み込まれたか確認します。

詳細

割り込みと例外(ベアメタル)

目的

ARM Cortex-M におけるベアメタルの割り込み処理について、エージェントをガイドします。対象は、NVIC の設定、ISR の記述ルール、例外ハンドラー(HardFault、BusFault)、優先度グループ化、ネスト、テールチェーン、レイテンシに関する考慮事項です。

使用する場面

  • 周辺機器 IRQ の優先度を設定するとき
  • ブロックしてはならない ISR を記述するとき
  • 割り込みを有効にした後に発生する HardFault をデバッグするとき
  • ISR とメインループの間でデータを共有するとき
  • 割り込みレイテンシを最適化するとき

ワークフロー

1. NVIC の概要(Cortex-M)
Exception / IRQ flow
├── NVIC receives IRQ (priority compare with BASEPRI/PRIMask)
├── Stacking: automatic save r0-r3, r12, lr, pc, psr
├── Branch to handler from vector table
├── Handler runs (should be short)
└── Unstack and return — tail-chain if another IRQ pending
2. IRQ を有効化して優先度を設定する
#include "stm32f4xx.h"  /* CMSIS device header */

void uart_irq_init(void) {
    NVIC_SetPriority(USART2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 0));
    NVIC_EnableIRQ(USART2_IRQn);
}

優先度は、数値が小さいほど緊急度が高くなります(ほとんどの Cortex-M 実装の場合)。グループ化ビットについては、ベンダーのドキュメントを確認してください。

3. ISR のテンプレート
void USART2_IRQHandler(void) {
    if (USART2->SR & USART_SR_RXNE) {
        uint8_t b = (uint8_t)USART2->DR;  /* read clears RXNE */
        ringbuf_push(b);
    }
    if (USART2->SR & USART_SR_ORE) {
        (void)USART2->DR;  /* clear overrun */
    }
}

ISR のルール:

  • ブロッキング呼び出し(printf、malloc、長いループ)を使用しない
  • 処理を最小限に抑え、フラグやリングバッファを使ってメインループに委ねる
  • データシートに従って割り込みフラグをクリアする(読み取りでクリア/1 の書き込みでクリア)
4. クリティカルセクション
uint32_t primask = __get_PRIMASK();
__disable_irq();
/* atomic section */
__set_PRIMASK(primask);

または、BASEPRI を引き上げて、優先度の低い IRQ のみをマスクします。

5. HardFault ハンドラー
void HardFault_Handler(void) {
    __asm volatile(
        "tst lr, #4\n"
        "ite eq\n"
        "mrseq r0, msp\n"
        "mrsne r0, psp\n"
        "b hard_fault_c\n"
    );
}

void hard_fault_c(uint32_t *stack) {
    uint32_t r0  = stack[0];
    uint32_t pc  = stack[6];
    uint32_t psr = stack[7];
    /* log pc — GDB: info registers, bt */
    while (1);
}

障害の原因を特定するには、CFSR/HFSR レジスタをデコードします。

volatile uint32_t cfsr = SCB->CFSR;
volatile uint32_t hfsr = SCB->HFSR;
volatile uint32_t bfar = SCB->BFAR;
6. レイテンシとテールチェーン
要因影響
優先度の高い IRQ優先度の低い IRQ をプリエンプトします
テールチェーン連続する IRQ では、アンスタック/再スタックを省略します
FPU コンテキスト遅延スタッキングにより、M4F/M7 でレイテンシが増加します
長い ISRほかの IRQ とメインループを妨げます

GPIO の切り替えとスコープ、または DWT サイクルカウンター(DWT->CYCCNT)を使って測定します。

7. エージェントの使用例
/interrupts-and-exceptions-baremetal Configure NVIC priority for UART vs SysTick
/interrupts-and-exceptions-baremetal Decode HardFault stacked PC with GDB

よくある問題

症状原因対処方法
IRQ が一度も発生しないNVIC が有効になっていない、または IRQ がマスクされているNVIC_EnableIRQ を使用し、PRIMASK を確認します
意図しない再入フラグがクリアされていないRM に従ってクリアします(ORE の場合は DR の読み取りが必要です)
ISR 内で HardFault が発生するスタックオーバーフロー_estack を増やし、ISR のスタックを確認します
バイトの欠落ISR の処理が遅すぎるリングバッファを使用し、IRQ の優先度を上げます
優先度の逆転クリティカルセクションが長い__disable_irq の使用期間を短くします

関連スキル

  • skills/baremetal/baremetal-startup — ベクターテーブルのエントリー
  • skills/baremetal/uart-serial-baremetal — UART IRQ ハンドラー
  • skills/embedded/openocd-jtag — ISR 内での GDB ブレークポイント
  • skills/debuggers/gdb — 障害発生時のスタックフレームを調べる
  • skills/low-level-programming/assembly-arm — 障害ハンドラーのアセンブリ

コメント