天天看點

關于瑞薩RL78系列單片機線上更新

最近在使用瑞薩的RL78FC0907晶片,用這個晶片做了一各線上更新的小程式.晶片基本資料請參考G13,連結如下:https://www2.renesas.cn/cn/zh/doc/products/region/rtcn/mpumcu/r01uh0146cj0320_rl78g13.pdf?key=1ee8684a42ed9660902b74808580e43a   中文資料。基本上涵蓋了907的所有内容。

首先先來看下晶片的記憶體分布:

關于瑞薩RL78系列單片機線上更新

可以看到,該晶片共有32K的rom,2K的RAM。在ROM中0000-7FFF,一些固定位址的内容無法用作APP或者BOOT程式區,比如向量表區、CALLT區、選項位元組等等,當你使用Boot cluster功能的時候,同樣的,你在1000位址開始的标注的表區也無法使用,請注意.該晶片有4K的内部資料閃存,可以使用官方的FDL庫操作。2K的RAM中包含32位元組的通用寄存器,請注意這32各位元組請不要使用.鏡像區是ROM區鏡像過去的,除了其他的表區之外剩餘的24K,因為其他被特殊功能寄存器,記憶體等映射了位址.對于這個鏡像區,有一點要注意,程式中聲明的隻讀資料,const,一定要布置在鏡像區,否則編譯器會報錯,也就是說,比如你頂一個隻讀數組 u8 const DataTable[10]={1,2,3,4,5,6,7,8,9,0};  那麼這個數組你如果把它放在鏡像區,他就不會報錯,你把它放在非鏡像區,比如你把它放在0X1000的位址處,它就會編譯報錯。

關于瑞薩RL78系列單片機線上更新
關于瑞薩RL78系列單片機線上更新

遇到這個問題,可以這麼解決,将段定義中的.const删除,然後把u8 const DataTable 改為 u8 __far const DataTable,使得存放在.constf段中.還有一種就是将.const資料段整個放置到鏡像區中,0x2000位址開始.

然後程式主要分APP區和BOOT區。boot區的程式配置設定如下.APP區定義從0x2000開始.

關于瑞薩RL78系列單片機線上更新

資料段分段如圖,CODE_IN_ROM_n 這個資料段是存放boot區中斷函數的,.text段是存放__near 聲明的函數,比如說啟動例程,rlib,slib是使用庫代碼部分分别是運作庫代碼和标準庫代碼..textf是__far 聲明的函數部分,大部分函數都在這個段。.constf是__far聲明的隻讀資料. .data是初始化的變量存放在ROM的資料,.sdata是初始化的資料,短直接尋址,具有SADDR屬性的資料,存放在ROM中.  其他的pfdl fsl什麼的都是需要用到的操作庫,FDL是用于操作數4K據存儲區的,fsl是用于線上自程式設計的.下面的0XFF700開始的是記憶體區,CODE_IN_RAM就是上面的CODE_IN_ROM_n的函數複制到記憶體中,可以在RAM中執行,主要是boot區使用中斷用到的..dataR 是初始化的變量,.bss是未初始化的變量,.sdataR和.sbss 都是具有saddr屬性的記憶體段。

BOOT區需要把中斷重映射,我這邊把中斷映射到了0x2000的位址開始

關于瑞薩RL78系列單片機線上更新
關于瑞薩RL78系列單片機線上更新

因為單片機中斷的中斷向量表是隻存放跳轉的位址的,是以,每個中斷向量都隻有兩個位元組,改變之後,每個需要預留4各位元組,要注意.相應的APP區需要設定

關于瑞薩RL78系列單片機線上更新

如圖所示,從0x2000的位址開始,設定相應的跳轉函數,我這邊隻有定時器的中斷函數.設定完中斷跳轉函數,接下來就是APP區的入口函數了,APP區的入口函數位址為0x2200,請把.text這個段放在最前面,因為這個段放着啟動函數。

關于瑞薩RL78系列單片機線上更新

是以,APP程式的啟動函數入口位址為0x2200,BOOT區最後跳轉

//示例
#define APP_Start_Addr 0x2200
void ( *pfunc)(void);  //申明一個函數指針

// BOOT 區的main函數

void main ()
{
    pfunc = 0; 
    pfunc = ( void(*)(void))(APP_Start_Addr);  // 指針指向0x2200的位址
    /*
     這邊存放boot區程式
    */
    pfunc();  //boot區最後調用函數跳轉APP程式啟動代碼
}
           

自程式設計使用瑞薩的自程式設計操作庫FSL。具體的步驟如下圖:

關于瑞薩RL78系列單片機線上更新

可以選擇使用中斷也可以選擇不使用中斷,使用FSL_ChangeInterruptTable(u16  fsl_interrupt_destination)函數會将中斷映射到記憶體中,fsl_interrupt_destination參數是中斷跳轉指定的位址,兩個位元組,指定到記憶體區域0xff700,取兩個位元組0xf700.

關于瑞薩RL78系列單片機線上更新
關于瑞薩RL78系列單片機線上更新
關于瑞薩RL78系列單片機線上更新

此時,原來存在ROM中的中斷向量無法正常跳轉,是以程式中斷會直接跳轉到記憶體,是以上面需要把存放在ROM中的中斷處理函數段_CODE_IN_ROM_n 先複制到記憶體CODE_IN_RAM中.為了不讓程式出錯,這個中斷處理函數需要和普通的中斷函數類似,下代碼段

//示例

#pragma interrupt r_uart0_interrupt_receive(vect=0x2)  // 這邊需要和正常中斷聲明一樣


#pragma  section text CODE_IN_ROM   //将中斷函數(boot區中使用)放置到固定段中
 void __near r_uart0_interrupt_receive(void)
{ 
	func1();
	 
	if(STIF0)
	{
		STIF0 = 0;
		 //  TXD0 = 0x56;
	}
	if(SRIF0)
	{
		SRIF0 = 0;
		boot.step = 0;
		boot.DelayCnt = 0;
		Data_Table[boot.ReceiveCnt] = RXD0;
		if(SSR01L&0x07)
		{
				SIR01 = 0X07;  //清除故障标志
				boot.ReceiveCnt	 = 0;
		}
		if(boot.ReceiveCnt == 0)
			boot.CheckSum = 0;
		if(boot.ReceiveCnt==3)
			boot.CheckSum = Data_Table[boot.ReceiveCnt];
		else if((boot.ReceiveCnt>3)&&(boot.ReceiveCnt<131))
			boot.CheckSum += Data_Table[boot.ReceiveCnt];
		boot.ReceiveCnt++;
		
	}

 	// __RETI();
	func2();
}
#pragma section
           

需要注意的是,boot區使用的中斷入口函數隻有一個,就是說所有的中斷都會在這個函數裡面處理,根據不同的中斷标志位,處理相對應的中斷程式.要注意,在進入APP區程式之前,如果使用了FSL_ChangeInterruptTable()這個功能,那麼必須使用FSL_RestorInterruptTable()函數使得中斷恢複正常中斷向量表.

          個人體會,也許有什麼了解的不對的地方,歡迎留言指正.

繼續閱讀