CC-RHでは,C言語で“割り込み”や“例外”が発生したときに呼ばれる“割り込みハンドラ”,“例外ハンドラ”を記述することができます。ここでは,その記述方法などについて説明します。
RH850ファミリでは,割り込みや例外が発生すると,その割り込みや例外に対応したハンドラ・アドレスにジャンプします。
なお,ハンドラ・アドレスの並びや,搭載している割り込みは,RH850の品種ごとに異なります。詳細は,使用する各デバイスのユーザーズ・マニュアルを参照してください。
具体的な記述方法は「(3) 割り込み/例外ハンドラの記述方法」で説明します。
関数実行時に割り込み/例外が入ると,即座に割り込み/例外処理を行う必要があります。そして割り込み/例外処理が終わると,割り込みが入った時点の関数に戻る必要があります。
したがって,割り込み/例外発生時には,そのときのレジスタ情報を保存し,割り込み/例外処理が終わった後は,そのレジスタ情報を復帰する必要があります。
割り込み/例外ハンドラの記述上の形態は,通常のC言語関数と変わりませんが,C言語で記述した関数を,CC-RHに対して“割り込み/例外ハンドラ”として認識させる必要があります。CC-RHでは,割り込み/例外ハンドラの指定を“#pragma interrupt指令”で行います。
関数名は,C言語記述の関数名を記述してください。たとえば,"void func1 ( ) { }"という関数であれば"func1"と指定します。
割り込み関数は,関数の出口コードが通常関数と異なるため,通常関数のように呼び出さないでください。
割り込み関数定義は,引数なし,または引数1 個のみ使用できます。
たとえば,“enable=”だけを書くとコンパイル・エラーとなります。割り込み仕様のデフォルトとは,個々の割り込み仕様を書かない場合の動作を意味します。
EIレベル例外の割り込み関数に対して,コンパイラが入口/出口に挿入する命令列を以下に示します。主に,EIINTやFPI等がこれに該当します。
ただし,これらをすべての割り込み関数に挿入するわけではなく,ユーザの#pragma記述やコンパイル・オプション等に応じて必要な処理が出力されます。
(2)割り込み関数中で使用する関数呼び出し前後で内容が保証されないレジスタを退避
(13)割り込み関数中で使用した関数呼び出し前後で内容が保証されないレジスタを復帰
次に,具体的な出力コード例を示します。コード例中の番号(1)〜(15)は,上記の各処理に記載された番号と対応しています。
なお,必ず出力コード例のとおりの命令が出力されるわけではありません。使用する命令や汎用レジスタ等は,コード例とは異なる場合があります。
#pragma interrupt func1(enable=true, callt=true, fpu=true) void func1(unsigned long eiic) { ユーザ記述の処理; } |
#pragma interrupt func1(enable=true, callt=true, fpu=true) void func1(unsigned long eiic) { ユーザ記述の処理; } |
FEレベル例外の割り込み関数に対して,コンパイラが入口/出口に挿入する命令列を以下に示します。主に,FEINTやPIE等がこれに該当します。
ただし,これらをすべての割り込み関数に挿入するわけではなく,ユーザの#pragma記述やコンパイル・オプション等に応じて必要な処理が出力されます。
(2)割り込み関数中で使用する関数呼び出し前後で内容が保証されないレジスタすべてを退避
(8)割り込み関数中で使用する関数呼び出し前後で内容が保証されないレジスタすべてを復帰
次に,具体的な出力コード例を示します。コード例中の番号(1)〜(10)は,上記の各処理に記載された番号と対応しています。
なお,必ず出力コード例のとおりの命令が出力されるわけではありません。使用する命令や汎用レジスタ等は,コード例とは異なる場合があります。
#pragma interrupt func1(priority=feint, callt=true, fpu=true) void func1(unsigned long feic) { ユーザ記述の処理; } |
FEレベル例外(復帰/回復不可)の割り込み関数に対して,コンパイラが入口/出口に挿入する命令列を以下に示します。主に,FENMIやSYSERR等がこれに該当します。
コンテキストの退避/復帰は一切出力されません。 |
次に,具体的な出力コード例を示します。コード例中の番号(1)は,上記の各処理に記載された番号と対応しています。