技术标签: 瑞萨 ##瑞萨 e2studio 瑞萨RA 单片机 flash
本篇文章主要介绍如何使用e2studio对瑞萨进行Flash配置,并且分别对Code Flash & Data Flash进行读写操作。
Flash有Code Flash(储存程序代码)以及Data Flash(储存一般数据),其中Code Flash主要以NOR型为主,储存系统程序代码及小量数据;而Data Flash则是以NAND型为主,用于储存大量数据。最近在弄ST和瑞萨RA的课程,需要RA样片的可以加群申请:6_15061293 。
https://www.bilibili.com/video/BV1Bh411L7eC/
瑞萨e2studio(19)----Code Flash&Data Flash读写
csdn课程更加详细。
https://edu.csdn.net/course/detail/36131
https://www.wjx.top/vm/wBbmSFp.aspx#
https://download.csdn.net/download/qq_24312945/87748068
首先需要准备一个开发板,这里我准备的是芯片型号R7FA4M2AD3CFP的开发板:
本文中使用R7FA4M2AD3CFP来进行演示。
开发板上的外部高速晶振为12M,需要修改XTAL为12M.
点击Stacks->New Stack->Storage -> Flash (r_flash_hp)。
C++ 构建->设置->GNU ARM Cross C Linker->Miscellaneous去掉Other linker flags中的 “–specs=rdimon.specs”
点击Stacks->New Stack->Driver->Connectivity -> UART Driver on r_sci_uart。
配置串口,用于打印数据。
打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。
注意一定要加上头文件#include <stdio.h>
#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<size;i++)
{
__io_putchar(*pBuffer++);
}
return size;
}
故可以用R_FLASH_HP_Open ()函数进行初始化开启初始化Flash。
/* Open the flash lp instance. */
err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg);
assert(FSP_SUCCESS == err);
故可以用R_FLASH_HP_Erase()函数进行擦除指定的代码或数据闪存块。
/* Erase 1 block of code flash starting at block 62. */
err = R_FLASH_HP_Erase(&g_flash0_ctrl, FLASH_CF_BLOCK_21, 1);
assert(FSP_SUCCESS == err);
故可以用R_FLASH_HP_StatusGet()函数对Code Flash或者Data Flash进行写数据。
/* Wait until the current flash operation completes. */
do
{
err = R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
故可以用R_FLASH_HP_Write()函数对Code Flash或者Data Flash进行写数据。
/* Write 32 bytes to the first block of data flash. */
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_21, g_src_uint8_length);
assert(FSP_SUCCESS == err);
对Data Flash进行写操作时候,数据可以在后台运行,故可以用R_FLASH_HP_StatusGet()函数查询是否执行完毕。
do
{
err = R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
对Code Flash进行读写操作时候,特别要注意写的地址,因为如果写的不对,会覆盖到代码区,造成运行错误,同时对于擦除,是一块的数据都会直接擦除掉。
在RA4M2中,Code flash最高为512KB,Data flash为8KB。
FACI Commands"(FACI 命令)指的是 Flash 辅助功能接口(Flash Accessibility Interface,简称 FACI)中可以使用的一组命令。
FACI 命令是 Flash 辅助功能的关键部分,它使得开发人员能够在 Flash 内容中实现可访问性功能。
对Code Flash进行读写操作时候,特别要注意写的地址,因为如果写的不对,会覆盖到代码区,造成运行错误,同时对于擦除,是一块的数据都会直接擦除掉。
在RA4M2中,Code flash分布如下所示。
这里向Block21种写入数据并且读取出来,地址范围是0x00078000 - 0x0007FFF。使用R_FLASH_HP_Write()写入的时候,写入的是64字节为单位。
#define FLASH_CF_BLOCK_21 0x00078000U /* 32 KB: 0x0007_8000 - 0x0007_FFFF */
volatile uint8_t g_src_uint8_length=4;
volatile uint8_t g_src_uint8[4]={
0x1a,0x24,0x46,0x6a};
/* Write 32 bytes to the first block of data flash. */
//写入数据,4个8位数据,RA4M2是128 bytes写入范围
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_21, 128 );
assert(FSP_SUCCESS == err)
//检查数据是否正确
assert(0 == memcmp(g_src_uint8, (uint8_t *) FLASH_CF_BLOCK_21, g_src_uint8_length));
对Data Flash进行读写操作时候,特别要注意要等待Data Flash写完才能进行后续读写操作。
在RA4M2中, Data flash总大小都是8KB的,每块大小为64B 。
向Block0种写入数据并且读取出来,地址范围是0x08000000 - 0x0800003F。
使用R_FLASH_HP_Write()写入的时候,写入的是4字节为单位。
#define FLASH_DF_BLOCK_0 0x08000000U /* 64 B: 0x0800_0000 - 0x0800_003F */
volatile uint8_t g_src_uint8[4]={
0x1a,0x24,0x46,0x6a};
volatile uint8_t g_src_uint8_length=4;
volatile uint8_t g_src_uint8[4]={
0x1a,0x24,0x46,0x6a};
flash_status_t status;
/* Write 32 bytes to the first block of data flash. */
//写入数据,4个8位数据,RA4M2的data flash是4 bytes写入范围
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_DF_BLOCK_0, 4);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
//等待是否完成
do
{
err = R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
向Data Flash地址0x40100000写入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
向Code Flash地址0x0001F000写入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
通过串口打印出的结果如下所示。
内存地址查询结果如下所示。
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. */
err = R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg);
assert(FSP_SUCCESS == err);
interrupt_called = false;
/* 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 21. */
//清空Block 21
err = R_FLASH_HP_Erase(&g_flash0_ctrl, FLASH_CF_BLOCK_21, 1);
assert(FSP_SUCCESS == err);
/* Check if block 0 is erased. */
//查看清除是否成功
err = R_FLASH_HP_BlankCheck(&g_flash0_ctrl, FLASH_CF_BLOCK_21, FLASH_DATA_BLOCK_SIZE, &blank_check_result);
assert(FSP_SUCCESS == err);
/* Verify the previously erased area is blank */
assert(FLASH_RESULT_BLANK == blank_check_result);
/* Write 32 bytes to the first block of data flash. */
//写入数据,4个8位数据,RA4M2是128 bytes写入范围
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_CF_BLOCK_21, 128 );
assert(FSP_SUCCESS == err);
//检查数据是否正确
assert(0 == memcmp(g_src_uint8, (uint8_t *) FLASH_CF_BLOCK_21, g_src_uint8_length));
//写入5个32位数据
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint32, FLASH_CF_BLOCK_21+128, 128);
assert(FSP_SUCCESS == err);
assert(0 == memcmp(g_src_uint32, (uint8_t *) FLASH_CF_BLOCK_21+128, g_src_uint32_length));
/* Enable interrupts after code flash operations are complete. */
__enable_irq();
printf("\n/********************code flash-8bit*******************************/\n");
PrintFlashTest(1,FLASH_CF_BLOCK_21);
printf("\n/********************code flash-32bit*******************************/\n");
PrintFlashTest(5,FLASH_CF_BLOCK_21+128);
/********************data flash*******************************/
interrupt_called = false;
/* Erase 1 block of data flash starting at block 0. */
//清空Block 0
err = R_FLASH_HP_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. */
//写入数据,4个8位数据,RA4M2的data flash是4 bytes写入范围
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint8, FLASH_DF_BLOCK_0, 4);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
//等待是否完成
do
{
err = R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);
} while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));
//写入数据,5个32位数据,RA4M2的data flash是4 bytes写入范围
err = R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t) g_src_uint32, FLASH_DF_BLOCK_0+4, 4*5);
assert(FSP_SUCCESS == err);
/* Wait until the current flash operation completes. */
//等待是否完成
do
{
err = R_FLASH_HP_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, 4));
assert(0 == memcmp(g_src_uint32, (uint8_t *) FLASH_DF_BLOCK_0+4, 8));
printf("\n/********************data flash-8bit*******************************/\n");
PrintFlashTest(1,FLASH_DF_BLOCK_0);
printf("\n/********************data flash-32bit*******************************/\n");
PrintFlashTest(5,FLASH_DF_BLOCK_0+4);
/*FLASH读取打印程序*/
void PrintFlashTest(uint32_t L,uint32_t addr)
{
uint32_t i=0;
for(i=0;i<L;i++)
{
printf("addr is:0x%x, data is:0x%x\n", addr+i*4, *(__IO uint32_t*)(addr+i*4));
}
}
交流Q_qun615061293。
或者关注『记帖』,持续更新文章和学习资料!
文章浏览阅读8.7k次,点赞5次,收藏4次。Matlab R2014a使用mcc编译lib文件时出错,Error: Could not check out a Compiler license: SIGN= keyword required but missing from the license certificate. This is probably because the license is older than _2014a mcc license
文章浏览阅读1.1k次。我也是醉了,在各种环境下对PBRT-V3进行了编译和调试。 参考:Q113:PBRT-V3分别在Linux和Mac下的编译与调试(汇总)不过,小编对CodeBlocks“情有独钟”,所以,必须在CodeBlocks下完成这个事情。(注意是Linux系统)一、用cmake生成CodeBlocks的工程文件二、编译三、调试_添加 pbrt vs
文章浏览阅读3.4k次。碰到很多人问Linux版本的Qt怎么不能输入中文。今天解答一下,在我们的ubuntu系统一般大家都是安装的搜狗输入法。而搜狗输入法只能在浏览器或者其他地方能输入中文。在Qtcreator中无法输入中文。解决的方法就是安装其他输入法。以下是具体操作首先看是否已添加中文输入,点你的设置图标进入设置菜单中的语言支持进入语言支持看你的是否已经有汉语(中国),没有则选择下面的添加或删除语言选项,添加汉语简体。然后点击应用到整个系统。接下来Ctrl+Alt+T 调出 Terminal.._qt里怎么弄不出拼音
文章浏览阅读587次。首先解释一下cli_opt_t的这个_t代表结构体可能是type的意思。同时还有很多i_ b_等作为前缀的变量,其中的i_表示int类型的变量,b_表示bool类型的。依次类推。正式进入主题。(A)typedef struct { int b_progress; int i_seek; hnd_t hin; hnd_t hout; FILE_param->rc.f_vbv_buffer_init
文章浏览阅读2.3k次。org.apache.ibatis.exceptions.PersistenceException:### Error querying database. Cause: java.util.ConcurrentModificationException### The error may exist in com/mybatis/mapper/UserMapper.xml### The ..._error querying database. cause: java.util.concurrentmodificationexception
文章浏览阅读450次。本文转自CSDN:https://blog.csdn.net/deiki/article/details/73252942,因为我在为树莓派安装2.4G无线键鼠的时候,鼠标反应很慢,卡顿严重(换成有线鼠标就好了,而且这个无线鼠标在win10上面是正常的),最终按着这位兄弟的办法,解决了,为了记住这个解决方法,特此转到我的博客。 之前在树莓派上试了几款鼠标..._树莓派2.4g鼠标速度如何调节
文章浏览阅读7.3k次。第一. 要向android项目libs文件夹里添加gson-2.2.2.jar文件。 Txt文件中的json字符串:[{"ID":1,"LineColor":-16776961,"FillColor":-16776961,"LineSpan":10,"LineWidth":1,"Display":true,"Selected":true}, {"ID":2,"LineColor_android12 sdcard文件中的字符串
文章浏览阅读629次。唉 ,好久没有写博客了,今天弄一个简单的工具类脚本吧,在我们开发中经常会出现频繁打包测试的功能,对于不懂Unity的一些测试和策划人员来说,他们不会啊,老是麻烦程序也不太好对吧,干脆直接来个工具吧,傻瓜式打包APP吧!哈哈哈~直接上代码~/**************************************************** 文件:BuildApp.cs 作者:LYZY..._一键打包app工具
文章浏览阅读296次。什么是二叉平衡树,如何插入节点,删除节点,说出关键步骤。_什么是二叉平衡树,如何插入节点,删除节点,说出关键步骤。
文章浏览阅读1.9k次。超文本标记语言(HyperText MarkUp Language,HTML)HTML是用来制作网页的标记语言,HTML不需要编译,直接由浏览器解析;HTML文件是一个文本文件,包含了一些HTML元素, 标签等;HTML文件必须使用html或htm为文件名后缀;HTML是大小写不敏感的,HTML与html是一样的。HTML超文本标记语言,通过使用标记来描述文档结构和表现形式的一种语言,由浏览器进行..._java超文本标记语言转义
文章浏览阅读975次。说明LNK1104: 无法打开文件“uiAccess='false' /MANIFESTDEPENDENCY:ty 对于此类型问题现实可能各种原因导致,我目前提供的并不能解决每一位所产生的问题,勿怪。平台:vs2015 - qt5.7.1将通过 qmake -tp vc xxx.pro 产生xxx.vcxproj 通过vs2019打开 并选择对应的工具集编译时,出现LNK1104: 无法打开文件“uiAccess=‘false’ /MANIFESTDEPENDENCY:ty解决方案打开_无法打开文件“uiaccess='false
文章浏览阅读869次。大家装SODBASE CEP Server的时候会发现,它本身就是一个分布式系统,可以非常方便的快速建立分布式运算模型。1. 启用集群方法只要修改sodbase-cep-server-webservice-1.0.1/configuration/configuration/db.properties即可。所有的计算服务器共享了一个状态服务器State Server,也就是db.proper_哪个分布式计算框架支持cep操作