割り込み優先度設計とは?リアルタイム性を壊さない考え方を解説

目次

はじめに

初心者さん

大事な処理なら、とりあえず最優先にすればいいんですよね?

エンジニアくん

それをやると、逆にシステム全体が壊れ始めることがあるんだ

割り込みは便利ですが、

👉 優先度設計を間違えると、
システムは簡単に不安定になります。

しかも厄介なのは、

  • たまにしか起きない
  • 再現しづらい
  • 原因が分かりにくい

という形で問題が出やすいことです。

この記事では、

  • 割り込み優先度とは何か
  • どう決めるべきか
  • なぜ「とりあえず最優先」が危険なのか

を、組み込み実務目線で整理します。

割り込みの基本についてはこちらの記事で解説しています。

割り込み処理解説シリーズ

本記事は「割り込み処理解説」シリーズの1つです。

割り込み処理解説シリーズの全体像はこちら

割り込み記事シリーズ一覧です。

  1. 割り込みとは何か?ポーリングとの違いから理解する【組み込み入門】
  2. 割り込み処理でやってはいけないこと5選|組み込み設計の落とし穴
  3. 割り込みは「処理を書く場所」ではない|組み込み設計の本質
  4. 割り込み×状態遷移設計|イベント駆動型組み込みの基本パターン
  5. 割り込み優先度設計の考え方|リアルタイム性を壊さないために(この記事)
  6. 割り込みとRTOSなし構成の違いとは?設計思想の本質を整理する

そもそも優先度とは何か?

マイコンでは、
複数の割り込みが同時に発生する可能性があります。

例えば:

  • タイマ割り込み
  • UART受信
  • ADC完了
  • 外部入力

などです。

このときCPUは、

👉 「どの割り込みを先に処理するか」

を決める必要があります。

それが「割り込み優先度」です。


割り込み優先度のイメージ

UART受信IRQ      優先度:高
Timer IRQ 優先度:中
Log出力IRQ 優先度:低

優先度が高い割り込みほど、
先に実行されます。

よくある誤解

初心者がかなりやりがちなのがこれです。

初心者さん

重要な機能ほど優先度を上げればいいよね?

一見正しそうです。

しかし実際には危険です。


「重要」と「即時性」は違う

例えば:

  • ログ出力
  • 画面更新
  • LED表示

などは重要でも、

👉 数ms遅れても問題ない

ことがあります。

一方:

  • UART受信
  • PWM制御
  • ADCサンプリング

などは、
データを失うと復旧できません。

つまり優先度は、

👉 「重要さ」ではなく、
👉 「即時性」と「損失リスク」

で考える必要があります。


割り込み優先度設計の基本原則

ここから、
実際の設計で重要な考え方を整理します。


原則① 実行時間が短いものを上位にする

これはかなり重要です。

短時間で終わるISRは、

  • 他ISRを止めにくい
  • ネスト影響が小さい
  • レイテンシを悪化させにくい

という特徴があります。

つまり:

👉 「短く終わるISR」は高優先度にしやすい

ということです。


なぜ長いISRが危険なのか?

もし高優先度ISRが長いと、

  • 他ISRが待たされる
  • タイミングが崩れる
  • システム全体が不安定になる

可能性があります。

つまり、

👉 「高優先度 = 偉い」

ではありません。


原則② 周期が短いものは慎重に扱う

例えば:

1ms Timer IRQ

これを最優先にしたくなることがあります。

しかし危険です。


なぜ危険なのか?

周期が短いISRを高優先度にすると、

👉 他ISRを頻繁に中断する

ことになります。

すると:

  • UART取りこぼし
  • ADC遅延
  • 全体タイミング崩壊

などにつながることがあります。

つまり:

👉 「周期が短い = 最優先」

ではありません。


原則③ データ損失リスクで考える

これは実務ではかなり重要です。

例えば:

割り込み損失時の影響
UART RXデータ欠落
ADC完了サンプル欠落
ログ出力後で出せばOK

この場合、
UART RX は優先度を高めにする価値があります。

つまり:

👉 「失うと困るもの」

を基準に考えます。


ネストの怖さ

高優先度割り込みが発生すると、
実行中ISRを中断できます。

これを「割り込みネスト」と呼びます。


ネストのイメージ

Low ISR 実行中

High ISR 発生

High ISR 実行

Low ISR に復帰

一見便利そうですが、
かなり危険でもあります。


ネストで起きる問題

ネストが増えると:

  • スタック使用量増加
  • 実行順変化
  • タイミング依存化
  • 再入問題

などが発生します。

つまり、

👉 「たまにだけ壊れる」

不具合が出やすくなります。

これがかなり厄介です。


スタックとの関係

割り込み発生時、
CPU状態はスタックへ退避されます。

つまりネストが増えるほど、

👉 スタック消費量も増える

ということです。

スタック不足は、

  • HardFault
  • メモリ破壊
  • 再現性の低いクラッシュ

の原因になります。

スタック領域については、
こちらの記事でも詳しく解説しています。


実務でよくある失敗

❌ とりあえず全部デフォルト

優先度を設計せず、
初期設定のまま放置。

これはかなり危険です。

問題が起きたとき、

👉 「なぜ壊れるのか分からない」

状態になります。


❌ とりあえず優先度を上げる

これもかなり多いです。

取りこぼす

優先度を上げる

動いた気がする

しかし実際には、

  • ISRが長すぎる
  • 負荷が高すぎる
  • 設計分離不足

など、
別の問題が隠れている場合もあります。

つまり、

👉 「優先度上げれば解決」

ではありません。


実務で意識している設計手順

私がかなり意識しているのは、
まず整理することです。


① 割り込み一覧を書き出す

まず全部洗い出します。

  • UART
  • Timer
  • ADC
  • GPIO

など。


② ISR実行時間を概算する

「どれくらいCPUを占有するか」

を把握します。


③ 発生周期を整理する

例えば:

  • 1ms周期
  • 10ms周期
  • 非同期発生

など。


④ データ損失リスクを評価する

失うと困るISRを整理します。


⑤ スタック最大使用量を確認する

ネスト前提で考えます。

これをやるだけでも、
事故はかなり減ります。


優先度設計は“性能”ではなく“安定性”の話

ここがかなり重要です。

優先度を上げることは、

👉 「そのISRだけを速くする」

ことではありません。

他ISRとのバランスを変える行為です。

つまり優先度設計とは、

👉 「システム全体を壊さないための調整」

なのです。


イベント駆動設計との関係

優先度設計では、

  • ISRを短くする
  • イベント通知だけ行う
  • 状態遷移へ逃がす

という設計も重要になります。

つまり、

👉 ISR設計と優先度設計はセット

です。

状態遷移設計については、
こちらの記事で詳しく解説しています。


まとめ

割り込み優先度設計では、

  • 短いISRを上位にする
  • 周期だけで決めない
  • データ損失リスクで考える
  • ネスト前提で設計する

ことが重要です。

そして本質は、

👉 「システム全体のバランス設計」

です。

優先度を適当に扱うと、

  • 再現しない不具合
  • スタック破壊
  • タイミング依存バグ

につながります。


次回予告

次回は、「割り込みとRTOSなし構成の違い」について、
設計思想の観点から整理します。

この記事が参考になった方へ

割り込み処理については、
こちらのまとめ記事で全体像を整理しています。

また当サイトでは、
割り込み理解に必要なC言語文法やメモリ構造についても実務目線で解説しています。

エンジニアとして技術を学ぶことは重要ですが、
キャリアや副業についても同時に考える必要があります。

副業の現実や市場価値、今後のキャリア戦略については、
こちらの記事でまとめています。

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

組み込みソフトエンジニアとして働きながら、
C言語・メモリ・ポインタなどの基礎から実務まで解説しています。

副業・キャリアについても実体験ベースで発信中です。

X・Qiita・noteでも発信しています。
X:更新情報・日常
Qiita:技術発信
note:キャリア・副業

▼まずはここから読むのがおすすめ
C言語文法シリーズ
メモリ領域解説シリーズ
割り込み処理解説シリーズ
ソフトウェア設計解説シリーズ
キャリアと副業ロードマップ

コメント

コメントする


目次