1.概述
本篇文章主要介紹如何使用e2studio對(duì)瑞薩進(jìn)行Flash配置,并且分別對(duì)Code Flash & Data Flash進(jìn)行讀寫(xiě)操作。
Flash有Code Flash(儲(chǔ)存程序代碼)以及Data Flash(儲(chǔ)存一般數(shù)據(jù)),其中Code Flash主要以NOR型為主,儲(chǔ)存系統(tǒng)程序代碼及小量數(shù)據(jù);而Data Flash則是以NAND型為主,用于儲(chǔ)存大量數(shù)據(jù)。
2.硬件準(zhǔn)備
首先需要準(zhǔn)備一個(gè)開(kāi)發(fā)板,這里我準(zhǔn)備的是芯片型號(hào) R7FA2L1AB2DFL 的開(kāi)發(fā)板。
3.新建工程
4.工程模板
5.保存工程路徑
6.芯片配置
本文中使用R7FA2L1AB2DFL來(lái)進(jìn)行演示。
7
7.工程模板選擇
8.Flash配置
點(diǎn)擊 Stacks -> New Stack -> Driver -> Storage -> Flash Driver on r_flash_lp。
9.Flash屬性配置
10.設(shè)置E2STUDIO堆棧
11.e2studio的重定向printf設(shè)置
C++ 構(gòu)建->設(shè)置->GNU ARM Cross C Linker->Miscellaneous去掉Other linker flags中的 “--specs=rdimon.specs”
12.printf輸出重定向到串口
打印最常用的方法是printf,所以要解決的問(wèn)題是將printf的輸出重定向到串口,然后通過(guò)串口將數(shù)據(jù)發(fā)送出去。
注意一定要加上頭文件#include
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;i;i++)>
13.R_FLASH_LP_Open()函數(shù)原型
故可以用R_FLASH_LP_Open ()函數(shù)進(jìn)行初始化開(kāi)啟初始化Flash。
/* Open the flash lp instance. */
fsp_err_t err = R_FLASH_LP_Open(&g_flash0_ctrl, &g_flash0_cfg);
assert(FSP_SUCCESS == err);
14.R_FLASH_LP_Erase()函數(shù)原型
故可以用R_FLASH_LP_Erase()函數(shù)進(jìn)行擦除指定的代碼或數(shù)據(jù)閃存塊。
/* Erase 1 block of code flash starting at block 62. */
err = R_FLASH_LP_Erase(&g_flash0_ctrl, FLASH_CF_BLOCK_62, 1);
assert(FSP_SUCCESS == err);
15.R_FLASH_LP_StatusGet()函數(shù)原型
故可以用R_FLASH_LP_StatusGet()函數(shù)對(duì)Code Flash或者Data Flash進(jìn)行寫(xiě)數(shù)據(jù)。
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_62, g_src_uint8_length);
assert(FSP_SUCCESS == err);
16.R_FLASH_L
故可以用R_FLASH_LP_Write()函數(shù)對(duì)Code Flash或者Data Flash進(jìn)行寫(xiě)數(shù)據(jù)。
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_62, g_src_uint8_length);
assert(FSP_SUCCESS == err);
17.R_FLASH_LP_StatusGet()函數(shù)原型
對(duì)Data Flash進(jìn)行寫(xiě)操作時(shí)候,數(shù)據(jù)可以在后臺(tái)運(yùn)行,故可以用R_FLASH_LP_StatusGet()函數(shù)查詢是否執(zhí)行完畢。
/* Wait until the current flash operation completes. */
do
{
err = R_FLASH_LP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
18.Code Flash
對(duì)Code Flash進(jìn)行讀寫(xiě)操作時(shí)候,特別要注意寫(xiě)的地址,因?yàn)槿绻麑?xiě)的不對(duì),會(huì)覆蓋到代碼區(qū),造成運(yùn)行錯(cuò)誤,同時(shí)對(duì)于擦除,是一塊的數(shù)據(jù)都會(huì)直接擦除掉。
在RA2L1中,Code flash有2種規(guī)格,分別是128KB和256KB,每塊大小為2KB。
為了兼容其他的型號(hào),向Block62種寫(xiě)入數(shù)據(jù)并且讀取出來(lái),地址范圍是0x0001F000 - 0x0001F800。
使用R_FLASH_LP_Write()寫(xiě)入的時(shí)候,寫(xiě)入的是字節(jié)為單位,故num_bytes為g_src_uint8_length*1;
#define FLASH_CF_BLOCK_62 0x0001F000U /* 2 KB: 0x0001F000 - 0x0001F800 */
volatile uint8_t g_src_uint8[4]={0x1a,0x24,0x46,0x6a};
volatile uint8_t g_src_uint8_length=4;
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_62, g_src_uint8_length);
assert(FSP_SUCCESS == err);
assert(0 == memcmp(g_src_uint8, (uint8_t *) FLASH_CF_BLOCK_62, g_src_uint8_length));
19.Data Flash
對(duì)Data Flash進(jìn)行讀寫(xiě)操作時(shí)候,特別要注意要等待Data Flash寫(xiě)完才能進(jìn)行后續(xù)讀寫(xiě)操作。
在RA2L1中, Data flash都是8KB的,每塊大小為1KB 。
向Block0種寫(xiě)入數(shù)據(jù)并且讀取出來(lái),地址范圍是0x40100000 - 0x401003FF。
使用R_FLASH_LP_Write()寫(xiě)入的時(shí)候,寫(xiě)入的是字節(jié)為單位,故num_bytes為g_src_uint8_length*1;
#define FLASH_DF_BLOCK_0 0x40100000U /* 1 KB: 0x40100000 - 0x401003FF */
volatile uint8_t g_src_uint8[4]={0x1a,0x24,0x46,0x6a};
volatile uint8_t g_src_uint8_length=4;
flash_status_t status;
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_DF_BLOCK_0, g_src_uint8_length);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
do
{
err = R_FLASH_LP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
20.演示效果
向Data Flash地址0x40100000寫(xiě)入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
向Code Flash地址0x0001F000寫(xiě)入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
通過(guò)串口打印出的結(jié)果如下所示。
內(nèi)存地址查詢結(jié)果如下所示。
21.完整代碼
#include "hal_data.h"
#include
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
}
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;ievent;
}
#define FLASH_DF_BLOCK_0 0x40100000U /* 1 KB: 0x40100000 - 0x401003FF */
#define FLASH_CF_BLOCK_62 0x0001F000U /* 2 KB: 0x0001F000 - 0x0001F800 */
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
assert(FSP_SUCCESS == err);
volatile uint8_t g_src_uint8_length=4;
volatile uint8_t g_src_uint8[4]={0x1a,0x24,0x46,0x6a};
volatile uint8_t g_src_uint32_length=5;
volatile uint32_t g_src_uint32[5]={
0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444
};
/********************code flash*******************************/
flash_result_t blank_check_result;
/* Open the flash lp instance. */
fsp_err_t err = R_FLASH_LP_Open(&g_flash0_ctrl, &g_flash0_cfg);
assert(FSP_SUCCESS == err);
/* Disable interrupts to prevent vector table access while code flash is in P/E mode. */
__disable_irq();
/* Erase 1 block of code flash starting at block 62. */
err = R_FLASH_LP_Erase(&g_flash0_ctrl, FLASH_CF_BLOCK_62, 1);
assert(FSP_SUCCESS == err);
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_62, g_src_uint8_length);
assert(FSP_SUCCESS == err);
assert(0 == memcmp(g_src_uint8, (uint8_t *) FLASH_CF_BLOCK_62, g_src_uint8_length));
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint32, FLASH_CF_BLOCK_62+g_src_uint8_length*1, g_src_uint32_length*4);
assert(FSP_SUCCESS == err);
assert(0 == memcmp(g_src_uint32, (uint8_t *) FLASH_CF_BLOCK_62+g_src_uint8_length*1, g_src_uint32_length*4));
/* Enable interrupts after code flash operations are complete. */
__enable_irq();
printf("\n/********************code flash*******************************/\n");
PrintFlashTest(6,FLASH_CF_BLOCK_62);
/********************data flash*******************************/
interrupt_called = false;
/* Erase 1 block of data flash starting at block 0. */
err = R_FLASH_LP_Erase(&g_flash0_ctrl, FLASH_DF_BLOCK_0, 1);
assert(FSP_SUCCESS == err);
while (!interrupt_called)
{
;
}
assert(FLASH_EVENT_ERASE_COMPLETE == flash_event);
interrupt_called = false;
flash_status_t status;
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_DF_BLOCK_0, g_src_uint8_length);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
do
{
err = R_FLASH_LP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
err = R_FLASH_LP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint32, FLASH_DF_BLOCK_0+g_src_uint8_length*1, g_src_uint32_length*4);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
do
{
err = R_FLASH_LP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
/* If the interrupt wasn't called process the error. */
assert(interrupt_called);
/* If the event wasn't a write complete process the error. */
assert(FLASH_EVENT_WRITE_COMPLETE == flash_event);
/* Verify the data was written correctly. */
assert(0 == memcmp(g_src_uint8, (uint8_t *) FLASH_DF_BLOCK_0, g_src_uint8_length));
assert(0 == memcmp(g_src_uint32, (uint8_t *) FLASH_DF_BLOCK_0+g_src_uint8_length*1, g_src_uint32_length*4));
printf("\n/********************data flash*******************************/\n");
PrintFlashTest(6,FLASH_DF_BLOCK_0);
while(1)
{
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT100->160
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*FLASH讀取打印程序*/
void PrintFlashTest(uint32_t L,uint32_t addr)
{
uint32_t i=0;
for(i=0;i;i++)>;i++)>
原創(chuàng):By RA_Billy Xiao
原文標(biāo)題:瑞薩e2studio----Code Flash&Data Flash讀寫(xiě)
文章出處:【微信公眾號(hào):RA生態(tài)工作室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
mcu
+關(guān)注
關(guān)注
146文章
16885瀏覽量
349912 -
ARM
+關(guān)注
關(guān)注
134文章
9027瀏覽量
366474 -
嵌入式
+關(guān)注
關(guān)注
5059文章
18973瀏覽量
301995 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
4895瀏覽量
97055
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論