※本記事は広告を含みます。
目次
割り込み処理解説シリーズ
本記事は「割り込み処理解説」シリーズの1つです。
- 割り込みとは何か?ポーリングとの違いから理解する【組み込み入門】
- 割り込み処理でやってはいけないこと5選|組み込み設計の落とし穴
- 割り込みは「処理を書く場所」ではない|組み込み設計の本質
- 割り込み×状態遷移設計|イベント駆動型組み込みの基本パターン(この記事)
- 割り込み優先度設計の考え方|リアルタイム性を壊さないために
- 割り込みとRTOSなし構成の違いとは?設計思想の本質を整理する
割り込みは「通知の入口」である。
前回の記事でそう書きました。
では、その通知はどこへ行くのか?
答えは、
状態遷移(ステートマシン)
です。
割り込みと状態遷移を正しく組み合わせると、
組み込み設計は一気に安定します。
なぜ割り込みだけでは足りないのか?
ありがちな構造:
void UART_IRQHandler(void)
{
parse_packet();
}ロジックが割り込みに埋まると、
- 状態が見えない
- 処理の流れが追えない
- 仕様変更に弱い
になります。
割り込みは「きっかけ」だけ。
制御の中心ではありません。
状態遷移とは何か?
状態遷移とは、
「今どの状態にいるか」を明示的に管理する設計
例:
typedef enum {
STATE_IDLE,
STATE_RECEIVING,
STATE_PROCESSING
} system_state_t;システムは常にどれかの状態にいます。
理想的な構造
[割り込み] → イベント発生
↓
イベントキュー or フラグ
↓
メインループ
↓
状態遷移ロジック割り込みはイベントを投げるだけ。
コード例(シンプル版)
volatile uint8_t uart_event = 0;
system_state_t state = STATE_IDLE;void UART_IRQHandler(void)
{
uart_event = 1; // 通知だけ
}
int main(void)
{
while(1)
{
if(uart_event)
{
uart_event = 0; switch(state)
{
case STATE_IDLE:
state = STATE_RECEIVING;
break; case STATE_RECEIVING:
state = STATE_PROCESSING;
break; default:
break;
}
}
}
}ロジックはすべてメイン側にあります。
なぜこの構造が強いのか?
① 割り込みが軽くなる
② 状態が可視化される
③ 仕様変更に強い
④ デバッグしやすい
特に③。
状態が明示されていれば、
- 機能追加
- 例外処理追加
- タイムアウト管理
がやりやすくなります。
実務でよくある失敗
❌ 状態を暗黙的に持つ
ifのネストだけで制御すると、
仕様追加で破綻します。
❌ 割り込みごとに処理を書く
イベントが増えるたびにISRが肥大化。
これは設計崩壊の入口です。
割り込み×状態遷移=イベント駆動設計
この組み合わせは、
- 小規模ベアメタル
- RTOSなし環境
- RAM制約が厳しい環境
で特に有効です。
RTOSを使わなくても、
構造化された並行設計ができます。
さらに一段上
実務では:
- イベントキュー化
- タイマイベント統合
- 優先度設計
- 非同期通信の抽象化
まで拡張できます。
しかし基礎は同じ。
割り込みは通知
状態遷移が制御
まとめ
割り込み単体では設計は安定しない。
- 割り込み → イベント通知
- 状態遷移 → ロジック制御
この分離ができると、
組み込み設計の質が一段上がります。
この記事が参考になった方へ
割り込みについてはこちらの記事でもまとめています。
- 割り込みとは何か?ポーリングとの違いから理解する【組み込み入門】
- 割り込み処理でやってはいけないこと5選|組み込み設計の落とし穴
- 割り込みは「処理を書く場所」ではない|組み込み設計の本質
- 割り込み×状態遷移設計|イベント駆動型組み込みの基本パターン(この記事)
- 割り込み優先度設計の考え方|リアルタイム性を壊さないために
- 割り込みとRTOSなし構成の違いとは?設計思想の本質を整理する
技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。
小さなご相談からでもお気軽にご連絡ください。

コメント