HOME > ソフテックだより > 第89号(2009年5月13日発行) 技術レポート「マイコン用ソフトウェアの割り込み処理」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ


ソフテックだより 第89号(2009年5月13日発行)
技術レポート

「マイコン用ソフトウェアの割り込み処理」

1. はじめに

ソフテックではマイコン用ソフトウェア開発を、柱の1つとして取り組んでいます。

マイコン用ソフトウェアでは、様々な周辺のICを制御して目的の動作を実現します。
このICへの制御を通信で行う場合、実際に処理が必要な時間はほんの一部で、大半は待ちとなる場合があります。しかし、制御が必要な時にはリアルタイム性が求められることがあります。
このような場合に、プログラムで常にチェックして必要な時に制御を実行する方法もありますが、ソフトウェアは様々な処理を行っているため、リアルタイム性を保障するのは難しいものです。またさらに、常にチェックするのは効率もよくありません。

このような時に、「割り込み」機能を使用します。割り込みを使用することで、リアルタイムでの処理が可能となり、信頼性や効率を上げることができます。
非常に便利な割り込みですが、その反面、使い方を間違えるとタイミングが絡む難解な問題となって表面化しやすいところであり、十分な設計と検証が必要です。
今回はこの「割り込み」の動作や、注意点を紹介します。

2. 割り込みの動作

割り込み」とはその名の通り、行っている処理を中断し、割り込んで処理を行うことを言います。
割り込みの種類には、大きく「ハードウェア割り込み」と「ソフトウェア割り込み」があります。割り込み要求を発生させる要因がハードウェアかソフトウェアかという違いであり、目的に応じて使い分けます。
当社で使用する割り込みの一例を挙げると、タイマ割り込みや通信の割り込み、ポートのエッジ割り込みなどを使用します。(これらはハードウェア割り込みに分類されます。)

割り込み処理の流れ

  1. プログラムを実行している位置(プログラムカウンタ)や、レジスタの状態を保存
  2. プログラムカウンタに、割り込み処理の開始位置を設定
  3. 割り込み処理を実行
  4. 保存していた状態を復元
  5. 通常の処理に戻る

割り込み処理イメージ
図1. 割り込み処理イメージ

多重割り込み

マイコン用ソフトウェアでは多くの場合、複数の割り込みを使いながら動作します。

複数の割り込みを使用する場合、割り込み処理中に別の割り込み要因が発生した場合や、同時に複数の割り込み要因が発生した場合のリアルタイム性などを考慮する必要があります。特に時間の制約が厳しく、他の割り込み処理と重なっても待てない場合には、多重割り込みを使用します。

多重割り込みを使用することで、既に別の割り込み処理を実行している時でも、それを中断して割り込むことが可能となります。多重割り込みは、各割り込みに設定されている優先度によって制御されますので、時間の制約が厳しいものは優先度を上げておき、多重割り込みを許可しておくことで、リアルタイム性を保障することができます。

多重割り込み処理イメージ
図2. 多重割り込み処理イメージ

3. どのような時に割り込み処理を使うか?

通常ソフトウェアは、外部で発生した事象に応じて動作します。
処理すべき事象が発生していたかどうかを調べる方法として、ポーリングという方法があります。
ポーリングでは、定期的に事象が発生していたかどうかをチェックし、事象が発生していた場合に処理を行います。

しかしこの方法では、事象が発生してからチェックするまでに時間がかかってしまう場合があります。そのため事象が発生したらすぐに処理したい場合には、間に合わず意図したとおりに処理できないかもしれません。

このような時、割り込みを使用します。
割り込みは、事象が発生したら実行中のプログラムを中断し、すぐに事象に対する処理を実施し、その後中断したプログラムを再開することができます。
そのため、事象が発生した場合にすぐに処理を実施したい時には、割り込みを使用します。

4. 割り込み処理を使う時の注意点

割り込みの動きなどを説明しましたが、ここでは実際に割り込みを使用する場合の注意点をいくつか紹介します。

(1). 割り込み処理のオーバーヘッド

割り込み処理を行う時には、その準備処理や割り込み終了後の処理でも多少の時間が必要です。また、状態を保存するための領域も必要となるため、その分を考慮しておく必要があります。
考慮せずに作ってしまうと、「準備処理の時間が長すぎて、処理が間に合わない」や、「容量オーバーになってしまった」などの問題が発生する場合があります。
実際私も、割り込みの準備処理に時間がかかりすぎて処理が間に合わないという問題に直面したことがありました。その時は準備処理を必要最低限に抑えることで対策できましたが、原因がわかるまで非常に苦労した記憶があります。

(2). 共通リソースの操作

問題が発生しやすいところですが、通常の処理と割り込み処理とで共通のリソース※を使用する場合、注意が必要です。
※ここでのリソースとは、変数やレジスタ、CPUの出力ポート、さらにICなどを指します。

よくある間違いに、1つの変数を、通常の処理と割り込み処理の両方で操作する場合、意図しない結果になることがあります。

簡単なプログラムで紹介します。

割り込み処理の注意点(共通リソース操作)
図3. 割り込み処理の注意点(共通リソース操作)

この例では、func関数とinterrupt_func関数ではどちらも同じ変数を操作しています。操作するビットが異なるため一見問題無いように見えますが、このプログラムには問題があります。

func関数実行中にinterrupt_func関数が割り込むと、g_uchValの値が0x03ではなく0x01となってしまう時があります。これは、C言語では1行のプログラムでも、CPUが実行する命令では数ステップに分かれているために起こる問題です。
このような問題は、たまにおかしな動作をする、という非常に厄介な問題となって表面化します。

そのため、通常の処理と割り込み処理とで操作するリソースは分けることが理想です。
ただし、ハードウェアの制限により、共通のリソースを操作しなければならない場合もあります。そのような時には、排他制御や一時的な割り込み禁止とする対策が必要です。

(3). 割り込み優先度

「2.割り込みの動作」で多重割り込みをご紹介しましたが、多重割り込みを使用する場合には、各割り込みの優先度に注意する必要があります。
多重割り込みを使用すると、優先度の高い割り込み要因が発生した時に、優先度が低いものは中断されてしまいます。そのため、優先度の低い割り込みは他の割り込み処理時間も一緒に考慮しないと、リアルタイム性を損なう場合があります。

(4). 割り込み処理時間

割り込みを使用すると必要な時だけ処理をすることが可能ですが、何でもかんでも割り込み処理で行うのは良くありません。
割り込み処理で多くのことをしようとすると、他の割り込みのリアルタイム性に影響を及ぼしてしまう場合があります。
多重割り込みを使うことで対応できる場合もありますが、優先度が同レベルの割り込みなどがある場合には、やはりリアルタイム性を損ねてしまいます。

割り込み処理の注意点(リアルタイム性の問題)
図4. 割り込み処理の注意点(リアルタイム性の問題)

また、割り込みを多用しすぎると、通常の処理に戻ることができず、常時行いたい処理ができなくなってしまう場合もあります。

割り込み処理の注意点(通常の処理が実行できない問題)
図5. 割り込み処理の注意点(通常の処理が実行できない問題)

ソフトウェアを安定した動作にするためには、時間の余裕のあるところはポーリングとし、すぐに処理をしたいところのみ割り込みにするなど、割り込み処理を必要最低限に抑えることが望まれます。また設計の時点で、割り込み時間のワーストケースを見積もり、問題無い設計をする必要があります。

5. 終わりに

マイコン用ソフトウェア開発での割り込み処理とその注意点を紹介しました。
割り込みは便利な反面、意図しない問題を発生させやすい機能ですので、使う場合には十分な設計と検証が必要です。しかし、割り込みを使用せずにマイコン用ソフトウェアを開発することも非常に大変です。
このメルマガで、割り込みについて少しでも理解を深めていただければ幸いです。

(T.O.)


関連ページへのリンク

関連するソフテックだより

ページTOPへ