源码下载地址:
//Flash中可存储的历史记录数量
#define RECORD_SIZE 500
//进行历史记录索引区整理时,flash中存储已发送历史记录数量需满足条件
#define SET_INDEX_BUF_COND 100
Flash中每个扇区大小
#define FLASH_SECTOR_SIZE 4096
#define NOUP_RECORD_INDEX_SECTOR1 0x2B000 //未发送历史记录索引存储扇区1地址,空间大小4k
#define NOUP_RECORD_INDEX_SECTOR2 0x2C000 //未发送历史记录索引存储扇区2地址,空间大小4k
#define HIS_RECORD_DATA_BASE_ADDR 0x2D000 //未发送历史记录索引存储扇区2地址,空间大小4k,需要保留5个4096作为数据
//未发送历史记录索引结构
typedef struct
{
u8 bIdentify; //标识符
u8 rsv; //发送表示符
u16 wIndex;
} NO_UP_RECORD_INDEX_T;
//未发送历史记录索引存储扇区起始地址,默认选择扇区1
extern u32 np_record_index_sec_base;
//查看历史记录,已发送数据总数
extern u16 F_Get_Send_Record_Num(u32 cur_sector_addr);
//查看历史记录,未发送数据总数
extern u16 F_Get_Noup_Record_Num(u32 cur_sector_addr);
//查看历史记录,已发送+未发送 数据总数
extern u16 F_Get_Total_Record_Num(u32 cur_sector_addr);
//查看历史数据索引-靠近当前时间的一条索引,获取流水号
extern u16 F_Get_Record_Index(u32 cur_sector_addr);//
//查看历史数据索引-远离当前时间的一条索引
extern u16 F_Get_Noup_Record_Index(u32 cur_sector_addr);
//增加一个未发送历史记录索引
extern u8 F_Add_Noup_Record_Index(u16 index, u32 cur_sector_addr);
//将一个未发送历史记录索引置为已发送
extern u8 F_Set_Record_Index_Send(u16 index, u32 cur_sector_addr);
//开机进行存储区整理
extern void F_Set_Buf_PowerOn(void);
//查看当前是否需要整理历史记录索引存储区
extern u8 F_Check_Set_Record_Index_Buf(void);
//整理未发送历史记录索引存储区
extern u8 F_Set_Noup_Record_Buf(void);
//检查是否需要整理数据记录存储区
extern u8 F_Check_Set_Record_Buf(void);
//擦除历史数据记录区
extern void F_Erase_Record_Buf(void);
//向flash中写入一个新的数据记录
extern u8 F_Write_New_Record(u8* record, u16 index);
//从flash中读取一个数据记录
extern u8 F_Read_Record(uint8_t* record, u16 index);
测试流程
①开机调用初始化函数
F_Set_Buf_PowerOn();
②写数据
osal_memset(write_record_flash_buf,0x55,sizeof(write_record_flash_buf));
write_record_flash_buf[0]=write_record_flash_index1;
write_record_flash_buf[1]=write_record_flash_index2;
uart_test_write_flash(write_record_flash_buf);
write_record_flash_index1++;
if (write_record_flash_index1>250)
{
write_record_flash_index2++;
write_record_flash_index1=0;
}
uint8_t write_record_flash_buf[32];
uint8_t write_record_flash_index1=0;
uint8_t write_record_flash_index2=0;
void uart_test_write_flash(uint8_t *p_data)
{
u16 cur_index = 0;
u16 total_index = 0;
u16 crc_val = 0;
u8 write_times = 5;
u16 record_index = 0;
u8 resutl =0;
total_index = F_Get_Noup_Record_Num(np_record_index_sec_base);
if(total_index >= 200)
{
record_index = F_Get_Noup_Record_Index(np_record_index_sec_base);
if(record_index > 639)
{
user_printf_level1("-->error:%d cur index>639\r\n",__LINE__);
return;
}
resutl = F_Set_Record_Index_Send(record_index, np_record_index_sec_base);
user_printf_level2("->^_^ del index:%d\r\n",record_index);
if (resutl)user_printf_level2("->error del index:%d\r\n",record_index);
}
//获取当前流水号
cur_index = F_Get_Record_Index(np_record_index_sec_base);
user_printf_level2("->cur index =%d\r\n", cur_index);
if (cur_index == 0x55AA)
{ //没有任何数据
user_printf_level1("->index buf is empty!\r\n");
cur_index = 0;
} else if (cur_index > 639)
{ //
user_printf_level1("-->error:%d cur index>639\r\n",__LINE__);
return;
} else
{
cur_index++;
}
//查看当前索引值是否为数据记录空间最大流水号,如是则置零
if (cur_index == 640)
{
cur_index = 0;
}
//查看是否需要整理历史记录存储区
F_Check_Set_Record_Buf();
//查看是否需要整理历史记录索引存储区
if (!F_Check_Set_Record_Index_Buf())
{ //2块4k FLASH管理下表
//进行历史记录索引存储区整理
if (F_Set_Noup_Record_Buf())
{
user_printf_level1("->eorror set no up record buf fail!\r\n");
}
}
total_index = F_Get_Total_Record_Num(np_record_index_sec_base);
if(total_index >= RECORD_SIZE)
{
user_printf_level2("->^_^ total index%d\r\n",total_index);
return ;
}
///
p_data[2] = cur_index>>8;
p_data[3] = cur_index;
crc_val = fals_calcCrc16(p_data, 30);
p_data[30]=crc_val>>8;
p_data[31]=crc_val;
//向flash中写入记录
while (write_times)
{ //最多写write_times次
//向索引区增加一个索引值,且写入记录成功
if (!F_Add_Noup_Record_Index(cur_index, np_record_index_sec_base))
{ //写索引成功
if (!F_Write_New_Record(p_data, cur_index))//写入记录成功
{
break;
} else
{
user_printf_level1("->error add a record fail!,%d\r\n",write_times);
}
}
//将该写入记录置为已发送
resutl = F_Set_Record_Index_Send(cur_index, np_record_index_sec_base);
if (resutl)user_printf_level2("->del index:%d\r\n",record_index);
cur_index++;
if(cur_index == 640)
{
cur_index = 0;
}
write_times--;
}
}
③读数据
uint8_t read_record_flash_buf[32];
uint16_t uart_test_read_flash(void)//read flash && ble send
{
u16 data_remain = 0;
u16 record_index = 0;
u16 crc_val = 0;
u16 crc_get = 0;
u16 index_get=0;
data_remain = F_Get_Noup_Record_Num(np_record_index_sec_base);
if (data_remain == 0)
{
user_printf_level2("->^_^ uart_test_read_flash empty\r\n",__LINE__);
return 0;
}
record_index = F_Get_Noup_Record_Index(np_record_index_sec_base);
if(record_index > 639)
{
user_printf_level2("->error:%d record index>639\r\n",__LINE__);
return 0;
}
F_Read_Record(read_record_flash_buf, record_index);
crc_val = fals_calcCrc16(read_record_flash_buf, 30);
crc_get = (read_record_flash_buf[30]<<8);
crc_get |= read_record_flash_buf[31];
index_get = (read_record_flash_buf[2]<<8);
index_get |= read_record_flash_buf[3];
if((index_get != record_index)||(crc_val != crc_get))
{
F_Set_Record_Index_Send(record_index, np_record_index_sec_base);
if (index_get != record_index) user_printf_level2("->error get index\r\n");
if (crc_val != crc_get) user_printf_level2("->error get crc\r\n");
return 0;
}
user_printf_level2("->data %03d,%03d,%d\r\n",\
read_record_flash_buf[0],read_record_flash_buf[1],\
index_get);
if (F_Set_Record_Index_Send(record_index, np_record_index_sec_base))
{
user_printf_level2("->error del one record\r\n");
}
return data_remain;
}
④擦除所有数据
F_Erase_Record_Buf();
F_Set_Buf_PowerOn();