RL78のミラー領域について

チョコです。

ミラー領域はプログラムの効率を低下させることなく,コード・フラッシュにアクセスするための方法です。

RL78は,基本的には1Mバイトのメモリ空間をもった16bitのMCUです。レジスタは16ビットなので,これだけでは1Mバイトのメモリ空間の全てのアドレスを指し示す(アドレッシングする)ことはできません。
通常は,データのアクセスは0xF0000~0xFFFFFの64kバイトの領域(これをnearと呼びます)を使用することで,16ビットのレジスタやイミディエート値でアドレッシングすることができます。この領域にはRAMやSFRが配置されているので,普通のデータアクセス処理はここ(near)だけで済みます。

ところが,コード・フラッシュに配置した定数はこれではアクセスできません。そこで,RL78では2つの方法が準備されています。
一つはESレジスタでアドレスの上位4ビットを指定して,残り16ビットをレジスタ等で指定する方法です(これが,farになります)。このような命令セットが準備されているので,1Mバイトのメモリ空間を全てアクセスすることは可能ですが,farでのアクセスはどうしても命令が1バイト長くなったり,実行クロック数が1クロック余分にかかってしまいます。
これに対応したのがミラー領域です。16ビットでアクセスできる0xF0000~0xFFFFFの64kバイトの領域は全て占有されているわけではなく,空いている領域が存在します。その空き領域を利用してコード・フラッシュをアクセスできるようにしたのがミラー領域です。ミラー領域を使うと,コード・フラッシュの一部をESレジスタを使用しない通常の命令でアクセスできるようになります。

CA78K0Rを使ってC言語でプログラミングを行う場合には定数(const)データはディフォルトでミラー領域に配置されます。


ただし,アドレス変換のオーバーヘッドをなくすために,ミラー領域のアドレスの上位4ビットを単純に0(または,一部の製品では1も選択可能)にしてコード・フラッシュへのアドレスとしています。
ミラー領域は0xF2000番地以降のアドレスになるので,アクセスできるコード・フラッシュは0x02000番地以降になってしまいます。このため,一部のRL78/G12では0x02000番地以降にコード・フラッシュが存在しないためにミラー領域が使えなくなっています。

なお,8ビットのRL78/G10ではミラー領域のアドレス変換をアドレスの上位5ビットに拡張し,0xF8000~のアドレスを0x00000に変換しています。これで,コード・フラッシュの0番地からミラー領域を使ってアクセスできるようになっています。

 

 

  • sohc1300さん

    ミラー領域へのアクセスはESレジスタを0x00として扱ってくれます。
    あえてfar指定すれば話は別ですが、普通にアクセスすれば
    MOVES, #00H
    MOV A, ES:!789H
    の代わりに
    MOV A, !789H
    だけでアクセスできます。
  • すみません。追記です。

    私もはまりましたが、RLマイコンはnear領域とfar領域をしっかり押さえないとはまりますのでご注意くたさい。
  • sohc1300さん

    UMの誤記ですね。
    アドレスに「8」が足りないようです。
    正しくは「MOV A, !8789H」かと。 

    G10はF8000H番地がフラッシュの0番地なので

  • チョコです。

    Kirinさんのおっしゃるようにマニュアルの間違いです。

    RL78/G10のミラー領域については以下のFAQをご参照ください。

    FAQ No. 1010750 (RL78/G10のミラー領域)

    japan.renesas.com/.../cpu_004j.jsp

  • Kon Nozomuさん、Kirinさん、チョコさん、回答ありがとうございます。

    G10はミラー領域の16ビットアドレスとそれに対応するコードフラッシュ上の16ビットアドレスが異なるため

    VMAとLMAの対応がややこしいです……

    dataセクションをVMA=0xFFE60に配置してLMA=0xF8000からロードしようとしてもさらにそのLMAにLMA=0x00000が必要になってしまいます。

    G13では2つのLMAの下位16ビットが同じだったのでこの問題はなかったことにしていました。