ZHCAEX4 January 2025 F29H850TU , F29H859TU-Q1
EEPROM_GetValidBank() 函数的功能是查找当前 EEPROM 组和页面。EEPROM_Write_Page() 和 EEPROM_Read() 函数都会调用此函数。GetValidBank 流程展示了搜索当前 EEPROM 组和页面所需的总体流程。
图 6-1 GetValidBank 流程进入此函数时,EEPROM 组指针和页面指针被设置为 FIRST_AND_LAST_SECTOR 中指定的第一个扇区的开头:
RESET_BANK_POINTER;
RESET_PAGE_POINTER;
这些指针的地址在 EEPROM_Config.h 文件中针对所使用的特定器件和 EEPROM 配置进行定义。
接下来,会找到当前 EEPROM 组。如 GetValidBank 流程所示,EEPROM 组可以具有三种不同的状态:空、当前和已使用。
空 EEPROM 组由 128 个状态位全部为 1 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) 表示。当前 EEPROM 组由最高有效 64 位被设置为 0x5A5A5A5A5A5A5A5A、其余 64 位被设置为 1 (0x5A5A5A5A5A5A5A5AFFFFFFFFFFFFFFFF) 表示。已使用的 EERPOM 组由全部 128 位被设置为 0x5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A 表示。可以根据需要更改这些值。
首先,程序会检查是否有空的 EEPROM 组。如果遇到此状态,则表示该 EEPROM 组尚未使用,无需进一步搜索。
if (Bank_in_Use == EMPTY_BANK)
{
Bank_Counter = i;
return;
}
如果未遇到空的 EEPROM 组,则接下来会检查当前状态。如果存在,则会相应地更新 EEPROM 组计数器,并且页面指针被设置为 EEPROM 组的第一页,以启用对当前页面的测试。然后退出该循环,因为不需要进一步的搜索。
if (Bank_in_Use == CURRENT_BANK && Bank_Full != CURRENT_BANK)
{
Bank_Counter = i;
Page_Pointer = Bank_Pointer + WRITE_SIZE_BYTES*2;
break;
}
最后,检查是否有“已使用”状态。在这种情况下,EEPROM 组已使用,EEPROM 组指针更新到下一个 EEPROM 组,以测试其状态。
if (Bank_in_Use == CURRENT_BANK && Bank_Full == CURRENT_BANK)
{
Bank_Pointer += Bank_Size;
}
找到当前 EEPROM 组后,需要找到当前页面。一个页面可以具有三种不同的状态:空、当前和已使用。
空页面由 128 个状态位全为 1 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) 表示。当前页面由最高有效 64 位被设置为 0xA5A5A5A5A5A5A5A5、其余 64 位被设置为 1 (0xA5A5A5A5A5A5A5A5FFFFFFFFFFFFFFFFF) 表示。已使用的页面由全部 128 位被设置为 0xA5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5 表示。可以根据需要更改这些值。
首先查找“空”和“当前”状态。如果页面的当前状态为这两种状态之一,则表示找到了正确的页面,并退出该循环,因为不需要进一步的搜索。
if (Page_in_Use == BLANK_PAGE)
{
Page_Counter = i;
break;
}
if (Page_in_Use == CURRENT_PAGE && Page_Full != CURRENT_PAGE)
{
Page_Counter = i + 1;
break;
}
如果页面状态不是这两种状态中的任何一种,则唯一的其他可能性是“已使用的页面”。在这种情况下,页面指针会更新到下一个页面,以测试其状态。
Page_Pointer += WRITE_SIZE_BYTES*2 + EEPROM_PAGE_DATA_SIZE;
此时,当前 EEPROM 组和页面已找到,调用函数可以继续运行。最后,此函数将会检查是否所有 EEPROM 组和页面均已使用。这种情况下,需要擦除该扇区。将完整单元中的最后一个组和页面标记为用于完整性,切换活动单元,重新配置写入/擦除保护掩码、并设置 Erase_Inactive_Unit 标志。
if (!ReadFlag && Bank_Counter == NUM_EEPROM_BANKS - 1 && Page_Counter == NUM_EEPROM_PAGES)
{
EEPROM_UpdatePageStatus();
EEPROM_UpdateBankStatus();
EEPROM_ACTIVE_UNIT ^= 1;
Set_Protection_Masks();
Erase_Inactive_Unit = 1;
RESET_BANK_POINTER;
RESET_PAGE_POINTER;
}
可以通过测试 EEPROM 组和页面计数器来执行该检查。表示已满 EEPROM 的 EEPROM 组和页面的数量取决于应用。如上述代码片段中所示针对当前 EEPROM 组和页面执行测试时,会设置这些计数器。然而,当设置了 Read_Flag 时,不会进行此检查。这是为了防止在从已满 EEPROM 单元读取时过早擦除非活动 EEPROM 单元。