一、条件
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
与大伙沟通交流,技术在于分享而进步