[C] 纯文本查看 复制代码
#if (RTS_FV_DEBUG_ENABLE)
#define local_printf(format,...) printf("[fv] "format,##__VA_ARGS__)
#else
#define local_printf(format,...) do{}while(0)
#endif
/** X.x.x: Major version */
#define RTS_FV_VERSION_MAJOR 1
/** x.X.x: Minor version */
#define RTS_FV_VERSION_MINOR 0
/** x.x.X: Revision*/
#define RTS_FV_VERSION_REVISION 1
#define RTS_FV_MARK_EMPTY 0xFFFFFFFF
#define RTS_FV_MARK_USING 0x55AA55AA
#define RTS_FV_MARK_USELESS 0x00000000
#define RTS_FV_MARK_PART_SIZE 4
#define RTS_FV_CRC__PART_SIZE 4
void rts_fv_init(rts_fv_layout_t *layout,void *data,uint32_t datasize)
{
local_printf("V%d.%d.%d\r\n",RTS_FV_VERSION_MAJOR,RTS_FV_VERSION_MINOR,RTS_FV_VERSION_REVISION);
local_printf("init %s start addr:0x%x total size:%d data size:%d max data num:%d \r\n",
layout->name,layout->addr,layout->size,datasize,layout->size/(RTS_FV_MARK_PART_SIZE+datasize+RTS_FV_CRC__PART_SIZE));
rts_fv_read(layout,data,datasize);
}
void rts_fv_read(rts_fv_layout_t *layout,void *data,uint32_t datasize)
{
uint32_t i=0;
uint32_t fream_size=0;
uint32_t fream_total=0;
uint32_t u32value;
uint32_t crc32;
if(datasize%4)
{
local_printf("datasize must be 4 times\r\n");
return;
}
fream_size=RTS_FV_MARK_PART_SIZE+datasize+RTS_FV_CRC__PART_SIZE;
fream_total=layout->size/fream_size;
if(layout->index>=fream_total)
{
local_printf("index is overflow\r\n");
goto _search_all;
}
//read fream mark part
layout->read(layout->addr+layout->index*fream_size,&u32value,RTS_FV_MARK_PART_SIZE);
if(u32value==RTS_FV_MARK_USING)
{
layout->read(layout->addr+layout->index*fream_size+RTS_FV_MARK_PART_SIZE,data,datasize);
crc32=rts_crc32_calculate(&rts_crc32,data,datasize);
layout->read(layout->addr+layout->index*fream_size+RTS_FV_MARK_PART_SIZE+datasize,&u32value,RTS_FV_CRC__PART_SIZE);
if(u32value==crc32)
{
local_printf("read success\r\n");
return;
}
else
{
local_printf("read check crc32 fail\r\n");
local_printf("set default values\r\n");
if(layout->data_set_default)layout->data_set_default(data,datasize);
else memset(data,0,datasize);
layout->index=fream_total;//set index overflow in rts_fv_write will call erase
rts_fv_write(layout,data,datasize);
return;
}
}
else
{
local_printf("mark is not RTS_FV_MARK_USING\r\n");
goto _search_all;
}
_search_all:
local_printf("search all ...\r\n");
for(i=0;i<fream_total;i++)
{
layout->read(layout->addr+i*fream_size,&u32value,RTS_FV_MARK_PART_SIZE);
if(u32value==RTS_FV_MARK_USING)
{
layout->read(layout->addr+i*fream_size+RTS_FV_MARK_PART_SIZE,data,datasize);
crc32=rts_crc32_calculate(&rts_crc32,data,datasize);
layout->read(layout->addr+i*fream_size+RTS_FV_MARK_PART_SIZE+datasize,&u32value,RTS_FV_CRC__PART_SIZE);
if(u32value==crc32)
{
layout->index=i;
local_printf("read success\r\n");
return;
}
else
{
local_printf("read check crc32 fail\r\n");
local_printf("set default values\r\n");
if(layout->data_set_default)layout->data_set_default(data,datasize);
else memset(data,0,datasize);
layout->index=fream_total;//set index overflow in rts_fv_write will call erase
rts_fv_write(layout,data,datasize);
return;
}
}
}
local_printf("search all done,but not foud,set to default\r\n");
if(layout->data_set_default)layout->data_set_default(data,datasize);
else memset(data,0,datasize);
layout->index=fream_total;//set index overflow in rts_fv_write will call erase
rts_fv_write(layout,data,datasize);
}
void rts_fv_write(rts_fv_layout_t *layout,void *data,uint32_t datasize)
{
uint32_t fream_size=0;
uint32_t fream_total=0;
uint32_t u32value;
uint32_t crc32;
bool is_erase=false;
uint32_t writeIndex=0;
if(datasize%4)
{
local_printf("datasize must be 4 times\r\n");
return;
}
fream_size=RTS_FV_MARK_PART_SIZE+datasize+RTS_FV_CRC__PART_SIZE;
fream_total=layout->size/fream_size;
writeIndex=layout->index+1;
if(writeIndex>=fream_total)
{
local_printf("index overflow erase\r\n");
layout->erase();
writeIndex=0;
is_erase=true;
}
//check is empty ?
layout->read(layout->addr+writeIndex*fream_size,&u32value,RTS_FV_MARK_PART_SIZE);
if(u32value!=RTS_FV_MARK_EMPTY)
{
local_printf("fream not empty erase\r\n");
layout->erase();
writeIndex=0;
is_erase=true;
}
u32value=RTS_FV_MARK_USING;
layout->write(layout->addr+writeIndex*fream_size,&u32value,RTS_FV_MARK_PART_SIZE);
layout->write(layout->addr+writeIndex*fream_size+RTS_FV_MARK_PART_SIZE,data,datasize);
crc32=rts_crc32_calculate(&rts_crc32,data,datasize);
layout->write(layout->addr+writeIndex*fream_size+RTS_FV_MARK_PART_SIZE+datasize,&crc32,RTS_FV_CRC__PART_SIZE);
local_printf("write data(%d) done\r\n",datasize);
if(is_erase==false)
{
u32value=RTS_FV_MARK_USELESS;
layout->write(layout->addr+layout->index*fream_size,&u32value,RTS_FV_MARK_PART_SIZE);
}
layout->index=writeIndex;
local_printf("adjust index(%d) done\r\n",layout->index);
}
#if (RTS_FV_UINT_TEST_ENABLE)
typedef struct
{
uint32_t data0;
uint32_t data1;
uint32_t data2;
uint32_t data3;
uint32_t data4;
uint32_t data5;
uint32_t data6;
uint32_t data7;
uint32_t data8;
uint32_t data9;
}user_data_t;
user_data_t user_data;
void rts_fv_uint_test(rts_fv_layout_t *p_fv_layout)
{
uint8_t u8value;
uint32_t i,j;
uint8_t *pu8;
local_printf("uint test start...\r\n");
rts_fv_init(p_fv_layout,&user_data,sizeof(user_data));
for(i=0;i<(p_fv_layout->size/(RTS_FV_MARK_PART_SIZE+sizeof(user_data)+RTS_FV_CRC__PART_SIZE));i++)
{
u8value+=0x12;
//wtire
memset(&user_data,u8value,sizeof(user_data));
rts_fv_write(p_fv_layout,&user_data,sizeof(user_data));
//read
memset(&user_data,0,sizeof(user_data));
rts_fv_read(p_fv_layout,&user_data,sizeof(user_data));
//check
pu8=(uint8_t *)&user_data;
for(j=0;j<sizeof(user_data);j++)
{
if(*pu8!=u8value)
{
local_printf("rts fv uint test fail\r\n");
return;
}
}
}
local_printf("rts fv uint test success !!\r\n");
}
#endif
#endif