1 Star 4 Fork 8

vtor3478/vtor_elec_module

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
vtor_flash_eeprom.c 5.61 KB
一键复制 编辑 原始数据 按行查看 历史
#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__
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/vtor3478/vtor_elec_module.git
git@gitee.com:vtor3478/vtor_elec_module.git
vtor3478
vtor_elec_module
vtor_elec_module
main

搜索帮助

0d507c66 1850385 C8b1a773 1850385