はじめに
CPUが「どんなときに忙しくなるのか」を簡単な例で見てみます。
組込み開発では、CPUを無駄に使わないようにする工夫がとても重要です。
ここでは、空ループで時間を稼ぐ場合と、割り込みで待つ場合を比較しながら、
ここでは、CPU負荷の違いを「ソフトウェアループ」と「割り込み処理」で比較します。
CPU負荷の違い
CPUを専有する処理の例
以下は、時間稼ぎのために何もしないループを回している関数です。
この間、CPUはずっと命令を実行しており、ほかの処理ができません。
void timer1m(int t)
{
volatile int i, j;
for (i = 0; i < t; i++) {
for (j = 0; j < 2220; j++) {
; // 何もしない
}
}
}
CPUの中では実際に次のような動作を繰り返しています:
| 命令 | 内容 |
|---|---|
| LOAD j | jをレジスタに読み込む |
| COMPARE j, 2220 | 比較 |
| BRANCH_IF_LESS | 条件分岐でループへ戻る |
| INCREMENT j | jを+1 |
| REPEAT | これをt×2220回繰り返す |
→ 見た目は「何もしていない」ように見えても、CPUはクロックごとに命令を回している状態です。
「CPUを使っている」とは?
CPUは1クロックごとに「命令を取り出し(Fetch)→ 解読(Decode)→ 実行(Execute)」します。
つまり、このループ中は他の命令を一切処理できません。
この状態を「CPUが占有されている」「CPUが忙しい」と言います。
ハードウェアタイマ(CMT)を使う場合
Compare Match Timer(CMT)は、CPUとは独立したタイマ専用回路です。
設定しておけば、CPUが何もしなくてもハードが時間を数えてくれます。
CPUの動き:
- タイマに「1秒ごとに通知して」と設定
- CPUは他の仕事をする(LCD描画など)
- 1秒後、ハードが自動で割り込み信号を送る
- CPUは一時的に割り込みハンドラへジャンプ
- 処理が終われば元の仕事に戻る
割り込み発生時の流れ
- ハードがイベントを検知(例:CMT0のカウント一致)
- CPUが実行中の命令を一時停止
- 現在のレジスタやプログラムカウンタをスタックに保存
- 割り込みハンドラ(ISR)を実行
- 処理後、保存した状態を復元して再開
→ CPUにとっては「一瞬だけ寄り道する」イメージです。
割り込み処理の負荷
例えば:
- 1秒ごとにCMT0割り込みが発生
- ISRでは
second++だけ実行
処理時間はわずか**数マイクロ秒(1秒のうち100万分の数)**です。
| 処理 | 実行時間 | 周期 | CPU使用率 |
|---|---|---|---|
| 割り込み処理 | 約5µs | 1秒ごと | 0.0005% 以下 |
→ CPUはほぼ遊んでいる時間が99.999%以上です。
対比:ソフトタイマ vs ハードタイマ
| 項目 | ソフトウェアタイマ (timer1m) |
ハードタイマ(CMT割り込み) |
|---|---|---|
| 処理方式 | 空ループで時間待ち | ハードウェアがカウント |
| CPU動作 | 1秒間ループし続ける | 1秒ごとに短時間割り込み |
| CPU負荷 | 約100% | 約0.0005% |
| 並行処理 | 不可 | 可能 |
| 精度 | 不安定(ループ依存) | 高精度(クロック基準) |
| 主な用途 | 簡易ウェイト、初学者練習用 | 時間管理、周期処理、イベント通知 |
まとめ
割り込みは「CPUに一瞬だけ仕事をさせて、すぐ戻す仕組み」です。
CPUを張り付けずに他の処理を進められるため、結果的に全体の負荷を大幅に減らします。