logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA32] EEPROM, stronicowanie, wielokrotny zapis

tmgofer 19 Sie 2009 19:55 2931 5
REKLAMA
  • #1 6910691
    tmgofer
    Poziom 12  
    Witam!

    Pytanie dotyczy zapisu do EEPROM'u pojedynczych bajtów.
    W datasheet'cie do ATmega32, w rozdziale 7.4.1 "EEPROM data memory" napisano:
    Cytat:
    The ATmega32A contains 1024 bytes of data EEPROM memory. It is organized as a separate
    data space, in which single bytes can be read and written. The EEPROM has an endurance of at
    least 100,000 write/erase cycles.

    Jak rozumiem użytkownik ma wrażenie jakby odczytywał i zapisywał pojedyncze bajty.

    W rozdziale 26.5 widnieje natomiast tabela (Table 26.6) w której to przedstawiono, że EEPROM jest podzielony na strony o pojemności 4 bajtów.
    Cytat:
    EEPROM Size | Page Size | PCWORD | No. of Pages | PCPAGE | EEAMSB
    1024 bytes | 4 bytes | EEA[1:0] | 256 | EEA[9:2] | 9


    Nasuwa się zatem pytanie, czy zanik zasilania przy zapisie jednego wybranego bajtu może zniszczyć zawartość całej strony?

    Czy mamy tu do czynienia z niejawnym wykorzystaniem mechanizmu read-modify-write wykonywanym na całej stronie?

    Czy intensywny zapis bajtu o adresie 0x0000 spowoduje, ze wartość zapisana w 3 kolejnych bajtach również ulegnie uszkodzeniu po 100 000 zapisów tego pierwszego?

    Pozdrawiam.
  • REKLAMA
  • #2 6912374
    tmf
    VIP Zasłużony dla elektroda
    Ciekawe pytanie. Praktyka wskazuje, ze bajty w EEPROM zapisywane sa pojedynczo i bledne zapisanie jednego z powodu przerwy w zasilaniu nie niszczy innych na tej samej stronie. Tu pojawia sie jednak pewien problem - operacje kasowania EEPROM i zapisu sa rozdzielne. Czyli zapisywany istotnie jest tylko jeden bajt (a konkretnie sa zerowane odpowiednie bity), ale operacja kasowania (ustawiania bajtu na 0xFF) moze istotnie dotyczyc calej strony, z transparentnym zapisem pozostalych bajtow. Wtedy problem moglby sie pojawiac nie podczas zapisu bajtu, a podczas kasowania komorki pamieci. Zeby to wyjasnic to chyba zostaje tylko pomoc trechniczna Atmela.
    BTW, unikaj raczej zapisu do komorki EEPROM o adresie 0. Rejestr EEADR zazwyczaj wskazuje na ta komorke i jak sie cos poknoci to czesto ulega ona uszkodzeniu. Ogolnie warto pamietac, zeby ten rejestr wskazywal na jakas nieuzywana komorke pamieci.
  • REKLAMA
  • #3 6912529
    tmgofer
    Poziom 12  
    Informacje z avr-libc-user-manual/FAQ :

    Problem o którym wspomniałeś dotyczy starszych AVR'ów w których rejestra adresowy po resecie przyjmuje wartość domyślną 0x0000. W nowszych wartość domyślna tego rejestru jest niezdefiniowana, dzięki czemu jeżeli watchdog klepnie w czasie zapisu EEPROMU, uszkodzona zostaje tylko aktualnie zapisywana cela pamięci.

    No i odpowiedź na moje pytanie:
    Cytat:
    AVRs use a paging mechanism for doing EEPROM writes. This is almost entirely transparent to the user with one exception: When a byte is written to the EEPROM, the entire EEPROM page is also transparently erased and (re)written, which will cause wear to bytes that the programmer did not explicitly write. If it is desired to extend EEPROM write lifetimes, in an attempt not to exceed the datasheet EEPROM write endurance specification for a given byte, then writes must be in multiples of the EEPROM page size, and not sequential bytes


    Dla użytkownika wynika z tego, że dla każdej zmiennej wielokrotnie zapisywanej w pamięci EEPROM należy zarezerwować ilość komórek pamięci będącą najmniejszą wielokrotnością 4 większą bądź równą rozmiarowi danej zmiennej. Dodatkowo należy zapewnić wyrównanie adresu do 4 (najlepiej zlecić to linkerowi stosując dyrektywę __attribute__((aligned(4)));

    W takim scenariuszu użycia pamięci EEPROM trzeba się liczyć z pewnym spadkiem jej efektywnej pojemności...
  • REKLAMA
  • #4 6912625
    tmf
    VIP Zasłużony dla elektroda
    Masz racje tmgofer, niemniej skoro wartosc EEADR jest niezdefiniowana to znaczy to tylko tyle, ze zamiast psuc ci komorke o adresie 0 psuje ci losowa komorke pamieci EEPROM. Male pocieszenie. Dlatego lepiej go ustawiac tak aby wskazywal na komorke, ktora nie jest uzywana.
    Co do zapisu EEPROM - jak pisalem mozna zapisac komorke pamieci bez wczesniejszego kasowania. Wtedy problem z przepisywaniem zawartosci sasiednich komorek nie wystapi. Oczyweiscie trzeba wtedy zapewnic poczatkowa wartosc EEPROM na 0xFF. Co jednak nie jest trudne jesli robimy cos w rodzaju wear leveling. Niemniej podales ciekawa informacje.
  • REKLAMA
  • #5 6912762
    tmgofer
    Poziom 12  
    tmf napisał:
    zamiast psuc ci komorke o adresie 0 psuje ci losowa komorke pamieci EEPROM. Male pocieszenie.

    Wydaje mi się, że w zamyśle projektantów było ulepszenie rdzenia AVR i dlatego po resecie wartość rejestru adresowego nie jest zerowana. Jest ona niezdefiniowana tylko po POR, natomiast kiedy watchdog resetuje rdzeń, to zarówno wartości w RAMie (sekcja .noinit) jak i w tym rejestrze pozostają takie same. Dzięki temu tylko ta wartość komórki EEPROM jest narażona na zniszczenie. Nie chodzi tu o losowo wybraną komórkę!

    tmf napisał:
    Dlatego lepiej go ustawiac tak aby wskazywal na komorke, ktora nie jest uzywana.

    Ale po co? Kiedy EEPROM nie jest w użyciu (nie jest zapisywany ani odczytywany) to wartość w tym rejestrze może być dowolna - i tak nie nastąpi zniszczenie jakiejkolwiek komórki pamięci w razie resetu.
    Natomiast w czasie zapisu oczywistą sprawą jest, że musi on zawierać adres komórki, do której następuje zapis/odczyt. Zapis to jedyny potencjalnie niebezpieczny moment - ale na to nic się nie da poradzić.

    tmf napisał:
    Co do zapisu EEPROM - jak pisalem mozna zapisac komorke pamieci bez wczesniejszego kasowania. Wtedy problem z przepisywaniem zawartosci sasiednich komorek nie wystapi.
    No OK...A w jaki sposób można zapisać komórkę bez jej kasowania? Udostępniony interface nie daje takiej możliwości z tego co się orientuję?
    BTW cały czas mówimy o wielokrotnym zapisie wybranej komórki więc tak czy inaczej kasowanie musi zostać przeprowadzone....
  • #6 6913262
    tmf
    VIP Zasłużony dla elektroda
    Problemz rejestrem adresowym i zapisem do EEPROM polega na tym, ze taka sytuacja moze wystapic przy wylaczaniu zasilania, szczegolnie kiedy nie masz ustawionego BOD. Empirycznie sprawdzilem to w ATMega8, czyli stosunkowo nowym procku. Ustawianie EEADR na nieuzywana komorke po prostu jest bezpieczne i zalecane przez Atmela.
    Co do zapisu to chyba standardowe procedury z pgmspace nie umozliwiaja tego, trzeba by mieszac w rejestrze EECR. Przy zapisie nowej wartosci trzeba kasowac stara, chyba, ze w celu wydluzenia trwalosci bedziesz zapisywal kolejne komorki, czyli kasujesz raz, zapisujesz az skonczy sie EEPROM i ponownie kasujesz. Oczywiscie ma to zastosowanie tylko w specyficznych sytuacjach.
REKLAMA