nRF52笔记(4) flash操作函数

一、条件

1、软件:sdk14.2
2、硬件:52832

操作次数
在这里插入图片描述

二、函数的调用步骤

1.注册一个回调函数,由于读、写函数涉及到协议栈内部的事件,所以为了观察是否成功

static bool write_success=0; // 写入成功判断标志位
void call_by_sys_flash_manage(uint32_t sys_evt,void * p_context)
{
    if(NRF_EVT_FLASH_OPERATION_SUCCESS==sys_evt)
        write_success=true;
}

void set_before_operation(void)
{
    write_success=false;
}

// 协议栈观察事件

NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, call_by_sys_flash_manage, NULL); 

放在这里
在这里插入图片描述

2:等待flash 写入成功

bool wait_after_operation(void)
{
    uint32_t i;
    //if(is_softdevice_enable()==false) return true;
    for(i=0; i<10000; i++)
    {
        nrf_delay_us(100);
        if(write_success==true)
            return true;
    }

    FLASH_RTT("flash operation timeout ---\r\n");
    return false;
}

3、检查地址是否在有效范围

bool CheckAddr(uint32_t addr)
{
    if( (addr>=APPBVK_ADDR)&&(addr<BOOT_ADDR))
    {
        return true;

    }
    return false;
}

4、flash擦除函数,记得(52832-4k一页)

bool Flash_Erase_Page(uint32_t Page_Num)
{
    uint32_t addr;
    uint8_t flash_erase_flag;
    addr=Page_Num*PAGE_SIZE;

    flash_erase_flag=flash_erase_flag;
	
    if(true==CheckAddr((uint32_t)addr))
    {
		FLASH_RTT("ERASE PAGE:%d\r\n",Page_Num);
        set_before_operation();
		

		
        flash_erase_flag=sd_flash_page_erase(Page_Num);
  
        FLASH_RTT("erase page :%d  result:0x%x\r\n",Page_Num,flash_erase_flag);
        nrf_delay_ms(50);
        return wait_after_operation();
    }
    return false;
}

5、flash写入函数

bool Flash_Write_World(uint32_t *addr,uint32_t *Data_Buf,uint32_t len)
{
    uint8_t flash_write_flag;
    flash_write_flag = flash_write_flag;
	
    if(true==CheckAddr((uint32_t)addr))
    {
		FLASH_RTT("flash write:%x page:%d len:%d\r\n",(uint32_t )addr,((uint32_t )addr)/4096,len);
		
        set_before_operation();
		
        flash_write_flag=sd_flash_write(addr,Data_Buf,len);
		
        if(0!=flash_write_flag)
        {
//            FLASH_RTT("write:%x\r\n",flash_write_flag);
        }
        return wait_after_operation();
    }
    return false;
}

6、flash 读取函数

void InflashRead(uint8_t *buf,uint32_t addr,uint16_t len)
{
    uint16_t i;
    const uint8_t *pdata;
    pdata=(uint8_t*)addr;
    for(i=0; i<len; i++)
        buf[i]=pdata[i];

}

三、使用例子代码

1、申明 flash 地址

#define HIS_ADDR        (RSV1_ADDR-4096)// 2d000   // store user data is ok  
#define HIS_ADDR_SIZE   (4*1024)

#define RSV1_ADDR        (RSV2_ADDR-4096)// 2E000
#define RSV1_ADDR_SIZE   (4*1024)

#define RSV2_ADDR        (BOOT_ADDR-4096)  // 2F000
#define RSV2_ADDR_SIZE   (4*1024)

#define BOOT_ADDR        (512*1024-4096)
#define BOOT_ADDR_SIZE   (4*1024)


#define PAGE_SIZE  4096UL
#define FACTORY_SET_HEAD 0xaaaaaaaa  // 定义写入数据头,来确定确定flash写入数据,方便读取用

定义一个结构体:
typedef struct
{
    uint8_t data1;
    uint8_t data2;
} STU_HIS;


2、写入函数


STU_HIS StuHis; //结构体
void Write_flash(uint8_t mode)
{
	uint32_t buf[BUF_LEN];
    uint8_t *pdata;
    uint8_t *pdata_src;
	uint16_t len_real = 0;
	uint8_t i;
	
	uint32_t data_head=FACTORY_SET_HEAD;
	
	len_real=sizeof(StuHis);
	
	pdata=(uint8_t*)buf; //  buff 
	
	pdata_src=(uint8_t*)&StuHis;   //
	
    for( i=0; i<len_real;i++)
    {
        pdata[i]=pdata_src[i];
    }
	Flash_Erase_Page(HIS_ADDR/PAGE_SIZE); // 擦除flash
    Flash_Write_World((uint32_t *)(HIS_ADDR),buf,BUF_LEN);
}

3、flash 读取

void Read_flash8757(void)
{
    // read flash data
	uint8_t read_buf[sizeof(StuHis)] ;
    memset(read_buf, 0, sizeof(StuHis)); // set 0x00
	InflashRead((uint8_t*)read_buf,HIS_ADDR,BUF_LEN*4); // flash data HIS_ADDR RSV1_ADDR
}
uint32_t Flash_buf[HIS_BUF_LEN];//==================>>>>>>>>>  4×Ö½Ú¶ÔÆë RSV1_ADDR Ö±½Ó²Ù×÷flash
void Read_user_flash(void)
{
	uint8_t flash_buf[sizeof(STU_HIS)] = {0};

	memset(Flash_buf,0,HIS_BUF_LEN);
	
	
	InflashRead((uint8_t*)Flash_buf,HIS_ADDR,HIS_BUF_LEN*4); 
	
	memcpy(flash_buf,Flash_buf,HIS_BUF_LEN*4);
	
	if(*((uint32_t *)HIS_ADDR) == FACTORY_SET_HEAD)
	{
		memset(&StuHis,0,sizeof(STU_HIS));
        memcpy((uint8_t *)&StuHis,flash_buf+4, sizeof(STU_HIS));
		BSP_RTT("flash: read HIS_ADDR data.... \r\n");

	}
	else
	{
	     init_user_data();
		BSP_RTT("flash: init_user_data \r\n");
	}	
}
/**********************************************
*
*
******************************************/
void Write_user_flash(uint8_t mode)
{
	uint32_t buf[HIS_BUF_LEN];
    uint8_t *pdata;
    uint8_t *pdata_src;
	uint16_t len_real = 0;
	uint32_t i;
	
	uint32_t data_head=FACTORY_SET_HEAD;
	

	len_real=sizeof(STU_HIS);
	
	pdata=(uint8_t *)buf; //  buff 
	pdata_src=(uint8_t *)&StuHis;   // 
	
    for( i=0; i<len_real;i++)
    {
        pdata[i]=pdata_src[i];
    }
	
    if(mode==1)
	{
		Flash_Erase_Page(HIS_ADDR/PAGE_SIZE);
		Flash_Write_World((uint32_t *)(HIS_ADDR),&data_head,1);	
        Flash_Write_World((uint32_t *)(HIS_ADDR+4),buf,HIS_BUF_LEN);		
	}

	mode = 0;
}

四 注意点

注意写入的数据不能超过整个flash的范围,擦除是4k,51822是1k

可以加入QQ群:687360507
与大伙沟通交流,技术在于分享而进步

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值