高级会员

- 积分
- 901
- 金钱
- 901
- 注册时间
- 2015-12-24
- 在线时间
- 197 小时
|
3金钱
背景:
我要做一个记录器,使用片外W25Q128做数据存储,设计是这样的,系统参数保存在一个大小为32Byte的结构体中,每个扇区可以存128次,存满清空,读取时读取最后一次保存的值,此功能目前已经实现,参数保存在0x000000-0x000FFF的扇区中。
另外,要存储若干条数据,每条数据的结构体大小为16字节,每扇区存储256条,目前使用0x002000-0x016000存储,共20扇区,计5120条数据,使用循环队列式的结构,写满后擦除下一个扇区继续写入,至最后一个扇区时返回头部。
问题:
不知道写入失败还是读取失败,独处的数据记录全是0xFF,代码用的是原子战舰开发板的示例代码。
源代码如下,请大家指正:
读取系统设置参数(成功)
void GLB_ReadSystemParameter(void)
{
uint32_t uiDataIndex = 0;
GLB_SYSPARAMETER stSystemParameterRead;
uint32_t uiAddress;
GLB_DATAITEM stDataItemDataCmp = {0x00};
#ifdef DBG_OUT
RTC_CALENDAR_STRUCT stDBGCleandar;
#endif
// Read system parameter.
while(uiDataIndex < 128)
{
uiAddress = SYSCFG_ADDRESS + (uiDataIndex * sizeof(GLB_SYSPARAMETER));
FLASH_ReadArray((uint8_t*)(&stSystemParameterRead), uiAddress, sizeof(GLB_SYSPARAMETER));
if(stSystemParameterRead.Index == 0xFFFFFFFF)
{
if(uiDataIndex == 0)
{
// No parameter set, load default value.
stSystemParameterRead.Index = 1;
stSystemParameterRead.FirstSectorIndex = (DATA_SECTOR_NUMBER - 1); //First index is 0;
stSystemParameterRead.LastSectorIndex = 0; //Set start sector index is last sector.
stSystemParameterRead.DataCursor = 0;
stSystemParameterRead.Magnification = 1.0;
stSystemParameterRead.SaveTime = 2;
memcpy(&gstSystemParameter, &stSystemParameterRead, sizeof(gstSystemParameter));
break;
}
else
{
// Read invalid parameter data, save last read.
break;
}
}
else
{
// Copy currant data to global parameter data.
memcpy(&gstSystemParameter, &stSystemParameterRead, sizeof(gstSystemParameter));
uiDataIndex ++;
}
}
#ifdef DBG_OUT
printf("Read parameter...\r\n");
printf(" Index: %u.\r\n", gstSystemParameter.Index);
printf(" SaveTime: %2u.\r\n", gstSystemParameter.SaveTime);
printf(" FirstSectorIndex: %u\r\n", gstSystemParameter.FirstSectorIndex);
printf(" LastSectorIndex: %u\r\n", gstSystemParameter.LastSectorIndex);
printf(" LastDataInSector: %u\r\n", gstSystemParameter.DataCursor);
#endif
// Read Last counter.
printf("Read data record...\r\n");
uiAddress = DATA_START_ADDRESS + (gstSystemParameter.LastSectorIndex*4096) + (gstSystemParameter.DataCursor * sizeof(GLB_DATAITEM));
FLASH_ReadArray((uint8_t*)(&stDataItemDataCmp), uiAddress, sizeof(GLB_DATAITEM));
if(stDataItemDataCmp.Index == 0xFFFFFFFF)
{
printf("Invalid data record.\r\n");
guiCounter = 0;
}
else
{
#ifdef DBG_OUT
printf(" Index: %u.\r\n", stDataItemDataCmp.Index);
memcpy(&stDBGCleandar, RTC_ConvertToCalendar(stDataItemDataCmp.TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
printf(" Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
printf(" Value: %8.2f\r\n", stDataItemDataCmp.Value);
#endif
// Recover records.
guiCounter = stDataItemDataCmp.Value;
memcpy(&gstDataItemData, &stDataItemDataCmp, sizeof(GLB_DATAITEM));
}
}
保存系统设置参数(成功)
void GLB_SaveSystemParameter(void)
{
uint32_t uiDataIndex = 0;
uint32_t uiAddress;
GLB_SYSPARAMETER stSystemParameterRead;
while(1)
{
uiAddress = SYSCFG_ADDRESS + (uiDataIndex * sizeof(GLB_SYSPARAMETER));
FLASH_ReadArray((uint8_t*)(&stSystemParameterRead), uiAddress, sizeof(gstSystemParameter));
if(stSystemParameterRead.Index == 0xFFFFFFFF)
{
if(uiDataIndex < 128)
{
// System parameter area is not full.
gstSystemParameter.Index ++;
FLASH_WriteArray((uint8_t*)(&gstSystemParameter), uiAddress, sizeof(gstSystemParameter));
}
else
{
// System parameter area is full, clear before rewrite.
printf("System parameter area is full, clear and rewrite.\r\n");
FLASH_EraseSector(SYSCFG_ADDRESS / 4096);
gstSystemParameter.Index = 1;
FLASH_WriteArray((uint8_t*)(&gstSystemParameter), SYSCFG_ADDRESS, sizeof(gstSystemParameter));
}
break;
}
else
{
uiDataIndex ++;
}
}
#ifdef DBG_OUT
printf("Write parameter to address 0x%08X\r\n", uiAddress);
printf(" Index: %u.\r\n", gstSystemParameter.Index);
printf(" SaveTime: %2u.\r\n", gstSystemParameter.SaveTime);
printf(" FirstSectorIndex: %u\r\n", gstSystemParameter.FirstSectorIndex);
printf(" LastSectorIndex: %u\r\n", gstSystemParameter.LastSectorIndex);
printf(" LastDataInSector: %u\r\n", gstSystemParameter.DataCursor);
#endif
}
保存数据函数(有问题)
void GLB_SaveDataItem(GLB_DATAITEM* pData)
{
uint32_t uiDataAddress;
#ifdef DBG_OUT
RTC_CALENDAR_STRUCT stDBGCleandar;
GLB_DATAITEM stDataItemDataCmp = {0x00};
#endif
// Update data cursor.
gstSystemParameter.DataCursor ++;
if(gstSystemParameter.DataCursor < (4096 / sizeof(GLB_DATAITEM)))
{
// Data address is in current sector.
}
else
{
// Current sector is full, turn to next sector.
gstSystemParameter.LastSectorIndex ++;
gstSystemParameter.LastSectorIndex %= DATA_SECTOR_NUMBER;
gstSystemParameter.DataCursor = 0;
}
// Check current sector is full.
if(gstSystemParameter.LastSectorIndex == gstSystemParameter.FirstSectorIndex)
{
printf("Current data sector(%d) is full.\r\n", gstSystemParameter.LastSectorIndex);
// First sector turn to next.
gstSystemParameter.FirstSectorIndex ++;
gstSystemParameter.FirstSectorIndex %= DATA_SECTOR_NUMBER;
// Erase current sector.
FLASH_EraseSector((DATA_START_ADDRESS / 4096) + gstSystemParameter.LastSectorIndex);
}
// Get save address.
uiDataAddress = DATA_START_ADDRESS+(gstSystemParameter.LastSectorIndex*4096)+(gstSystemParameter.DataCursor * sizeof(GLB_DATAITEM));
// Update index.
gstDataItemData.Index ++;
// Update Now time.
gstDataItemData.TimeStamp = RTC_GetNowTimeStamp();
// Write to data area;
FLASH_WriteArray((uint8_t*)pData, uiDataAddress, sizeof(GLB_DATAITEM));
#ifdef DBG_OUT
// DBG log.
printf("Write data to address %u(0x%08X).\r\n", uiDataAddress, uiDataAddress);
printf(" Index: %u, Value: %8.2f.\r\n", pData->Index, pData->Value);
memcpy(&stDBGCleandar, RTC_ConvertToCalendar(pData->TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
printf(" Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
// Check data.
FLASH_ReadArray((uint8_t*)(&stDataItemDataCmp), uiDataAddress, sizeof(GLB_DATAITEM));
printf("Check data read from address %u(0x%08X).\r\n", uiDataAddress, uiDataAddress);
printf(" Index: %u, Value: %8.2f.\r\n", stDataItemDataCmp.Index, stDataItemDataCmp.Value);
memcpy(&stDBGCleandar, RTC_ConvertToCalendar(stDataItemDataCmp.TimeStamp), sizeof(RTC_CALENDAR_STRUCT));
printf(" Time: %04u-%02u-%02u %02u:%02u:%02u.\r\n", stDBGCleandar.tm_year, stDBGCleandar.tm_mon, stDBGCleandar.tm_mday, stDBGCleandar.tm_hour, stDBGCleandar.tm_min, stDBGCleandar.tm_sec);
#endif
printf("Write data finished.\r\n");
}
|
|