代码拉取完成,页面将自动刷新
#include "vtor_flash_eeprom.h"
#ifdef __VTOR_FLASH_EEPROM__
uint32_t VtorFlashEeprom_GetNewDataAddr(
VtorFlashEeprom* eeprom, uint32_t curAddr)
{
uint32_t nextAddr = curAddr;
// 如果未找到,认为未写过eeprom,指向开头
if(0x00000000 == nextAddr)
{
nextAddr = eeprom->flashStartAddress;
}
else
{
// 否则指向下一个eeprom偏移
nextAddr += eeprom->eepromSize;
}
if(nextAddr >= eeprom->flashStartAddress
+ eeprom->flashPageSize * eeprom->flashPageCnt)
{
nextAddr = eeprom->flashStartAddress; // 越界了,修正到开始地址
}
// 必须处于页边界才执行擦除操作
if(0 == nextAddr % eeprom->flashPageSize)
{
// 如果发现下一个地址有有效数据,那么执行擦除
if(VtorFlash_CheckValid(nextAddr, eeprom->flashPageSize))
{
VtorFlash_Erase(nextAddr);
}
}
else
{
// 非page边界发现eeprompage被写过,跳到下一个flashpage
if(VtorFlash_CheckValid(nextAddr, eeprom->eepromSize))
{
uint32_t flashIdx = nextAddr / eeprom->flashPageSize;
nextAddr = flashIdx * eeprom->flashPageSize
- eeprom->eepromSize;
// 重入执行,确保边界正常
nextAddr = VtorFlashEeprom_GetNewDataAddr(eeprom, nextAddr);
}
}
return nextAddr;
}
// 寻找最新可用的数据地址
uint32_t VtorFlashEeprom_GetCurDataAddr(VtorFlashEeprom* eeprom)
{
// 把最大idx的地址存储在curAddr内
uint32_t maxEepromAddr = 0x00000000;
uint32_t maxEepromIdx = 0;
// 根据flash页偏移,寻找基础地址
for(uint32_t flashIdx = 0; flashIdx < eeprom->flashPageCnt; flashIdx++)
{
uint32_t flashBaseAddr = eeprom->flashStartAddress
+ flashIdx * eeprom->flashPageSize;
for(uint32_t eepromIdx = 0;
eepromIdx < eeprom->flashPageSize / eeprom->eepromSize; eepromIdx++)
{
uint32_t flashAddr = flashBaseAddr + eepromIdx * eeprom->eepromSize;
// 从前往后,发现全f,说明当前flashpage没数据,不再需要扫描
VtorFlashEepromData* eepromData = (VtorFlashEepromData*)flashAddr;
// 如果两者不是互为反码,认为校验失败
if(eepromData->idx != -eepromData->revIdx)
{
break;
}
if(0x00000000 == maxEepromAddr)
{
maxEepromAddr = flashAddr;
maxEepromIdx = eepromData->idx;
}
else
{
uint32_t eepromDataOverflow = 0;
uint32_t maxOverflow = 0;
if(eepromData->idx < VTOR_EEPROM_LITTLE
&& maxEepromIdx > VTOR_EEPROM_BIG)
{
eepromDataOverflow = VTOR_EEPROM_MAX;
}
if(eepromData->idx > VTOR_EEPROM_BIG
&& maxEepromIdx < VTOR_EEPROM_LITTLE)
{
maxOverflow = VTOR_EEPROM_MAX;
}
// 如果id相同,也以后面的为最新,所以允许相等情况
if(eepromData->idx + eepromDataOverflow
>= maxEepromIdx + maxOverflow)
{
maxEepromAddr = flashAddr;
maxEepromIdx = eepromData->idx;
}
}
//VtorDebugChanPrintf("max[%x]=%d\r\n", maxEepromAddr, maxEepromIdx);
}
}
return maxEepromAddr;
}
// eeprom只提供read与write方法
uint32_t VtorFlashEeprom_Read(
VtorFlashEeprom* eeprom, void* data, uint32_t len)
{
uint32_t readAddr = VtorFlashEeprom_GetCurDataAddr(eeprom);
uint32_t retAddr = VtorFlash_Read(readAddr, data, len);
//VtorDebugChanPrintf("VtorFlashEeprom_Read [%x] = %d, ret %x\r\n",
// readAddr, eepromData->idx, retAddr);
return retAddr;
}
uint32_t VtorFlashEeprom_Write(
VtorFlashEeprom* eeprom, void* data, uint32_t len)
{
VtorFlashEepromData* eepromData = (VtorFlashEepromData*)data;
// 写之前保证idx变化,同时防止id溢出
eepromData->idx++;
eepromData->idx %= VTOR_EEPROM_MAX;
// 设置反码
eepromData->revIdx = -eepromData->idx;
uint32_t curAddr = VtorFlashEeprom_GetCurDataAddr(eeprom);
uint32_t newAddr = VtorFlashEeprom_GetNewDataAddr(eeprom, curAddr);
uint32_t retAddr = VtorFlash_Write(newAddr, data, len);
//VtorDebugChanPrintf("VtorFlashEeprom_Write [%x->%x] = %d, ret %x\r\n",
// curAddr, newAddr, eepromData->idx, retAddr);
return retAddr;
}
uint32_t VtorFlashEeprom_Erase(VtorFlashEeprom* eeprom)
{
for(uint32_t flashIdx = 0; flashIdx < eeprom->flashPageCnt; flashIdx++)
{
uint32_t flashBaseAddr = eeprom->flashStartAddress
+ flashIdx * eeprom->flashPageSize;
VtorFlash_Erase(flashBaseAddr);
}
return eeprom->flashStartAddress;
}
void VtorFlashEeprom_Scan(VtorFlashEeprom* eeprom)
{
// 根据flash页偏移,寻找基础地址
for(uint32_t flashIdx = 0; flashIdx < eeprom->flashPageCnt; flashIdx++)
{
uint32_t flashBaseAddr = eeprom->flashStartAddress
+ flashIdx * eeprom->flashPageSize;
for(uint32_t eepromIdx = 0;
eepromIdx < eeprom->flashPageSize / eeprom->eepromSize; eepromIdx++)
{
uint32_t flashAddr = flashBaseAddr + eepromIdx * eeprom->eepromSize;
VtorFlashEepromData* eepromData = (VtorFlashEepromData*)flashAddr;
VtorDebugChanPrintf("[%x] = %x(%d), %d\r\n", flashAddr,
eepromData->idx, eepromData->idx, eepromData->revIdx);
}
}
}
uint32_t VtorFlashEeprom_Test(VtorFlashEeprom* eeprom)
{
uint32_t wData[5] = {8800};
uint32_t rData[5] = {8700};
// 读出,修改再写入,保证测试顺利运行
VtorFlashEeprom_Read(eeprom, wData, sizeof(wData));
uint32_t writeAddr = VtorFlashEeprom_Write(eeprom, wData, sizeof(wData));
// 再读出进行对比,确保更新没问题
uint32_t readAddr = VtorFlashEeprom_Read(eeprom, rData, sizeof(rData));
VtorFlashEepromData* wEepromData = (VtorFlashEepromData*)wData;
VtorFlashEepromData* rEepromData = (VtorFlashEepromData*)rData;
if(writeAddr != readAddr || wEepromData->idx != rEepromData->idx)
{
VtorDebugChanPrintf("write %x %x\r\n", writeAddr, wEepromData->idx);
VtorDebugChanPrintf("read %x %x\r\n", readAddr, rEepromData->idx);
}
return readAddr;
}
#endif // __VTOR_FLASH_EEPROM__
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。