CC-RHでは,C言語で“割り込み”や“例外”が発生したときに呼ばれる“割り込みハンドラ”,“例外ハンドラ”を記述することができます。ここでは,その記述方法などについて説明します。
RH850ファミリでは,割り込みや例外が発生すると,その割り込みや例外に対応したハンドラ・アドレスにジャンプします。
なお,ハンドラ・アドレスの並びや,搭載している割り込みは,RH850の品種ごとに異なります。詳細は,使用する各デバイスのユーザーズマニュアルを参照してください。
具体的な記述方法は「(3) 割り込み/例外ハンドラの記述方法」で説明します。
関数実行時に割り込み/例外が入ると,即座に割り込み/例外処理を行う必要があります。そして割り込み/例外処理が終わると,割り込みが入った時点の関数に戻る必要があります。
したがって,割り込み/例外発生時には,そのときのレジスタ情報を保存し,割り込み/例外処理が終わった後は,そのレジスタ情報を復帰する必要があります。
割り込み/例外ハンドラの記述上の形態は,通常のC言語関数と変わりませんが,C言語で記述した関数を,CC-RHに対して“割り込み/例外ハンドラ”として認識させる必要があります。CC-RHでは,割り込み/例外ハンドラの指定を“#pragma interrupt指令”で行います。
関数名は,C言語記述の関数名を記述してください。たとえば,"void func1 ( ) { }"という関数であれば"func1"と指定します。
割り込み関数は,関数の出口コードが通常関数と異なるため,通常関数のように呼び出さないでください。
たとえば,“enable=”だけを書くとコンパイル・エラーとなります。割り込み仕様のデフォルトとは,個々の割り込み仕様を書かない場合の動作を意味します。
割り込み関数の仮引数は,割り込み仕様param=を指定した場合は4個まで,指定しない場合は1個まで記述できます。
仮引数の型は,常にunsigned long型としてください。
param=を指定しない場合は,EIレベル例外であればEIICレジスタの値が,それ以外であればFEICレジスタの値が仮引数に格納されます。
param=を指定した場合は,指定した内容に従って,各例外要因レジスタの値が,対応する仮引数に格納されます。
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)は,上記の各処理に記載された番号と対応しています。
resbank指定をしたEIレベル例外の割り込み関数に対して,コンパイラが入口/出口に挿入する命令列を以下に示します。
通常のEIレベル例外の割り込み関数で出力する命令列とは,次の点が異なります。
なお,レジスタ・バンク機能が自動的に退避するコンテキストの情報は,-Xresbank_modeオプション指定から判断します。
また,これらをすべての割り込み関数に挿入するわけではなく,ユーザの#pragma記述やコンパイル・オプション等に応じて必要な処理が出力されます。
割り込み仕様resbankを使用しても,RBCR0へ値を設定するコードは生成されません。ユーザ・プログラムで直接設定してください。
#pragma inline_asm,#pragma inline,#pragma noinline,#pragma interrupt,