自作関数のリエントラント性について

RL78/G14(R5F104LLAFB#V0)で、C言語の自作関数を使用しておりますが、この関数をメインルーチンと割り込みルーチンの両方で使用しております。

関数内ではグローバル変数を使用しておらず、リエントラントになっていると考えております。

 

void mmcopy( _UBYTE *d5, _UBYTE *s5, _UWORD n)
{ _UWORD i;
for(i=0;i<n;i++)
*(d5+i) = *(s5+i);
}

 

この関数がメインと割り込みで競合した場合、カウンタiはスタック退避されて戻れると認識しておりますが、E1エミュレータを接続し、連続運転していると

RESF=10hのリセットが発生します。OCDトレースを見るとこの関数で無限ループに陥っているように見えます。

RL78では上記のような関数はリエントラントにはならないのでしょうか?

Parents
  • > この関数がメインと割り込みで競合した場合、

    割り込み処理が正しく実装されてるかも疑われるべきでしょう。
  • fujita nozomuさん

    コメントありがとうございます。
    割り込み処理はA/D変換の割り込みで、コード生成ツールにより作成されたr_cg_adc_user.c内のr_adc_interrupt()関数内でユーザー定義関数を呼び出しております。

    static void __near r_adc_interrupt(void)

    _r_adc_interrupt@1:
    c1 PUSH AX
    c3 PUSH BC
    c5 PUSH DE
    c7 PUSH HL
    8efd MOV A,ES
    70 MOV X,A
    8efc MOV A,CS
    c1 PUSH AX
    ADCint( );

    fc918c00 CALL !!_ADCint
    c0 POP AX
    9efc MOV CS,A
    60 MOV A,X
    9efd MOV ES,A
    c6 POP HL
    c4 POP DE
    c2 POP BC
    c0 POP AX
    61fc RETI


    ネストが深く、長くなるのでADCintの中までは記載しませんが、上記でスタック退避していることから問題ないと考えております。
  • リエントラント性について問題はなく、割り込み関数も正常にコード化されているようですが、

    > RESF=10hのリセットが発生します。

    RESF の bit4 がセットされるのはウォッチドッグタイマによる内部リセットなので其方を疑うべきと思います。
    mmcopy() は最適化なしでコンパイルされており 1バイトの転送に 20クロックくらい要する実行効率の良くないコードとなっており、割り込み処理の中でどのような用途で使用されているのか分かりませんが、例えば A/D 変換で入力された値をバッファに格納する際、過去に貯めた値をがばっとブロック転送している場合などではバッファのサイズにより結構な処理時間を要してしまう可能性があり、それによりウォッチドッグを叩くタイミングに遅れてしまいリセットが掛かる、というような状況は普通に考えられるのではないかと思います。割り込み処理では重い処理はさせずに先の想定ではブロック転送を止めてリングバッファを導入する等対策が必要でしょう。
    ウォッチドッグタイマの設定やウォッチドッグの叩き方、割り込み処理で行っていることの内容等詳しい説明があればもう少し具体的な話に踏み込めるのではないかと思います。
  • fujita nozomuさん

    ご回答ありがとうございます。

    割り込み処理中のmmcopyはUARTポートに”:”を出力するために1byteのコピーで使用しております。
    A/D割り込みではR_ADC_StopとR_ADC_Get_Result_8bitでADCRHからデータを取得する処理を行っております。
    ウォッチドッグを叩くタイミングはメインループの先頭および中間に適度に叩くようにちりばめております。
    発生頻度も低く、2/28以降本日までに3/4、3/12の2回のみの発生となっております。それ以外にRESF=02H(IAWRF)のリセットも3/6、3/19に発生しており、この時のOCDトレースではmmcopyが正常終了した直後4ステップ程度に起きております。症例が少ないので何とも言えませんが、付近で発生しているのでmmcopyが疑わしいと思いました。ノイズ等H/Wに起因するものとの複合的な事象と推測しております。
  • ウォッチドッグタイマのオーバーフロー時間は136.53ms(2^11/fIL=15kHz)です。
    メインループ一周は8~24μs(オシロスコープにて実測)、A/D割り込み処理は最長5μsです。
Reply
  • ウォッチドッグタイマのオーバーフロー時間は136.53ms(2^11/fIL=15kHz)です。
    メインループ一周は8~24μs(オシロスコープにて実測)、A/D割り込み処理は最長5μsです。
Children
No Data