0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【干货分享】瑞萨RA6E2地奇星开发板Flash读写与OLED显示实战

电子发烧友论坛 2025-12-16 08:08 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群


本次测评基于瑞萨RA6E2地奇星开发板,验证其内部 Code Flash 与 Data Flash 的读写功能稳定性与可靠性,测试 Flash 擦除、写入、读取及数据验证的全流程可行性,为后续嵌入式项目存储方案提供参考依据。


摘自优秀创作者-jf_34532509

https://bbs.elecfans.com/jishu_2507323_1_1.html


613810e4-da13-11f0-8ce9-92fbcf53809c.png
瑞萨RA6E2-地奇星开发板
测评环境:e² studio + FSP( Flexible Software Package ) + RA6E2地奇星开发板

1、测评概述

硬件与软件环境

61515c02-da13-11f0-8ce9-92fbcf53809c.png

616d8670-da13-11f0-8ce9-92fbcf53809c.png

核心测评流程

  1. 初始化 Flash 控制器,配置 FSP 底层驱动;
  2. 对指定 Flash 块执行擦除操作,验证擦除后空白状态;
  3. 向 Code Flash 与 Data Flash 写入测试数据;
  4. 从 Flash 读取数据,通过memcmp函数验证读写一致性;
  5. 通过 OLED 显示读写状态及数据,直观呈现测试结果。


二、测评原理与代码实现

2.1 Flash 读写核心原理

瑞萨RA6E2的 Code Flash 与 Data Flash 均基于 NOR Flash 架构,遵循"先擦除,后写入"的操作原则:

  • 擦除:将指定 Flash 块的所有字节置为0xFF(空白状态);
  • 写入:仅能将0xFF位改写为0,无法直接将0改写为1;
  • 验证:读取写入后的数据与原始数据对比,一致则代表读写成功。

2.2 FSP库配置

对于IIC引脚的相关配置在之前帖子中讲过了,试用软件IIC主要就是把SCL和SDA引脚配置成GPIO接口模拟IIC数据的传输即可。本次主要介绍flash相关FSP库的配置。
步骤如下:

  1. 打开configuration.xml,先配置Clock,开发板有连个晶振,分别是20MHz和32.768kHz。这里一定要20MHz的主控晶振。RTC时钟晶振在这里不做要求。
    619db5ac-da13-11f0-8ce9-92fbcf53809c.png
  2. 新增flash堆栈
    61b2881a-da13-11f0-8ce9-92fbcf53809c.png
    61d27e68-da13-11f0-8ce9-92fbcf53809c.png

通过上述配置就完成了flash的FSP库的配置。

2.3 芯片内部flash Memory结构及地址

通过查阅用户手册,flash memory相关的模块框图如下:
61e64722-da13-11f0-8ce9-92fbcf53809c.png

通过上图我们可以知道应用层通过FACI向闪存子系统发起操作请求,FCU解析FACI转发的命令,结合外部信号生成时序控制逻辑,通过Flash sequencer完成操作的资源调度与流程编排。Flash sequencer根据FCU的控制指令对目标存储介质进行擦除-编程操作。
code flash的存储器地址映射如下图:
61fd71e0-da13-11f0-8ce9-92fbcf53809c.png

值得注意的是,每个块对应的内存容量不一样,后续代码编写需要注意,本次使用Block 13块进行操作,从0x0003_8000开始编写。
data flash的存储器地址映射如下:

621692ec-da13-11f0-8ce9-92fbcf53809c.png

本次代码编写从起始地址0x0800_0000开始编写。

2.4 关键代码实现


本次测评采用 FSP 标准 API 完成 Flash 操作,核心代码逻辑如下:
本次所有有关flash的代码都在hal_entry.c文件下编写:

1. 对相关地址寄存器的地址进行宏定义

#defineFLASH_CF_BLOCK_21 0x00038000U#defineFLASH_DF_BLOCK_0 0x08000000U#defineFLASH_DATA_BLOCK_SIZE (1024*32)

2. 回调函数实现

volatilebool interrupt_called;volatileflash_event_t flash_event;voidflash_callback(flash_callback_args_t*p_args){ interrupt_called =true; flash_event = p_args->event;}

通过回调函数,Flash操作完成后,主动触发中断然后调用回调函数并置位标志位,主程序只需要等待标志位即可,从而降低CPU资源占用率。

3. 擦除flash

// 擦除Code Flash R_FLASH_HP_Erase(&g_flash0_ctrl,FLASH_CF_BLOCK_21,1);

4. 写入Code Flash

// 写入Code Flash R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)test_data, FLASH_CF_BLOCK_21,256);

5. 读取并验证是否写入成功

memcpy(read_data, (uint8_t*)FLASH_CF_BLOCK_21,4);if(memcmp(test_data, read_data,4) ==0){// OLED显示"code flash写入成功"OLED_ShowString(1,1,"code flash: OK");// 显示读取的实际数据for(uint8_ti=0; i<4; i++) OLED_ShowHexNum(2,1+i*3, read_data[i], 2);}else{OLED_ShowString(2,1,"code flash: FAIL");assert(false);}

data flash相关代码和code flash基本一致,因此不在展示。
整体相关实现代码如下:

#include"hal_data.h"#include"oled.h"#include // 仅用于memcpy/memcmp#if(1 == BSP_MULTICORE_PROJECT) && BSP_TZ_SECURE_BUILDbsp_ipc_semaphore_handle_tg_core_start_semaphore = {.semaphore_num =0};#endif// Flash 块地址定义#defineFLASH_CF_BLOCK_21 0x00038000U // Code Flash 21块地址#defineFLASH_DF_BLOCK_0 0x08000000U // Data Flash 0块地址#defineFLASH_DATA_BLOCK_SIZE (1024*32) // Code Flash 块容量(32KB)// Flash 中断回调标志与事件volatilebool interrupt_called;volatileflash_event_t flash_event;/*** [url=home.php?mod=space&uid=2666770]@Brief[/url] Flash 中断回调函数* [url=home.php?mod=space&uid=1902110]@NOTE[/url] 用于感知Flash异步操作(擦除/写入)的完成状态*/voidflash_callback(flash_callback_args_t*p_args){ interrupt_called =true; // 置位操作完成标志 flash_event = p_args->event;// 记录操作结果事件}/*** @brief 主入口函数:实现Code Flash/Data Flash读写验证*/voidhal_entry(void){ fsp_err_terr; uint8_ttest_data[4] = {0x1a,0x24,0x46,0x6a}; // 测试数据(4字节) uint8_tread_data[4] = {0}; // Flash读取数据缓存 // 初始化OLED(可视化验证结果) OLED_Init(); OLED_Clear(); // ========== Code Flash 操作流程 ========== // 1. 打开Flash控制器 err =R_FLASH_HP_Open(&g_flash0_ctrl, &g_flash0_cfg); assert(FSP_SUCCESS == err); // 2. 关闭全局中断,避免Flash操作被干扰 __disable_irq(); // 3. 擦除Code Flash 21块(擦除是写入的前提) R_FLASH_HP_Erase(&g_flash0_ctrl, FLASH_CF_BLOCK_21,1); // 4. 写入测试数据到Code Flash(最小写入单位256字节) R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)test_data, FLASH_CF_BLOCK_21,256); // 5. 恢复全局中断 __enable_irq(); // 6. 读取+验证Code Flash数据 memcpy(read_data, (uint8_t*)FLASH_CF_BLOCK_21,4); if(memcmp(test_data, read_data,4) ==0) { // OLED显示Code Flash写入成功 OLED_ShowString(1,1,"code flash: OK"); // 显示读取的实际数据(十六进制) for(uint8_ti=0; i<4; i++) OLED_ShowHexNum(2,1+i*3, read_data[i], 2);    }    else    {        OLED_ShowString(2,1,"code flash: FAIL");        assert(false);  // 验证失败触发断言,定位错误    }    // ========== Data Flash 操作流程 ==========    // 1. 重置中断完成标志    interrupt_called = false;    // 2. 擦除Data Flash 0块 + 等待中断回调确认完成    R_FLASH_HP_Erase(&g_flash0_ctrl, FLASH_DF_BLOCK_0, 1);    while(!interrupt_called);    // 3. 写入测试数据到Data Flash(最小写入单位4字节)    R_FLASH_HP_Write(&g_flash0_ctrl, (uint32_t)test_data, FLASH_DF_BLOCK_0, 4);    // 4. 等待写入操作完成(轮询状态寄存器)    flash_status_t status;    do{R_FLASH_HP_StatusGet(&g_flash0_ctrl, &status);}while(FLASH_STATUS_BUSY == status);    // 5. 读取+验证Data Flash数据    memcpy(read_data, (uint8_t *)FLASH_DF_BLOCK_0, 4);    if(memcmp(test_data, read_data, 4) == 0)    {        // OLED显示Data Flash写入成功        OLED_ShowString(3,1,"data flash: OK");        // 显示读取的实际数据(十六进制)        for(uint8_t i=0; i<4; i++) OLED_ShowHexNum(4,1+i*3, read_data[i], 2);    }    else    {        OLED_ShowString(4,1,"data flash: FAIL");        assert(false);  // 验证失败触发断言,定位错误    }    // 多核相关代码(保留以避免编译错误,单核场景可忽略)#if (0 == _RA_CORE) && (1 == BSP_MULTICORE_PROJECT) && !BSP_TZ_NONSECURE_BUILD#if BSP_TZ_SECURE_BUILD    R_BSP_IpcSemaphoreTake(&g_core_start_semaphore);#endif    R_BSP_SecondaryCoreStart();#if BSP_TZ_SECURE_BUILD    while(FSP_ERR_IN_USE == R_BSP_IpcSemaphoreTake(&g_core_start_semaphore)){}#endif#endif#if (1 == _RA_CORE) && (1 == BSP_MULTICORE_PROJECT) && BSP_TZ_SECURE_BUILD    R_BSP_IpcSemaphoreGive(&g_core_start_semaphore);#endif#if BSP_TZ_SECURE_BUILD    R_BSP_NonSecureEnter();#endif}// 安全相关空函数(保留以避免编译错误)#if BSP_TZ_SECURE_BUILDFSP_CPP_HEADERBSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable (){}FSP_CPP_FOOTER#endif

三、测评结果与分析

3.1 功能验证结果

6229e87e-da13-11f0-8ce9-92fbcf53809c.png

3.2 常见问题与解决方案

623c5f2c-da13-11f0-8ce9-92fbcf53809c.png

四、测评总结与建议

4.1 测评总结

  1. 瑞萨RA6E2地奇星开发板的Code FlashData Flash读写功能稳定可靠,数据验证一致性达 100%,完全满足嵌入式项目的存储需求。
  2. FSP 驱动封装简洁易用,通过标准化 API 即可完成 Flash 全流程操作,降低了开发门槛。
  3. Code Flash 适合存储程序固件或大容量静态数据,Data Flash 适合存储小容量频繁更新的参数(如设备配置信息)。

4.2 应用建议

  1. 存储方案选型
  • 大容量、低更新频率数据 → Code Flash;
  • 小容量、高更新频率数据 → Data Flash;
  • 关键数据建议采用双备份存储,提升可靠性。
  • 开发优化建议
    • 擦除和写入操作耗时较长,建议在非中断敏感时段执行;
    • 频繁写入的场景可引入wear leveling(磨损均衡)算法,延长 Flash 使用寿命;
    • 利用 Flash 保护功能,对关键数据块进行写保护,防止误操作。


6250b210-da13-11f0-8ce9-92fbcf53809c.png


6258b500-da13-11f0-8ce9-92fbcf53809c.png声明:本文由电子发烧友社区发布,转载请注明以上来源。如需平台(包括:试用+专栏+企业号+学院+技术直播+共建社区)合作及入群交流,请咨询18925255684(微信同号:elecfans123),谢谢!

更多热点文章阅读

基于ESP32的终极智能手表,全过程+全开源!

RDK X3暴改机器人:手搓能爬楼的AI快递员会爬楼能唠嗑

基于树莓派制作一个番茄钟机器人!

用ESP12E做一个3D打印的6轮摇臂火星探测车

基于ESP32的圆形显示屏互动式圣诞雪球

基于Arduino控制的六足机器人


62673486-da13-11f0-8ce9-92fbcf53809c.png


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • OLED
    +关注

    关注

    121

    文章

    6335

    浏览量

    232668
  • FlaSh
    +关注

    关注

    10

    文章

    1718

    浏览量

    154798
  • 瑞萨
    +关注

    关注

    36

    文章

    22436

    浏览量

    89860
  • 开发板
    +关注

    关注

    26

    文章

    6152

    浏览量

    113950
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    RA6E2】开箱测试报告_ZGZZ

    ;amp;vd_source=7ab92f6a337b22fda39554fd6e70f01a] ****有幸参加RA6E2开发板试用活
    发表于 12-01 22:25

    RA6E2开发板试用】+初识地

    是我见到的首款外观近似于ESP32系列开发板产品,其修长的体型与常规的
    发表于 12-05 20:51

    RA6E2开发板试用】+开发环境构建与下载测试

    这次试用的RA6E2-立创地是一款高性价比的开发板,为透彻地体验它的性能,构建其
    发表于 12-06 00:11

    RA6E2开发板试用】+3款RA6E2开发板的比较

    在同一时期,能在论坛出现3款RA6E2开发板是一件不多见的罕见事儿。 出于好奇不免想对其做一下比较看看各自都有些啥特点。 1 . 体型和外观 我们的地星主打的就是一个小巧秀气,见图1所示。 图1
    发表于 12-06 10:06

    RA6E2开发板试用】介绍、环境搭建、工程测试

    RA6E2开发板试用】介绍、环境搭建、工程测试 本文介绍了
    发表于 12-07 15:27

    RA6E2开发板试用】驱动 TEMT6000 环境光传感器

    RA6E2开发板试用】驱动 TEMT6000 环境光传感器 本文介绍了
    发表于 12-07 17:32

    RA6E2开发板试用】+ 2.串口打印测试

    ; delay_ms(200); printf(\"欢迎使用RA6E2开发板\\\
    发表于 12-08 16:41

    RA6E2开发板试用】开发板相关资料介绍、点灯工程创建及演示

    HDMI CEC,SSI Quad SPI 12位A/D转换器 12位D/A转换器 通用PWM定时器 有预留的 SWD 接口。 详见:【立创·地RA6E2开发板 文档中心。 h
    发表于 12-08 16:44

    RA6E2开发板试用】+ 5.RA6E2开发板coremark跑分测试313分

    RA6E2开发板这款开发板性能很强的,是A
    发表于 12-09 17:18

    RA6E2开发板试用】 环境配置+串口驱动LED灯

    RA6E2开发板试用】+ 环境配置+串口驱动LED灯 1.硬件准备 USB-TTL驱动
    发表于 12-10 15:35

    RA6E2开发板试用】软件IIC驱动OLED屏幕实现数字打印

    RA6E2测评版 软件IIC驱动OLED数字显示
    发表于 12-11 19:58

    RA6E2开发板试用】内部Code flash和Data flash写入数据并通过OLED显示

    RA6E2开发板 Code Flash与D
    发表于 12-12 20:15

    RA6E2开发板试用】LED点亮

    的寄存器和IO关系吧,官方给了资料在\\\\立创·地RA6E2开发板\\\\4、官方文档\\\\RA6E2 Group.pdf,第438
    发表于 12-16 22:02

    RA6E2开发板试用】使用RA6E2驱动 esp8266 WiFi模块进行串口通信

    1. 需求描述 使用RA6E2驱动 esp8266 WiFi模块,用串口调试助手显示 esp8266WiFi模块响应数据。 具体来说: 串口调试助手发送 AT 指令到
    发表于 12-17 10:13

    试用活动 | 100套!!RA6E2/RA4E2开发板评测活动

    活动简介: RA6E2/RA4E2开发板评测活动是一个针对
    的头像 发表于 09-10 11:18 1518次阅读
    试用活动 | 100套!!<b class='flag-5'>瑞</b><b class='flag-5'>萨</b><b class='flag-5'>RA6E2</b>/<b class='flag-5'>RA4E2</b><b class='flag-5'>开发板</b>评测活动