RXマイコン用スタートアップのバグ

今まで、RXマイコンで、挙動が怪しい事があって、その原因が判らなかったが、
やっと判明した・・・

症状としては、
・スタックに配置した変数が書き換わる場合
・割り込みが多重に起動するような場合に多く発生
・多重じゃなくても割り込み関連が絡む場合など

どうもスタックが壊れている感じではあるけど、プログラムを追っても、問題無
さそう・・・

RXマイコンでは、スタックは、割り込み用スタック(ISP)と、ユーザース
タック(USP)に分かれていて、起動時、「start.s」のアセンブラプログラム
で設定されている。
ISPをメモリーの後半に置き、その手前にUSPを設定している。
当初、ISPの容量は32バイトくらいしか無かったので、256バイトにした
が、症状に変化は無い・・・

    .text
    .global  _start
    .type    _start,@function
_start:

# スタックの設定(SP:__stack、USP:__stack - 128)
    mov.l       #__stack, r0
    mvtc        r0, isp
    sub         #128,r0
    mvtc        r0, usp

ソフトウェアーマニュアルを読み直していたら、何と「R0」レジスタと「SP」
は扱いが同一となっていた!

汎用レジスタ R0 には、汎用レジスタとしての機能に加えて、スタックポインタ
(SP)としての機能が割り当てられています。

あ!、「R0」は使ったら駄目なんだ・・・・・・・・・

そこで、単純に、レジスタ名を変更

    .text
    .global  _start
    .type    _start,@function
_start:

# スタックの設定(SP:__stack、USP:__stack - 128)
    mov.l       #__stack, r5
    mvtc        r5, isp
    sub         #128,r5
    mvtc        r5, usp

この修正後、今までのおかしな挙動が直った。

今まで、結構大きなプログラムを動かしていたけど、よく動いてたなぁ・・・

経験的に、レジスターセットの後ろ(R15とか)にSPを置いてあるのが普通と
思っていたから、何も考えずに、R0を使ったのが間違いだった・・・
※ソフトウェアーマニュアルを良く読まなかったのが悪いのだけど・・・

-----
RXマイコンでは、スーパーバイザーモードとユーザーモードのRUNレベルがあり、
通常はユーザーモードで動作させる。

ユーザーモードで特権命令を実行すると、「特権違反例外」が発生する。

ユーザーモードに移行するには、「rte」命令などを実行した場合に、退避してあった
ステータスレジスターを復帰するが、その際、ユーザーモードフラグが有効になって
いれば、ユーザーモードに移行する為、以下のような、少しキワドイプログラムで移
行する。

# PMレジスタを設定し、ユーザモードに移行する、ユーザースタックに切り替わる
    mvfc    psw,r1
    or      #0x00100000, r1
    push.l  r1

# UレジスタをセットするためにRTE命令を実行する
    mvfc    pc,r1
    add	    #10,r1
    push.l  r1
    rte
    nop

※PCにオフセットを加える事で、RTE命令の下に復帰する。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください