いつもお世話になります。 Tanamiと申します。
e2Studio+Lllvmコンパイラを使って、RL78/G23 UART通信によるブートスワップを使用したセルフプログラミングのサンプルコードをベースに、ファームウェアアップデート機能を構築しようとしています。
llvmコンパイラのリンカスクリプトを書き換えてUART通信、フラッシュ制御などは1000番地からに配置し、書き換え部は4000番地以降に配置しました。
UARTからSTARTコマンド(コマンド=02)を送り込むと、R_RFD_SeetFlashMemoryMode関数を実行するところまでは動いていること確認できています。
ところがこの関数の中で、下記部分を実行すると、デバッガがハングアップした状態になります。
R_RFD_REG_U08_PFCMD = R_RFD_VALUE_U08_PFCMD_SPECIFIC_SEQUENCE_WRITE;
またFlash書き換え状態にはいってデバッガ(e2エミュレータLITE)の制御が効かなくなる?と思い、単独で実行させてみたのですが、どうもこのあたりでリセットが発生しているようです。(起動を示すメッセージをUARTから送信していることで確認)この領域はnearで定義されていることが原因?とかも疑っていますが・・
#define R_RFD_REG_U08_PFCMD (*(volatile __near unsigned char *)0x00C0u)
具体的にどう対処したら処理がこの先へ進ませることができるかご存じの方教えていただけないでしょうか?どうぞよろしくお願いいたします。
自己レスです。まだきちんと動作したわけではないのですが、下記定義のnearをfarに置き換えたらリセットかからなくなり、先に進むことができました。(その先のまだどこかでリセットかかっているのですが・・)#define R_RFD_REG_U08_PFCMD (*(volatile __near unsigned char *)0x00C0u)CC-RLとllvmではこのあたりの命令出力が異なるようですね。
推測ですがメモリモデル無指定の時のデフォルトモデルがFARとNEARどちらが設定されるかに違いがあるかもしれません。GCCのRL78コンパイラだとデフォルトNEARで指定があるときだけFARになると書いてあります。これは古い書き込みなのでもしかしたら切り替えオプションは現在利用できるかもしれませんが、無指定はおそらくNEARです。一方CC-RLでは-cpu/-memory_model/-far_romオプションで無指定の時のメモリモデルを設定できます。
llvm-gcc-renesas.com/.../
Yamamoto様 貴重な情報ありがとうございました。CC-RL用ではC0番地をあえてnearと定義しているところを、llvmでfarと明記したら動くということからコンパイラによってこのあたりの判断が異なるみたいですね。はるか昔マイコンクロックが1MHz程度だった時代はnearにしておかないと処理速度が遅すぎるとかありましたが、今開発しているものではすべてfarでも処理速度問題ないので、farに切り替えて試してみます。
もしかすると最適化をサイズで行うとサイズがおさまってNEARでも動くかもしれません。-Osが使えると思います。RL78/G10についてですが、同じことなのかもです。blueeyes.sakura.ne.jp/.../
RL78/G23 だと、 000C0H 番地は、ユーザ・オプション・バイト F00C0H 番地が、PFCMD(フラッシュ・プロテクト・コマンド・レジスタ)のようです。
#define R_RFD_REG_U08_PFCMD (*(volatile __near unsigned char *)0x00C0u) R_RFD_REG_U08_PFCMD = R_RFD_VALUE_U08_PFCMD_SPECIFIC_SEQUENCE_WRITE;
に対して、LLVM(2024.09、-mcpu=s3 -Os) は、
mov !0xf00c0, #-91
F00C0H 番地に1バイトの R_RFD_VALUE… を書き込む、意図通りと思われるコードを出力しています。
それに対して、__near を __far に変えて、 #define R_RFD_REG_U08_PFCMD (*(volatile __far unsigned char *)0x00C0u)とすると、LLVM は、
clrw bc movw hl, #192 movw ax, #192 movw ax, bc mov a, x mov es, a mov a, #-91 mov es:[hl], a
と、000C0H 番地(ユーザ・オプション・バイト)に1バイトの R_RFD_VALUE… を書き込む、多分、本来、意図していないコードを出力しています。
なので、少なくとも、> 下記部分を実行すると、デバッガがハングアップした状態になります。の原因に関しては、__near / __far は無罪じゃないか、と思います。
それにしても、LLVM が __far に対して出しているコードは、結構、悲惨ですね。PFCMD に書き込むように #define R_RFD_REG_U08_PFCMD (*(volatile __far unsigned char *)0xF00C0u)なんてすると、目も当てられない
egret様なんとアセンブラコードの比較まで! ここまで教えていただき本当にありがとうございます。確かにC0番地と F00C0番地の違いに気づいてなかったですし、吐き出されるコードがこんなに違うとは思ってなかったです。まだ悪戦苦闘してますが、ご指導いただいたことも頭に入れてなんとか動くようがんばってみます。本当に貴重な情報ありがとうございました。