1.读部分。
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
{
uint16_t ValidPage = PAGE0;
uint16_t AddressValue = 0x5555, ReadStatus = 1;
uint32_t Address = 0, PageStartAddress = 0;
/* Get active Page for read operation */
ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
/* Check if there is no valid page */
if (ValidPage == NO_VALID_PAGE)
{
return NO_VALID_PAGE;
}
/* Get the valid Page start Address */
PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
/* Get the valid Page end Address */
Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
/* Check each active page address starting from end */
while (Address > (PageStartAddress + 2))
{
/* Get the current location content to be compared with virtual address */
AddressValue = (*(__IO uint16_t*)Address);
/* Compare the read address with the virtual address */
if (AddressValue == VirtAddress)
{
/* Get content of Address-2 which is variable value */
*Data = (*(__IO uint16_t*)(Address - 2));
/* In case variable value is read, reset ReadStatus flag */
ReadStatus = 0;
break;
}
else
{
/* Next address location */
Address = Address - 4;
}
}
/* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
return ReadStatus;
}
1.程序找到存储的有效页面.页面从后面开始检索数据,为什么反着找,是因为写的是顺序写的,最新的时候在最后面。
一个数据包含是两个字节的有效数据+两个字节的虚拟地址,这个虚拟地址表示存储的ID。
读取数据每个页面最前面两个是页面的标记位,所以这个两个位不是存储的。
为什么是虚拟地址在后面有效数据在前面,这样设计,设想一下如果数据断电,刚好存储的数据写了,但是虚拟地址没有写,
那么这个数据也是没有效的。
不同的MCU可能在断电写的数据不正常,不排除可能写的是其他有效虚拟地址,所以开机读取数据还是需要做数据合法性检测。
虽然这样的概率很低。
其实前面是标识符只有两个字节有用,为什么用了4个,也是为了对齐,程序好写。