瑞萨e2studio(18)----Code Flash&Data 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课程

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.
在这里插入图片描述

工程模板选择

在这里插入图片描述

FLASH配置

点击Stacks->New Stack->Storage -> Flash (r_flash_hp)。
在这里插入图片描述

FLASH属性配置

在这里插入图片描述

设置e2studio堆栈

在这里插入图片描述

e2studio的重定向printf设置

在这里插入图片描述

C++ 构建->设置->GNU ARM Cross C Linker->Miscellaneous去掉Other linker flags中的 “–specs=rdimon.specs”
在这里插入图片描述

uart配置

点击Stacks->New Stack->Driver->Connectivity -> UART Driver on r_sci_uart。
在这里插入图片描述

uart属性配置

配置串口,用于打印数据。
在这里插入图片描述

printf输出重定向到串口

打印最常用的方法是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()函数原型

在这里插入图片描述

故可以用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()函数原型

在这里插入图片描述

故可以用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()函数原型

在这里插入图片描述

故可以用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()函数原型

在这里插入图片描述
故可以用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);


R_FLASH_HP_StatusGet()函数原型

在这里插入图片描述
对Data Flash进行写操作时候,数据可以在后台运行,故可以用R_FLASH_HP_StatusGet()函数查询是否执行完毕。

do
    {
        err = R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);
    } while ((FSP_SUCCESS == err) && (FLASH_STATUS_BUSY == status));


Flash

对Code Flash进行读写操作时候,特别要注意写的地址,因为如果写的不对,会覆盖到代码区,造成运行错误,同时对于擦除,是一块的数据都会直接擦除掉。
在RA4M2中,Code flash最高为512KB,Data flash为8KB。

在这里插入图片描述
FACI Commands"(FACI 命令)指的是 Flash 辅助功能接口(Flash Accessibility Interface,简称 FACI)中可以使用的一组命令。
FACI 命令是 Flash 辅助功能的关键部分,它使得开发人员能够在 Flash 内容中实现可访问性功能。
在这里插入图片描述

Code 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进行读写操作时候,特别要注意要等待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读取

/*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。
或者关注『记帖』,持续更新文章和学习资料!
在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记帖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值