いつもお世話になります。 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ではこのあたりの命令出力が異なるようですね。
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番地の違いに気づいてなかったですし、吐き出されるコードがこんなに違うとは思ってなかったです。まだ悪戦苦闘してますが、ご指導いただいたことも頭に入れてなんとか動くようがんばってみます。本当に貴重な情報ありがとうございました。