Idea taka zapisana jest w nocie aplikacyjnej AN2594.
Wymaga ona lekkiego wyjaśnienia (mam nadzieję, że dobrze zrozumiałem to co autorzy mieli na myśli i że nie popełnię jakiegoś błędu).
Otóż według rozwiązania zaproponowanego w tej nocie pamięć EEPROM jest emulowana w postaci dwóch lub więcej stron pamięci FLASH. Strony rozpoczynają się od adresu EEPROM_START_ADDRESS (plik eeprom.h) i dla procesorków podrodziny LOW_DENSITY i MEDIUM_DENSITY mają rozmiar 1 kB, a dla podrodziny HIGH_DENSITY 2kB.
Każda strona posiada na początku dwa bajty statusu: ERASED (pusta strona), RECEIVE_DATA (strona pobiera dane z innej pełnej strony), VALID_PAGE (strona zawiera ważne dane).
Dane zapisywane są do kolejnych komórek danej strony w formacie 2 bajty danych + 2 bajty adresu wirtualnego tych danych, aż do zapełnienia danej strony.
Tak np. wyglądać będą kolejne komórki pamięci zapisywane kolejnymi wartościami zmiennej o tym samym adresie wirtualnym np. 0x0005
Strona | Adres fizyczny | Wartość zmiennej | Adres wirtualny |
0 | 0x08010002 | wartość1 | 0x0005 |
0 | 0x08010006 | wartość2 | 0x0005 |
0 | 0x0801000A | wartość3 |
0x0005 |
Przy odczycie wartości o adresie wirtualnym 0x0005 strona zostanie przeszukana i zrwrócona zostanie ostatnia wartość (wartość3) o tym adresie (wartość ostatnio zapisana).
Gdy będziemy chcieli zapisać następną daną o innym adresie wirtualnym (np. 0x0006) to zostanie ona wpisana w następne wolne miejsce, czyli:
Strona | Adres fizyczny | Wartość | Adres wirtualny |
0 | 0x0801000E | wartość1 | 0x0006 |
W momencie gdy strona się zapełni następuje skopiowanie najbardziej aktualnych wartości jej zmiennych do następnej wolnej strony, po czym zostaje ona skasowana. W nowej stronie mamy następujące wpisy:
Strona | Adres fizyczny | Wartość | Adres wirtualny |
1 | 0x08010402 | wartość3 | 0x0005 |
1 | 0x08010406 | wartość1 | 0x0006 |
Następne wpisy trafiają już do strony nr 1 (druga strona), aż znowu ona się nie zapełni.
Wirtualne adresy zmiennych zawarte są w tablicy VirtAddVarTab[NumbOfVar].
NumbOfVar zawiera całkowitą liczbę zmiennych, wartość ta jest konieczna do prawidłowego kopiowania stron pamięci.
Na początku programu trzeba odblokować pamięć FLASH (FLASH_Unlock()) oraz zainicjować pamięć EEPROM (EE_Init()).
Przykładowy zapis do pamięci wygląda następująco:
- EE_WriteVariable(VirtAddVarTab[index],zmienna);
A tak wygląda odczyt:
- EE_ReadVariable(VirtAddVarTab[index],&zmienna);
Rozwiązanie to ma tę zaletę, że gdyby zapisywać cały czas tę samą fizyczną komórkę pamięci FLASH to za każdym razem przez zapisem należałoby ją wykasować (w zasadzie kasowanie w STM32 dotyczy całej strony, a nie pojedynczej komórki), a tak kasowanie następuje dopiero po zapełnieniu strony.
Wadą jest to, że do pamięci oprócz wartości zapisywany jest też jej adres wirtualny, więc tracimy na pojemności.