CC-RHでは,Cソースにおいて,マスカブル割り込みを禁止にすることができます。
マスカブル割り込みを禁止する方法には,大きく分けて次の2通りがあります。
C言語で記述した関数内で,部分的に割り込みを禁止する場合,アセンブラ命令の“di命令”と“ei命令”を使用することができますが,CC-RHではCソースで割り込み制御を行うことのできる関数を用意しています。
|
|
|
__DI
|
すべてのマスカブル割り込みの受け付けを禁止します。
|
di命令を生成
|
__EI
|
すべてのマスカブル割り込みの受け付けを許可します。
|
ei命令を生成
|
例 | __DI,__EI関数の記述方法とその出力コード |
void func1(void) {
:
__DI();
/*割り込みを禁止して行いたい処理を記述*/
__EI();
:
}
|
_func1:
--プロローグ・コード
:
di
--割り込みを禁止して行いたい処理
ei
:
--エピローグ・コード
jmp [lp]
|
CC-RHでは,関数全体のマスカブル割り込み割り込みを禁止する“#pragma block_interrupt”指令を用意しています。
次のような書式で記述します。
#pragma block_interrupt [(]関数名[)]
|
関数名は,C言語記述の関数名を記述してください。たとえば,"void func1 ( ) { }"という関数であれば"func1"と指定します。
上記で“関数名”で指定された関数に対し,マスカブル割り込みを禁止します。「(1) 関数内で部分的に割り込みを禁止する方法」で説明したように,関数の最初に“__DI ( );”を,最後で“__EI ( );”を記述することもできますが,この場合だと,CC-RHが出力する“プロローグ・コード”,“エピローグ・コード”に対してマスカブル割り込みを禁止/許可することができず,関数全体を完全に割り込み禁止にすることができません。
#pragma block_interrupt指令を用いると,“プロローグ・コード”実行の直前にマスカブル割り込みが禁止され,“エピローグ・コード”実行直後にマスカブル割り込み割り込みが許可されます。そのため関数全体を完全に割り込み禁止にすることができます。
例 | #pragma block_interrupt指令の使用方法と,出力されるコードは次のとおりです。 |
#pragma block_interrupt func1
void func1(void) {
:
/*割り込みを禁止して行いたい処理を記述*/
:
}
|
_func1:
di
--プロローグ・コード
:
--割り込みを禁止して行いたい処理
:
--エピローグ・コード
ei
jmp [lp]
|
関数全体の割り込みを禁止にした場合の注意事項について,次に示します。
- | 同じ関数に対して,割り込みハンドラ指定と#pragma block_interrupt指定された場合,割り込みハンドラ指定の方が優先され,割り込み禁止の設定は無視されます。 |
- | 割り込み禁止となっている関数内で,次の関数を呼び出した場合,その呼び出しからの復帰時に,割り込み許可状態になるため,注意が必要です。 |
- | #pragma block_interrupt指定された関数 |
- | 関数の先頭で割り込み禁止をし,最後で割り込み許可している関数 |
- | #pragma block_interrupt指令は,関数の定義と同一ファイル内で,かつ,定義より前に記述してください。 |
- | 関数の定義より後ろに記述された場合は無効になります。 |
- | ただし,関数のプロトタイプ宣言順とは関係ありません。 |
- | #pragma block_interrupt指定された関数に#pragma inline指令を指定した場合はエラーとなります。 |
- | #pragma block_interrupt指定しても,PSW(プログラム・ステータス・ワード)内のEPフラグ(例外処理中を示すフラグ)の操作を行うコードは出力されません。 |