RX660シリーズのセルフプログラミング処理中にプログラムエラーが発生する

お世話になっております。
GAです。

以前、似た内容で一度ご質問させて頂いていたのですが、
(community-ja.renesas.com/.../51738
このソースコードを実装したファームウェアにて、
セルフプログラム中に、とあるコードフラッシュのブロックの先頭アドレスの書き込み直後に、
FASTATレジスタに0x10(コマンドロック状態のビットのみ1)と
FSTATRレジスタに0x00009000(フラッシュレディフラグとプログラムエラービットのみ1)が発生し、
プログラムに失敗します。
その際にFPESTATレジスタを読み出すと、0x02(ロックビット以外の原因によるプログラムエラー)が読み出せます。
このプログラムエラーが発生するメモリアドレスが、0xfff48000と0xfff50000で確認されており、
起動毎や直接関係ない箇所の修正でも発生しており、恐らく一定の位置ではないように思われます。

ここまでの状況を踏まえ、
まず単純にイレースが失敗している可能性を考えた為、
コードフラッシュ全域のイレース処理を終えた後に、ブランクチェックを行ったのですが、
全てのブロックでFBCSTATレジスタが0x0(ブランク)であることが確認されました。
また、割り込みで処理が中断されている可能性も考え、
プログラムの際ににシリアル通信経由でデータを受け取る必要がある都合上、SCI以外の割り込みを
__set_ipl(0xe)で制限し、
また、FWEPRORレジスタがウォッチドッグタイマリセット(WDTカウントのリセットと理解しました。)で
初期化されてしまう為、FWEPRORレジスタを監視し、
許可以外に変化した場合、許可に設定しなおすようにしております。
これらを追加した後でも、上記のようにプログラムエラーとなってしまいます。

現状他に思い付く原因が無く、何故失敗するかが分からない状態となっております。
お忙しいところ恐縮ですが、お知恵をお借り出来ましたら、幸いです。
以下開発環境と処理部、定数部のソースコードの抜粋となります。

[開発環境]
ソフト:CS+ for CC V8.11.00 [30 Nov 2023]
デバッガー:E2 Lite
対象:RX660 (R5F56609EDFP#10)


※下記に記載しているソースコードは
 全てがRAM上に展開されて動作していることを確認済みです。

[開発環境]
ソフト:CS+ for CC V8.11.00 [30 Nov 2023]
デバッガー:E2 Lite
対象:RX660 (R5F56609EDFP#10)


※下記に記載しているソースコードは
 全てがRAM上に展開されて動作していることを確認済みです。
(ソースコードにつきまして、どうしてもフォーラム上で、インデントを再現出来なかった為、
別途インデント付のtxtファイルを同梱致します。
よろしければ、そちらも合わせてご確認ください。)
/cfs-file/__key/communityserver-discussions-components-files/69/_BB30EB30D530D730ED30B030E930DF30F330B030BD30FC30B930B330FC30C930E890_.txt

定数部
const struct
{
UINT bit;
UINT* adr;

} ERASEBLOCK[] =
{
{ 0, ( UINT* )0xFFFFE000}, { 1, ( UINT* )0xFFFFC000 },
{ 2, ( UINT* )0xFFFFA000 }, { 3, ( UINT* )0xFFFF8000 },
{ 4, ( UINT* )0xFFFF6000 }, { 5, ( UINT* )0xFFFF4000 },
{ 6, ( UINT* )0xFFFF2000 }, { 7, ( UINT* )0xFFFF0000 },
{ 8, ( UINT* )0xFFFE8000 }, { 9, ( UINT* )0xFFFE0000},
{ 10, ( UINT* )0xFFFD8000},{ 11, ( UINT* )0xFFFD0000},
{ 12, ( UINT* )0xFFFC8000},{ 13, ( UINT* )0xFFFC0000},
{ 14, ( UINT* )0xFFFB8000},{ 15, ( UINT* )0xFFFB0000},
{ 16, ( UINT* )0xFFFA8000},{ 17, ( UINT* )0xFFFA0000},
{ 18, ( UINT* )0xFFF98000},{ 19, ( UINT* )0xFFF90000},
{ 20, ( UINT* )0xFFF88000},{ 21, ( UINT* )0xFFF80000},
{ 22, ( UINT* )0xFFF78000},{ 23, ( UINT* )0xFFF70000},
{ 24, ( UINT* )0xFFF68000},{ 25, ( UINT* )0xFFF60000},
{ 26, ( UINT* )0xFFF58000},{ 27, ( UINT* )0xFFF50000},
{ 28, ( UINT* )0xFFF48000},{ 29, ( UINT* )0xFFF40000},
{ 30, ( UINT* )0xFFF38000},{ 31, ( UINT* )0xFFF30000},
{ 32, ( UINT* )0xFFF28000},{ 33, ( UINT* )0xFFF20000},
{ 34, ( UINT* )0xFFF18000},{ 35, ( UINT* )0xFFF10000},
{ 36, ( UINT* )0xFFF08000},{ 37, ( UINT* )0xFFF00000}

};

#define BLK_SIZE 128 // 1ブロックサイズ
#define DATSIZE BLK_SIZE+6 // 一回のデータ送信サイズ
#define STR_BLK 0 // 書込み開始ブロック番号
#define END_BLK 37 // 書込み終了ブロック番号
#define STR_ADR 0xFFF00000 // 書込み開始アドレス
#define END_ADR 0xFFFFFEFF // 書込み終了アドレス


処理部
//書き込みメインプログラム
void RomProgSet( void )
{
int ret,jk,hige;
UCHR buf = 0;
ULNG lRcv_Counter = 0L;
long checksum;
int SequenceNumber = 1;
UCHR DumpDates[(BLK_SIZE*5)+1];
UCHR *DumpAddr;

UCHR hogechar =0; //デバッグ用レジスタ読み出しバッファ
unsigned long hogelong = 0;

jk=0;
for(jk=0;jk<BLK_SIZE;jk++)
{
DumpDates[jk]=0x81;
}
for(jk=0;jk<BLK_SIZE;jk++)
{
DumpAddr = 0xffff4000 + jk;
DumpDates[jk] = *DumpAddr;
}

do
{
switch ( SequenceNumber )
{
case 1: // 書込み開始
status = OFF;
WaitTimer( 20 );
SequenceNumber = 20;
break;

case 20: // ROMの指定領域消去
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
FLASH.FENTRYR.WORD = 0xAA01;//コードフラッシュ
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
do
{
WaitTimer(1);
}
while(FLASH.FENTRYR.WORD != 0x0001);
do
{
WaitTimer(1);
FLASH.FPROTR.WORD = 0x5501;
}
while(FLASH.FPROTR.WORD == 0x0000);
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
do
{
WaitTimer(1);
}while(FLASH.FSTATR.BIT.FRDY == OFF);
FLASH.FWEPROR.BYTE = 0x01;
do
{
FLASH.FWEPROR.BYTE = 0x01;
WaitTimer(1);
}while( FLASH.FWEPROR.BYTE != 0x01 );
FLASH.FCPSR.WORD = 0x01;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
ret = EraseRom( STR_BLK, END_BLK );
FLASH.FPROTR.WORD = 0x5500;
FLASH.FENTRYR.WORD = 0xAA00;
for(hige=0;hige<19;hige++)
{
for(jk=0;jk<=BLK_SIZE*2;jk++)
{
DumpAddr = STR_ADR + jk+((BLK_SIZE*2+1)*hige);
DumpDates[jk] = *DumpAddr;
}
WaitTimer(1);
}
hige = 0;
jk =0;

if ( ret != 0 )
{
// 消去エラー
status = 1;
SequenceNumber = 999;
break;
}
do
{
WaitTimer(1);
}while(FLASH.FSTATR.BIT.FRDY == OFF);
SequenceNumber = 30;
break;

case 30: // ROMの指定領域書込み
FLASH.FENTRYR.WORD = 0xAA01;
do
{
WaitTimer(1);
}
while(FLASH.FENTRYR.WORD == 0x0000);
do
{
WaitTimer(1);
FLASH.FPROTR.WORD = 0x5501;
}
while(FLASH.FPROTR.WORD == 0x0000);
do
{
WaitTimer(1);
}while(FLASH.FSTATR.BIT.FRDY == OFF);
FLASH.FWEPROR.BYTE = 0x01;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
IEN(SCI1, TXI1) = 1U;
ICU.GENBL0.BIT.EN2 = 1U;
IEN(SCI1, RXI1) = 1U;
ICU.GENBL0.BIT.EN3 = 1U;
FLASH.FWEPROR.BYTE = 0x01;
ret = ProgRom( STR_ADR, END_ADR );

if ( ret == -1 )
{
// 書込みエラー
status = 1;
SequenceNumber = 999;
break;
}
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
FLASH.FPROTR.WORD = 0x5500;
FLASH.FENTRYR.WORD = 0xAA00;
do
{
WaitTimer(1);
}while(FLASH.FSTATR.BIT.FRDY == OFF);
for(hige=0;hige<19;hige++)
{
for(jk=0;jk<=BLK_SIZE*2;jk++)
{
DumpAddr = STR_ADR + jk+((BLK_SIZE*2+1)*hige);
DumpDates[jk] = *DumpAddr;
}
WaitTimer(1);
}

SequenceNumber = 35;
break;
case 35:
checksum = H8S_CheckSum();
SumSend( checksum );
SequenceNumber = 40;
break;
case 40: // 終了確認
if ( status == 0 ) // 書込み終了
{
lRcv_Counter = 0L;
SequenceNumber = 50;
}
else // 書込みエラー
{
SequenceNumber = 999;
}
break;

case 50: // チェックサムチェック結果待ち
//デバッグ用に一旦コメントアウト
buf = 0;
// if ( SCI1.SSR.BIT.RDRF ) // 受信データあり
// {
// buf = SCI1.RDR; // データ読み込み
// SCI1.SSR.BIT.RDRF = 0;
// }
// // チェックサム正常のためリブート
// if ( buf == STS_RB )
// {
// SequenceNumber = 60;
// }
// // チェックサム異常のためリトライ
// if ( buf == STS_WR )
// {
// SequenceNumber = 1;
// }
// 旧バージョンにバージョンDOWNのとき強制リブート
lRcv_Counter++;
// if ( lRcv_Counter >= 800000L ) // タイムアップ(200ms)
if ( lRcv_Counter >= 1L ) // タイムアップ(200ms)//デバッグ用に縮小
{
SequenceNumber = 70;
}
break;
case 60: //ログデータ送信
SequenceNumber = 70;
break;
case 70: // 自動リブート
for(jk=0;jk<BLK_SIZE*5;jk++)
{
DumpAddr = STR_ADR + jk;
DumpDates[jk] = *DumpAddr;
}

ICU.NMIER.BIT.WDTEN = 1U;
R_BSP_SETPSW_I();
for ( ;; ); // 無限ループによる強制リセット
break;

case 999:
lRcv_Counter = 0L;
SequenceNumber = 50;
break;
default:
break;
}
}
while ( SequenceNumber != 0 );
}

/*-----------------------------------------------------------
機能 :フラッシュROMの指定領域を消去する
引数 :int startBlock: 消去開始アドレス
:int endBlock : 消去終了アドレス
戻り値 :正常:(0)/異常:(1)
-----------------------------------------------------------*/
int EraseRom( int startBlock, int endBlock )
{
int block, status;
WaitTimer( 20 );

// for ( block = startBlock; block < endBlock; ++block )
for ( block = endBlock; block >= startBlock; --block )
{
R_Config_WDT_Restart(); //WDリセット
if(FLASH.FENTRYR.WORD == 0x0000){FLASH.FENTRYR.WORD = 0xAA01;}
if(FLASH.FPROTR.WORD == 0x0000)
{
WaitTimer(1);
FLASH.FPROTR.WORD = 0x5501;
}
status = BlockErase( block );
WaitTimer( 5 );
if ( status != 0 )
{
break;
}
status = BlockBlankCheck(block);
if ( status != 0 )
{
block--;
}

}
WaitTimer( 600 );
return status;
}


/*-----------------------------------------------------------
機能 :指定ブロックを消去する
引数 :int block: 消去ブロック番号
戻り値 :正常:(0)/異常:(1)
-----------------------------------------------------------*/
int BlockErase( int block )
{
int status, n;
bool Endflg = false;
UCHR hogechar =0;
unsigned long hogelong = 0;
unsigned int *hogeintpointer;

n=0;
FLASH.FSADDR.LONG = ERASEBLOCK[block].adr;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
do
{
if(FLASH.FSTATR.BIT.FRDY == ON)
{
if(FLASH.FWEPROR.BYTE != 0x01)
{
FLASH.FWEPROR.BYTE = 0x01;
}
FACI = 0x20;
FACI = 0xD0;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

if(FACI_command_chk(0xD0)==0)
{
Endflg = true;
}
}
else{}
}while(Endflg == false);
Endflg = false;
WaitTimer(10);
do
{
if(FLASH.FSTATR.BIT.FRDY == ON)
{
Endflg = true;
if (FLASH.FASTAT.BIT.CMDLK == OFF)
{
status = 0;
}
else
{
status = 1;
}
}
else if(FLASH.FSTATR.BIT.FRDY == OFF)
{
if(n >= 600)
{
Endflg = true;
status = 1;
ForceEndCmd();
}
else { n++;}
WaitTimer(5000);
}
}while(Endflg == false);

hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
return status;
}

//ブランクチェック関数
// 戻り値 :正常:(0)/異常:(1)
int BlockBlankCheck(int block)
{
int status, n;
bool Endflg = false;
UCHR hogechar =0;
unsigned long hogelong = 0;
unsigned int *hogeintpointer;

n=0;
FLASH.FSADDR.LONG = ERASEBLOCK[block].adr;
if(block == 0)
{
FLASH.FEADDR.LONG = 0xFFFFFFFF;
}
else
{
FLASH.FEADDR.LONG = (ERASEBLOCK[block+1].adr)-1;
}
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
do
{
if(FLASH.FSTATR.BIT.FRDY == ON)
{
if(FLASH.FWEPROR.BYTE != 0x01)
{
FLASH.FWEPROR.BYTE = 0x01;
}
FACI = 0x71;
FACI = 0xD0;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

if(FACI_command_chk(0xD0)==0)
{
Endflg = true;
}
}
else{}
}while(Endflg == false);
Endflg = false;
WaitTimer(10);
do
{
if(FLASH.FSTATR.BIT.FRDY == ON)
{
Endflg = true;
if (FLASH.FBCSTAT.BYTE == 0x00)
{
status = 0;
}
else
{
status = 1;
}
}
else if(FLASH.FSTATR.BIT.FRDY == OFF)
{
if(n >= 600)
{
Endflg = true;
status = 1;
ForceEndCmd();
}
else { n++;}
WaitTimer(5000);
}
}while(Endflg == false);

hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
return status;

}

/*-----------------------------------------------------------
機能 :フラッシュROMの指定領域書込み
引数 :ULNG startAdr: 書込み開始アドレス
:ULNG endAdr : 書込み終了アドレス
戻り値 :正常:(0)/異常:(-1)
-----------------------------------------------------------*/
int ProgRom( ULNG startAdr, ULNG endAdr )
{
unsigned long* addr;
unsigned long count;
int i;

for ( count = startAdr; count < endAdr; count += 256 )
{
addr = count;
if( FLASH.FWEPROR.BYTE != 0x01){FLASH.FWEPROR.BYTE = 0x01;}
if ( ProgBlock( addr ) != 0 )
{
return -1;
}
i++;
}
return 0;
}

/*-----------------------------------------------------------
機能 :1ブロック書込み
引数 :UCHR* Waddr:
戻り値 :正常:(0)/異常:(-1)
-----------------------------------------------------------*/
int ProgBlock( UCHR* Waddr)
{

UCHR* dataAddr;
UCHR ReWrite[BLK_SIZE + 2], WriteData[BLK_SIZE + 2];
SUCHR program_data[DATSIZE + 2];
int n, prgStatus, i,ErrCount;
bool Loopflg,Loopflg2;
Loopflg = false;
Loopflg2 = false;
ErrCount=0;
UCHR hogechar =0;
unsigned long hogelong = 0;
unsigned int hogeint = 0;
unsigned long addr_memo = 0;

//本来のデータ受け取り関数 デバッグ中により、コメントアウト
// 新しいプログラムデータを取得(134byte)
// if ( getProgDat( program_data ) != 0 )
// {
// return ( 1 );
// }

//デバッグ用のデータ受け取り関数 ↑と同じデータの一部をヘッターファイルに入れて代用
if ( getProgDat_Dummy( program_data ) != 0 )
{
return ( 1 );
}

// 配列の3~130番目が実プログラムデータ */
dataAddr = ( UCHR* )( &program_data[3] );
for ( i = 0; i <= BLK_SIZE+1; ++i, ++dataAddr )
{
WriteData[i] = ReWrite[i] = *dataAddr;
}

FLASH.FWEPROR.BYTE = 0x01;
FLASH.FSADDR.BIT.FSADDR = Waddr;
addr_memo= FLASH.FSADDR.BIT.FSADDR;
do
{
WaitTimer(1);
}
while(FLASH.FSTATR.BIT.DBFULL == ON);

FACI = 0xE8;
FACI = 0x80;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

FACI_S = (unsigned short)WriteData[4] | ( ((unsigned short)WriteData[3]) <<8 );

hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

n=1;
do
{
FLASH.FWEPROR.BYTE = 0x01;
);
FACI_S = (unsigned short)WriteData[(2*n)+4] | ( ((unsigned short)WriteData[(2*n)+3]) <<8 );

hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

if(n==127)
{
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
while(FLASH.FSTATR.BIT.DBFULL == ON)
{
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
};
FLASH.FWEPROR.BYTE = 0x01;
FACI = 0xD0;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
while(FLASH.FSTATR.BIT.FRDY != 1)
{
__nop();
}
FACI_command_chk(0xD0);
Loopflg = true;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
if(hogechar == 0x10 || hogelong != 0x00008000)
{
hogeint = FLASH.FPESTAT.WORD;
}
}
else if (FLASH.FSTATR.BIT.DBFULL == ON)
{
while(Loopflg2 == false)
{
ErrCount++;
WaitTimer(4);
if(FLASH.FSTATR.BIT.DBFULL == OFF)
{
ErrCount = 0;
Loopflg2 =true;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

}
else if (ErrCount == 4)
{
ForceEndCmd();
Loopflg = true;
Loopflg2 = true;
prgStatus = -1;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;

}
}
}
n++;
R_Config_WDT_Restart();

}while(Loopflg == false);
Loopflg = false;
while(Loopflg == false)
{
if(FLASH.FSTATR.BIT.FRDY == 1)
{
Loopflg = true;
}
else
{
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;
ErrCount++;
WaitTimer(80);
if(ErrCount == 4)
{
Loopflg = true;
ForceEndCmd();
prgStatus = -1;
}
}
}
n=0;
prgStatus = 0;
hogechar = FLASH.FASTAT.BYTE;
hogelong = FLASH.FSTATR.LONG;


return prgStatus;
}

/*-----------------------------------------------------------
機能 :ウェイトタイマー
引数 :UINT time: ループ回数
戻り値 :無し
-----------------------------------------------------------*/
void WaitTimer( UINT time )
{
UINT i;
int hoge = 0;
for ( i = 0; i < time; i++ )
{
R_Config_WDT_Restart(); //WDリセット
// nop();
hoge = (i*i)/(i-1);

}

}

/***********************************************************************************************************************
* Function Name: R_Config_WDT_Restart
* Description : This function restarts WDT module
* Arguments : None
* Return Value : None
***********************************************************************************************************************/

void R_Config_WDT_Restart(void)
{
/* Refreshed by writing 00h and then writing FFh */
WDT.WDTRR = 0x00U;
WDT.WDTRR = 0xFFU;
}


  • >また、FWEPRORレジスタがウォッチドッグタイマリセット(WDTカウントのリセットと理解しました。)で
    >初期化されてしまう為

    R_Config_WDT_Restart();(WDT.WDTRRに0x00を書き込んだ後、0xFFを書き込む:WDTのリフレッシュ)で、FWEPRORが初期化(プログラム禁止)になってしまうということでしょうか。それは変な仕様である様に思えます。(ウォッチドックタイマがカウントダウンして、リセットが掛かった際に初期化されるのではないでしょうか。)

    FWEPROR.FLWEが初期値(=0x2)に戻るとしたら、それが原因で書き込みNGとなっているのではないでしょうか。(戻るタイミングと、0x01に再設定するタイミング、書き込みコマンド実行時間の3者のタイミングの関係は?FWEPRORが勝手に書き換わるのだとすると、書き込みコマンド発行後、書き込み終了までにFWEPRORの値が変わらない事の保証が出来ているのか。)

    なんとなくですが、ウォッチドックが働いている気がするのですが。(フラッシュの消去や書き込みには、思った以上の時間が掛かるので)

    一度、ウォッチドックタイマを働かせない状態で書き込みを試してみてはいかがでしょうか。

  • tf様

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

    >R_Config_WDT_Restart();(WDT.WDTRRに0x00を書き込んだ後、0xFFを書き込む:WDTのリフレッシュ)で、FWEPRORが初期化(プログラム禁止)になってしまうということでしょうか。それは変な仕様である様に思えます。(ウォッチドックタイマがカウントダウンして、リセットが掛かった際に初期化されるのではないでしょうか。)
    >FWEPROR.FLWEが初期値(=0x2)に戻るとしたら、それが原因で書き込みNGとなっているのではないでしょうか。(戻るタイミングと、0x01に再設定するタイミング、書き込みコマンド実行時間の3者のタイミングの関係は?FWEPRORが勝手に書き換わるのだとすると、書き込みコマンド発行後、書き込み終了までにFWEPRORの値が変わらない事の保証が出来ているのか。)
    →こちらの件、再度動作を確認したのですが、FWEPRORの状態は変化していませんでした。
     データシートにあった内容を見た時の推察から、思い込みをしていたようです。申し訳ございません。

    改めて動作確認をしていた際に、イレースやブランクチェックの際に使用している、
    「ERASEBLOCK」(アドレスを格納している定数)がイレースのとある段階から全て0xFFFFFFFFに変化しており、
    恐らく定数セクションCがRAM上に展開されていないことが原因でした。(プログラムセクションPはデバッガ上の表示で確認出来ていたので、同じ様にCも展開されているだろうという思い込みをしておりました。)
    #pragma section で、明示的にこの部分のC領域をRAM上に展開するセクションに変更するようにしたところ、
    無事イレース、ブランクチェック、プログラムが出来るようになりました。
    お騒がせしてしまい、申し訳ございません。

    以上です。宜しくお願い致します。

  • 本件、自己解決致しました。
    tf様への返信でも言及しましたが、
    セクション設定に問題があり、定数部CセクションがRAM上に展開されておらず、
    ERASEBLOCK[]の内容がイレース中に削除されてしまい、途中からアドレスの情報を正しく渡せていないことが原因でした。
    お騒がせしてしまい、申し訳ございません。

    本件クローズとさせていただきます。


  • 上記の件の同じプログラムにて、
    一点追加で不具合が発生しておりまして、
    もし、よろしければ、お知恵をお借り出来ましたら幸いです。

    セルフ書き込みの際に、SCI(スマートコンフィグレータにて生成)経由で
    データをやり取りしているのですが、
    SCIの受信割り込み時に、undefined_interrupt_source_isrへ遷移してしまい、
    正しくデータを受信できません。
    恐らく、上記の際と同じ様に、どこかの処理がRAM上に展開されていないことで、
    正しく割り込みが遷移出来ていないのだと考えているのですが、
    実際に遷移する際の関数である、group_bl0_handler_isrはRAM上にあり、
    そこからROM上に遷移する様子もありません。
    その為、どこの箇所が原因となるのかが分からず難航しております。
    下記に該当のソースコードを記載します。
    どんな小さなことでも構いませんので、お知恵をお貸しいただけますと幸いです。

    /***********************************************************************************************************************
    * Function name: undefined_interrupt_source_isr
    * Description : All undefined interrupt vectors point to this function.
    * Set a breakpoint in this function to determine which source is creating unwanted interrupts.
    * Arguments : none
    * Return Value : none
    ***********************************************************************************************************************/
    R_BSP_ATTRIB_INTERRUPT void undefined_interrupt_source_isr(void)
    {
        /* If user has registered a callback for this exception then call it. */
        R_BSP_InterruptControl(BSP_INT_SRC_UNDEFINED_INTERRUPT, BSP_INT_CMD_CALL_CALLBACK,     FIT_NO_PTR);
    } /* End of function undefined_interrupt_source_isr() */


    /***********************************************************************************************************************
    * Function Name: group_bl0_handler_isr
    * Description : Interrupt handler for Group BL0 interrupts. The way this code works is that for each possible interrupt
    * in this group the following will be performed:
    * 1) Test to see if an interrupt is requested for this source
    * 2) If an interrupt is requested then the registered callback is called (if one is registered)
    * NOTE: The interrupt request flag must be cleared in the peripheral.
    * Arguments : None
    * Return Value : None
    ***********************************************************************************************************************/
    R_BSP_ATTRIB_STATIC_INTERRUPT void group_bl0_handler_isr (void)
    {
        /* BL0 IS1 */
        if (1 == ICU.GRPBL0.BIT.IS1)
        {
            /* BSP_INT_SRC_BL0_SCI0_ERI0 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_ERI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

        /* BL0 IS0 */
        if (1 == ICU.GRPBL0.BIT.IS0)
        {
            /* BSP_INT_SRC_BL0_SCI0_TEI0 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_TEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

        /* BL0 IS3 */
        if (1 == ICU.GRPBL0.BIT.IS3)
        {
            /* BSP_INT_SRC_BL0_SCI1_ERI1 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI1_ERI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS2 */
        if (1 == ICU.GRPBL0.BIT.IS2)
        {
        /* BSP_INT_SRC_BL0_SCI1_TEI1 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI1_TEI1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);    
        }

    /* BL0 IS5 */
        if (1 == ICU.GRPBL0.BIT.IS5)
        {
        /* BSP_INT_SRC_BL0_SCI2_ERI2 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI2_ERI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

        /* BL0 IS4 */
        if (1 == ICU.GRPBL0.BIT.IS4)
        {
            /* BSP_INT_SRC_BL0_SCI2_TEI2 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI2_TEI2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS7 */
        if (1 == ICU.GRPBL0.BIT.IS7)
        {
            /* BSP_INT_SRC_BL0_SCI3_ERI3 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI3_ERI3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS6 */
        if (1 == ICU.GRPBL0.BIT.IS6)
        {
            /* BSP_INT_SRC_BL0_SCI3_TEI3 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI3_TEI3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS9 */
        if (1 == ICU.GRPBL0.BIT.IS9)
        {
            /* BSP_INT_SRC_BL0_SCI4_ERI4 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI4_ERI4, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS8 */
        if (1 == ICU.GRPBL0.BIT.IS8)
        {
            /* BSP_INT_SRC_BL0_SCI4_TEI4 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI4_TEI4, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS11 */
        if (1 == ICU.GRPBL0.BIT.IS11)
        {
            /* BSP_INT_SRC_BL0_SCI5_ERI5 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI5_ERI5, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS10 */
        if (1 == ICU.GRPBL0.BIT.IS10)
        {
            /* BSP_INT_SRC_BL0_SCI5_TEI5 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI5_TEI5, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS13 */
        if (1 == ICU.GRPBL0.BIT.IS13)
        {
            /* BSP_INT_SRC_BL0_SCI6_ERI6 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_ERI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS12 */
        if (1 == ICU.GRPBL0.BIT.IS12)
        {
            /* BSP_INT_SRC_BL0_SCI6_TEI6 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_TEI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS15 */
        if (1 == ICU.GRPBL0.BIT.IS15)
        {
            /* BSP_INT_SRC_BL0_SCI7_ERI7 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI7_ERI7, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS14 */
        if (1 == ICU.GRPBL0.BIT.IS14)
        {
            /* BSP_INT_SRC_BL0_SCI7_TEI7 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI7_TEI7, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS17 */
        if (1 == ICU.GRPBL0.BIT.IS17)
        {
            /* BSP_INT_SRC_BL0_SCI12_ERI12 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_ERI12, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS16 */
        if (1 == ICU.GRPBL0.BIT.IS16)
        {
            /* BSP_INT_SRC_BL0_SCI12_TEI12 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_TEI12, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS18 */
        if (1 == ICU.GRPBL0.BIT.IS18)
        {
            /* BSP_INT_SRC_BL0_SCI12_SCIX0 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS19 */
        if (1 == ICU.GRPBL0.BIT.IS19)
        {
            /* BSP_INT_SRC_BL0_SCI12_SCIX1 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX1, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS20 */
        if (1 == ICU.GRPBL0.BIT.IS20)
        {
        /* BSP_INT_SRC_BL0_SCI12_SCIX2 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX2, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS21 */
        if (1 == ICU.GRPBL0.BIT.IS21)
        {
            /* BSP_INT_SRC_BL0_SCI12_SCIX3 */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI12_SCIX3, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS26 */
        if (1 == ICU.GRPBL0.BIT.IS26)
        {
            /* BSP_INT_SRC_BL0_CAC_FERRI */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_FERRI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS27 */
        if (1 == ICU.GRPBL0.BIT.IS27)
        {
            /* BSP_INT_SRC_BL0_CAC_MENDI */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_MENDI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

    /* BL0 IS28 */
        if (1 == ICU.GRPBL0.BIT.IS28)
        {
            /* BSP_INT_SRC_BL0_CAC_OVFI */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_CAC_OVFI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }

        /* BL0 IS29 */
        if (1 == ICU.GRPBL0.BIT.IS29)
        {
            /* BSP_INT_SRC_BL0_DOC_DOPCI */
            R_BSP_InterruptControl(BSP_INT_SRC_BL0_DOC_DOPCI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR);
        }
    } /* End of function group_bl0_handler_isr() */

  • 今回のこの件はプログラム細部のバグではないので、ソースコードを見せられてもあまり役に立たないです。 CS+ GUI であればリンクオプション→外部シンボル割り付け情報ファイルを出力するをはい (-Map)にしてマップファイルを見てください。この関数は RAM になきゃいけない、この変数は RAM になきゃいけない、この定数テーブルや割り込みベクタは RAM になきゃいけない・・・云々をあなた自身の目で確認するほうがコメント待っているより早く解決します。

    -isa=RXV2 以後では制御レジスタ EXTB を操作することで「例外ベクタ」 FFFFFF80 も RAM に移せます。が、移していないとプログラムの誤りによって例外が発生しているが例外ベクタが既に消去済みである、なんてのは私もやっちゃいました。メモリ保護機能 MPU で通常の CodeFlash 上実行に最適なような保護を掛けたまま書き換え部に移動して例外で死ぬ、ってのもやりました。それら全部を掲示板でやり取りすると膨大な時間がかかるだけです。

  • cacao99様

    お世話になっております。
    上記の件、ご連絡ありがとうございます。
    内容確認させていただきました。
    フォーラムのメンテナンスが始まってしまう為、
    取り急ぎ、お礼だけ先にご連絡させていただきます。
    ありがとうございます。
    頂いた内容で少し自分なりに考えてみます。

    以上です。宜しくお願い致します。