1.概述
本篇文章主要介绍如何使用e2studio对瑞萨进行flash配置,并且分别对code flash & data flash进行读写操作。
flash有code flash(储存程序代码)以及data flash(储存一般数据),其中code flash主要以nor型为主,储存系统程序代码及小量数据;而data flash则是以nand型为主,用于储存大量数据。
2.硬件准备
首先需要准备一个开发板,这里我准备的是芯片型号 r7fa2l1ab2dfl 的开发板。
3.新建工程
4.工程模板
5.保存工程路径
6.芯片配置
本文中使用r7fa2l1ab2dfl来进行演示。
7
7.工程模板选择
8.flash配置
点击 stacks -> new stack -> driver -> storage -> flash driver on r_flash_lp。
9.flash属性配置
10.设置e2studio堆栈
11.e2studio的重定向printf设置
c++ 构建->设置->gnu arm cross c linker->miscellaneous去掉other linker flags中的 “--specs=rdimon.specs”
12.printf输出重定向到串口
打印最常用的方法是printf,所以要解决的问题是将printf的输出重定向到串口,然后通过串口将数据发送出去。
注意一定要加上头文件#include
#ifdef __gnuc__ //串口重定向 #define putchar_prototype int __io_putchar(int ch)#else #define putchar_prototype int fputc(int ch, file *f)#endifputchar_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()函数原型
故可以用r_flash_lp_open ()函数进行初始化开启初始化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()函数原型
故可以用r_flash_lp_erase()函数进行擦除指定的代码或数据闪存块。
/* 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()函数原型
故可以用r_flash_lp_statusget()函数对code flash或者data flash进行写数据。
/* 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()函数对code flash或者data flash进行写数据。
/* 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()函数原型
对data flash进行写操作时候,数据可以在后台运行,故可以用r_flash_lp_statusget()函数查询是否执行完毕。
/* 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
对code flash进行读写操作时候,特别要注意写的地址,因为如果写的不对,会覆盖到代码区,造成运行错误,同时对于擦除,是一块的数据都会直接擦除掉。
在ra2l1中,code flash有2种规格,分别是128kb和256kb,每块大小为2kb。
为了兼容其他的型号,向block62种写入数据并且读取出来,地址范围是0x0001f000 - 0x0001f800。
使用r_flash_lp_write()写入的时候,写入的是字节为单位,故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
对data flash进行读写操作时候,特别要注意要等待data flash写完才能进行后续读写操作。
在ra2l1中, data flash都是8kb的,每块大小为1kb 。
向block0种写入数据并且读取出来,地址范围是0x40100000 - 0x401003ff。
使用r_flash_lp_write()写入的时候,写入的是字节为单位,故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写入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
向code flash地址0x0001f000写入{0x1a,0x24,0x46,0x6a}和{0xaabbccdd,0x11111111,0x22222222,0x33333333,0x44444444}
通过串口打印出的结果如下所示。
内存地址查询结果如下所示。
21.完整代码
#include hal_data.h#include fsp_cpp_headervoid r_bsp_warmstart(bsp_warm_start_event_t event);fsp_cpp_footerfsp_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)#endifputchar_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++)>原创:by ra_billy xiao
原文标题:瑞萨e2studio----code flash&data flash读写
文章出处:【微信公众号:ra生态工作室】欢迎添加关注!文章转载请注明出处。
一文带你了解工业CT
新AirPods已经准备就绪,设计类似目前的AirPods Pro
用老人机制作夜视仪
计算机将如何影响制造业?
香港国际春灯展云集各国参展商 新增四个展区
瑞萨e2studio----Code Flash/Data Flash读写
LM4836单片立体声电桥音频功率放大器
芳源环保为松下供应三元材料NCA前驱体
最新移动装置设备管理技术
中科创达与亚马逊云科技合作实现物联网平台等技术高效集成
安森美半导体配合市场趋势的无线充电方案
i9-13900K加速频率5.8GHz,单核心2314分、多核心26464分
自行车改装成纯电动
比亚迪半导体荣获2021金翎奖“年度最具影响力品牌”
Redmi Watch小方屏智能手表上线
各种规模飞行任务的耐辐射性筛查
美国的制裁严重损害了华为今年的业务计划
为什么说,光刻机是整个芯片产业的命门呢?
Dialog针对宽带通信ASIC的ADC
多款锐龙4000系列笔记本上架,性价比相当可观