4.2.4.6 マスカブル割り込みの禁止/許可

CC-RHでは,Cソースにおいて,マスカブル割り込みを禁止にすることができます。

マスカブル割り込みを禁止する方法には,大きく分けて次の2通りがあります。

-

関数内で部分的に割り込みを禁止する方法

-

関数全体の割り込みを禁止する方法

(1)

関数内で部分的に割り込みを禁止する方法

C言語で記述した関数内で,部分的に割り込みを禁止する場合,アセンブラ命令の“di命令”と“ei命令”を使用することができますが,CC-RHではCソースで割り込み制御を行うことのできる関数を用意しています。

表 4.18

割り込み制御関数

割り込み制御関数

動作

CC-RHの処理

__DI

すべてのマスカブル割り込みの受け付けを禁止します。

di命令を生成

__EI

すべてのマスカブル割り込みの受け付けを許可します。

ei命令を生成

 

__DI,__EI関数の記述方法とその出力コード

-

Cソース

void func1(void) {
      :
    __DI();
    /*割り込みを禁止して行いたい処理を記述*/
    __EI();
      :
}

-

出力コード

_func1:
    --プロローグ・コード
      :
    di
    --割り込みを禁止して行いたい処理
    ei
      :
    --エピローグ・コード
    jmp     [lp]

(2)

関数全体の割り込みを禁止する方法

CC-RHでは,関数全体のマスカブル割り込み割り込みを禁止する“#pragma block_interrupt”指令を用意しています。

次のような書式で記述します。

#pragma block_interrupt [(]関数名[)]

関数名は,C言語記述の関数名を記述してください。たとえば,"void func1 ( ) { }"という関数であれば"func1"と指定します。

上記で“関数名”で指定された関数に対し,マスカブル割り込みを禁止します。「(1) 関数内で部分的に割り込みを禁止する方法」で説明したように,関数の最初に“__DI ( );”を,最後で“__EI ( );”を記述することもできますが,この場合だと,CC-RHが出力する“プロローグ・コード”,“エピローグ・コード”に対してマスカブル割り込みを禁止/許可することができず,関数全体を完全に割り込み禁止にすることができません。

#pragma block_interrupt指令を用いると,“プロローグ・コード”実行の直前にマスカブル割り込みが禁止され,“エピローグ・コード”実行直後にマスカブル割り込み割り込みが許可されます。そのため関数全体を完全に割り込み禁止にすることができます。

#pragma block_interrupt指令の使用方法と,出力されるコードは次のとおりです。

-

Cソース

#pragma block_interrupt func1
void func1(void) {
      :
    /*割り込みを禁止して行いたい処理を記述*/
      :
}

-

出力コード

_func1:
    di
    --プロローグ・コード
      :
    --割り込みを禁止して行いたい処理
      :
    --エピローグ・コード
    ei
    jmp     [lp]

(3)

関数全体の割り込み禁止時の注意事項

関数全体の割り込みを禁止にした場合の注意事項について,次に示します。

-

同じ関数に対して,割り込みハンドラ指定と#pragma block_interrupt指定された場合,割り込みハンドラ指定の方が優先され,割り込み禁止の設定は無視されます。

-

割り込み禁止となっている関数内で,次の関数を呼び出した場合,その呼び出しからの復帰時に,割り込み許可状態になるため,注意が必要です。

-

#pragma block_interrupt指定された関数

-

関数の先頭で割り込み禁止をし,最後で割り込み許可している関数

-

#pragma block_interrupt指令は,関数の定義と同一ファイル内で,かつ,定義より前に記述してください。

-

関数の定義より後ろに記述された場合は無効になります。

-

ただし,関数のプロトタイプ宣言順とは関係ありません。

-

#pragma block_interrupt指定された関数に#pragma inline指令を指定した場合はエラーとなります。

-

#pragma block_interrupt指定しても,PSW(プログラム・ステータス・ワード)内のEPフラグ(例外処理中を示すフラグ)の操作を行うコードは出力されません。