RTOS用割り込みハンドラ(#pragma rtos_interrupt)


RL78向けルネサスRTOS用の割り込みハンドラを記述することができます。

[機能]

-

#pragma rtos_interrupt指令で指定された関数名をRL78向けルネサスRTOS用割り込みハンドラと解釈します。

-

ベクタテーブル指定時は,記述された関数名のアドレスを,指定された割り込みベクタテーブルに登録します。

-

割り込みハンドラの本体(関数定義)部分のコードは,.textセクション,または.textfセクションに出力されます。セクション名は,#pragma sectionにより変更可能です。
ただし,ベクタテーブル指定時は,割り込みハンドラの先頭アドレスは16ビットでアドレッシングできなければなりません。

-

ベクタテーブルを指定した場合,明示的,暗黙問わず__farを指定しても強制的に__near指定となります。
警告は出力しません。

-

ベクタテーブルを指定しなかった場合,明示的,暗黙問わず関数の__near/__far指定に従います。

-

RTOS用割り込みハンドラは,次の順番でコード生成を行います。

(a)

call !!addr20命令によるカーネル・シンボル__kernel_int_entryの呼び出し
ベクタテーブル指定時は,__kernel_int_entryには割り込みアドレスを実引数として渡します。
ベクタテーブル未指定時は,__kernel_int_entryには実引数を渡しません。

(b)

ローカル変数領域の確保(ローカル変数があるときのみ)

(c)

関数本体の実行

(d)

ローカル変数領域の解放(ローカル変数があるときのみ)

(e)

ラベル__kernel_int_exitにbr !!addr20命令で無条件分岐

[効果]

-

Cソース・レベルで,RTOS用割り込みハンドラの記述が可能となります。

[方法]

-

次の#pragma指令により,割り込みアドレスと関数名を指定します。

#pragma rtos_interrupt   [(]関数名[(vect=アドレス)][)]

アドレス: 2,8,10 または16 進数定数
定数値は0〜0x7c の偶数のみ(範囲外はエラー)

-

#pragma 指令は関数定義の前に書いてください。

[制限]

-

#pragma rtos_interrupt 指定した関数を通常関数のように呼び出すと,コンパイル・エラーとなります。

#pragma rtos_interrupt func (vect=8)
void func(void) {}
 
void xxx()
{
        func();                 //エラー
}

-

関数は,引数,戻り型ともにvoid型で宣言しなければなりません(例:void func (void);)。
void型でない場合はコンパイル・エラーとなります。

-

RTOS用割り込みハンドラに__inline,__calltおよび他#pragmaを指定すると,コンパイル・エラーとなります。

-

#pragma rtos_interruptの宣言行以降は,関数,または変数として_kernel_int_exitおよび_kernel_int_entryの呼び出しと定義はエラーとなります。

#pragma rtos_interrupt func (vect=8)
void func(void) {
        _kernel_int_entry();    //エラー
        _kernel_int_exit();     //エラー
}
 
void    _kernel_int_entry(){}   //エラー
void    _kernel_int_exit(){}    //エラー

[使用例]

ベクタテーブルの指定があり,割り込みハンドラ中に関数呼び出しがない場合の使用例を示します。

 

【入力プログラム】

#include "iodefine.h"
 
#pragma rtos_interrupt inthdr (vect=INTP0)
volatile int g;
 
void inthdr(void) {
        volatile int a;
        a = 1;
        g = 1;
}

 

【出力プログラム】

        .SECTION .textf,TEXTF
_inthdr .vector 0x0008
_inthdr:
        push    ax                      ;axレジスタの退避
        movw    ax, #0x0008
        call    !!__kernel_int_entry    ;ax以外のレジスタの退避
        push    hl                      ;ローカル変数の領域確保
        onew    ax
        movw    [sp+0x00], ax
        movw    !LOWW(_g), ax
        pop     hl                      ;ローカル変数の領域解放
        br      !!__kernel_int_exit     ;割り込み元タスクの実行再開時に
                                        ;全レジスタを復帰するよう処理

ベクタテーブルの指定がなく,割り込みハンドラ中に関数呼び出しがない場合の使用例を示します。

 

【入力プログラム】

#include "iodefine.h"
 
#pragma rtos_interrupt inthdr
volatile int g;
 
void inthdr(void) {
        volatile int a;
        a = 1;
        g = 1;
}

 

【出力プログラム】

        .SECTION .textf,TEXTF
_inthdr:
        call    !!__kernel_int_entry    ;ax以外のレジスタの退避
        push    hl                      ;ローカル変数の領域確保
        onew    ax
        movw    [sp+0x00], ax
        movw    !LOWW(_g), ax
        pop     hl                      ;ローカル変数の領域解放
        br      !!__kernel_int_exit     ;割り込み元タスクの実行再開時に
                                        ;全レジスタを復帰するよう処理