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

Samoistne kasowanie się komórek EEPROM Xmega 128A4U

MateuszW_ 03 Sty 2016 22:29 1551 18
  • #1 15297678
    MateuszW_
    Poziom 8  
    Piszę większy program na tytułową Xmegę i mam problem z pamięcią EEPROM. Zapisuję tam kilka ustawień (kilkadziesiąt bajtów). Wartości są odczytywane przy uruchomieniu urządzenia, a zapisywane, gdy użytkownik je zmieni.

    Niestety, z jakiegoś powodu, co jakiś czas wartość pod w miarę losowym adresem pamięci kasuje się (ustawia na FF). Testuję to uruchamiając urządzenie ponownie kilkanaście / dziesiąt razy. Za którymś (dziesiątym, czy dwudziestym) restartem następuje wykasowanie jakiejś komórki. Adres kasowanej komórki jest nieprzewidywalny, choć jest to zazwyczaj jedna z 3-4 konkretnych, a rzadziej któraś z pozostałych. Moment kasowania jest nieprzewidywalny, to nieraz działa ok przez kilkadziesiąt ponownych uruchomień, a nieraz psuje się po 3-5. W czasie testowania program nie powinien (jeśli jest prawidłowy, to nie ma prawa) nic zapisywać do EEPROM (jeśli nic nie robię na urządzeniu, to następuje tylko odczyt ustawień).

    Korzystam z funkcji eeprom_update_word itp. W kodzie jest kilkanaście wywołań tych funkcji. Jeśli zakomentuję je wszystkie, to problem znika - wartości pamięci się nie zmieniają.

    Zrobiłem też tak, że przed każdą funkcją zapisu urządzenie wydawało sygnał dźwiękowy. Po kilkunastu restartach któraś komórka znowu się wykasowała, ale urządzenie nie wydało dźwięku. Czyli teoretycznie nie weszło w miejsce kodu, gdzie jest funkcja zapisu. Ale z drugiej strony przecież, gdy usunę wszystkie wywołania funkcji zapisu, to problem znika, więc ta funkcja jakby się wywołuje w czasie niepożądanego skasowania pamięci.

    Moim zdaniem możliwości są dwie: albo mam jakiś parszywy błąd w programie, który w losowym momencie kasuje losową komórkę, albo pamięć jest fizycznie wadliwa. Moje testy dają nieco sprzeczne wyniki, które nie wskazują na żadną z teorii.

    Nie mam już więcej pomysłów, więc proszę Was o pomoc. Będę bardzo wdzięczny! Dziękuję!
  • #2 15297697
    BlueDraco
    Specjalista - Mikrokontrolery
    A ta pomoc to na czym ma konkretnie polegać? Mamy okazać Ci współczucie czy napisać "nie martw się"? Bo rozumiem, że skoro nie zamieściłeś kodu to technicznej pomocy nie oczekujesz?
  • #4 15297725
    kamyczek
    Poziom 38  
    Teoretycznie to jak dioda zapali się na 1/32000000s czy na tyle wysterujesz pin buzera to nie usłyszysz nic . Pierwsza sprawa schemat, kolejna listing a procedura musi się wywoływać z jakiegoś wątku , bo gdyby tak nie było to robienie z niej komentarzy nic by nie zmieniało ...
  • #5 15297823
    MateuszW_
    Poziom 8  
    BlueDraco napisał:
    A ta pomoc to na czym ma konkretnie polegać? Mamy okazać Ci współczucie czy napisać "nie martw się"? Bo rozumiem, że skoro nie zamieściłeś kodu to technicznej pomocy nie oczekujesz?

    Jak pisałem, program jest dość spory i nie chciałem od nikogo wymagać jego analizowania. Liczyłem, że może na sucho ktoś coś wymyśli. Ale faktycznie, raczej jest mała na to szansa. W takim razie wrzucam kod. Wrzucam cały, bo fragmenty wyrwane z kontekstu będą raczej bezsensowne. Obawiam się, że problem leży gdzieś głęboko i będzie to wymagać dłuższej analizy. Ale obym się mylił, może ktoś zauważy na pierwszy rzut oka.
    Generalnie zapis do eeproma odbywa się w plikach pcDrver, screenMenu i main.
    Projekt jest w AtmelStudio6.

    Cytat:
    Teoretycznie to jak dioda zapali się na 1/32000000s czy na tyle wysterujesz pin buzera to nie usłyszysz nic . Pierwsza sprawa schemat, kolejna listing a procedura musi się wywoływać z jakiegoś wątku , bo gdyby tak nie było to robienie z niej komentarzy nic by nie zmieniało ...

    Buzzer włączam na długi czas, więc powinien być słyszalny. Jedyna opcja, żeby nie był słyszalny, to jeśli zapis następuje w momencie zaniku zasilania. A być może tak jest.

    BOD jest włączony, jeśli dobrze pamiętam.
  • #6 15297990
    kamyczek
    Poziom 38  
    Jakie masz narzędzia do atmela ?. Warto spróbować odnaleźć błąd debugerem sprzętowym poustawiać sobie pułapki i zobaczyć czy stos się nie przepełnia , czy nie wywołuje się puste przerwanie , a może po prostu trzeba dla bezpieczeństwa dodać dwie linijki z warunkiem żeby się wykonał zapis eeprom w rejestrach x i y musi być wartość np.1793 wtedy nawet jeśli program się wybierze do procedury sprawdzi wartość rejestrów x i y i masz 65535 kombinacji że tego przypadkiem nie zrobi , a jeśli to poza programem ;)
  • #7 15298091
    MateuszW_
    Poziom 8  
    Debugowania sprzętowego jeszcze nigdy nie robiłem. Mam taki programator, nie wiem, czy obsługuje debugowanie: https://sklep.avt.pl/avt5388.html.
    Ale program wgrywam bootloaderem FLIP, więc nie wiem, czy programator się na coś zda.

    Pomysł z warunkiem ciekawy, też o tym pomyślałem, tylko nie wiem jak to do końca zrobić. Bo o zapisie do eeproma decyduję w zasadzie w tym miejscu, gdzie robię zapis, wiec ustawienie zmiennej do ifa następowały by prawie bezpośrednio przed ifem.

    Obawiam się, że program skacze do procedury zapisu eepromu bezpośrednio, a nie wchodzi tam przez moje wywołanie. To by mgło tłumaczyć brak wydawania dźwięku przez buzzer.

    Ale dlaczego zawsze wpisuje się FF, a nie losowa wartość? Czy to może być spowodowane niestabilnością zasilania, mimo, że używam BODa?
  • #8 15298310
    tmf
    VIP Zasłużony dla elektroda
    To w końcu masz włączonego BODa, czy nie jesteś pewien, bo to dużo zmienia.
    Skoro wykomentowanie funkcji zapisu eliminuje problem, to znaczy, że błąd leży w programie, lub program w jakiś momentach idzie w maliny. Być może przy zaniku zasilania - to by tłumaczyło dlaczego masz 0xff - EEPROM zdąży się skasować, ale nie zapisać. Korzystasz z mapowaina EEPROM w SRAM? Lub zapisu blokowego?
    Sprawdź te fusebity, żeby być pewnym co masz. Pokaż schemat. Stwórz minimalny przykład ilustrujący problem. Jeśli po okrojeniu kodu problem zniknie to wiesz, że leży w reszcie kodu...
  • #9 15298483
    trol.six
    Poziom 31  
    Pomijając błędy w programie (przecież może paść co innego), zrób sobie np. dwie tablice z weryfikacją. Tam gdzie ważność danych jest ważna, czasem beckup może się przydać, nawet jak nigdy nie będzie potrzebny.

    MateuszW_ napisał:
    Za którymś (dziesiątym, czy dwudziestym) restartem następuje wykasowanie jakiejś komórki

    A to jest restart napięciowy zasilaniem czy wejściem reset?

    Jeśli proces zapisu polega na uwcześniejszym wykasowaniu pamięci a następnie jej zapisie, to przerwanie procesu spowoduje że będzie 0xff. Akuratnie nie znam szczegółów jak to jest zrealizowane. Jednak sygnał dźwiękowy (jego brak) przed zapisem sugeruje coś innego.
  • #10 15298672
    Konto nie istnieje
    Konto nie istnieje  
  • #11 15304330
    MateuszW_
    Poziom 8  
    TMF, dzięki. Sprawdziłęm tego BODa i jednak nie był aktywny. Coś musiałem pomieszać, bo kilka razy edytowałem te fusebity. Po włączeniu problem zniknął (prawie na pewno)!

    Trol.six, tak zapisywanie np w dwóch kopiach i weryfikacja to fajny pomysł. Szczególnie, że mam sporo wolnego miejsca. Na pewno nie zaszkodzi.

    Z pamięci korzystam tylko funkcjami z eeprom.h, brak mapowania i zapisu blokowego. Resetowanie polegało na wyłączaniu zasilania.


    Mam jeszcze pytania co do BODa. Czy da się go włączyć programowo lub za pomocą FLIP? Jakie napięcie ustawić? Dałem 2,6, bo na 3V procek świrował (ciągle się resetował). Taktuję go 24Mhz, więc do tych 2,6 teoretycznie powinien pracować stabilnie. Jeśli dobrze policzyłem, to minimalne napięcie dla tej częstotliwości to 2,34V, wiec może ustawić na 2,4V? Czy sam eeprom ma jakieś minimalne napięcie zasilania zewnętrznego potrzebne do prawidłowej pracy?

    Przy okazji mam pytanie, jaki jest czas odczytu z eeprom? W tej chwili odczytuję sobie kopie wartości do zmiennych i operuję na nich w programie, zamiast ciągle odczytywać. Ale może to nie ma sensu. A czy mapowanie przyśpiesza czas dostępu, tak jakby to był ram?
  • #12 15304499
    tmf
    VIP Zasłużony dla elektroda
    EEPROM pracuje przy takim zakresie napięć jak MCU. Skoro przy BOD na 3V i zasilaniu procka 3,3V masz resety to znaczy, że coś jest nie tak z zasilaniem. Masz wszystkie wymagane kondensatory filtrujące przy MCU?
    Odczyt z EEPROM jest szybki, tak jak z innych rodzajów pamięci, mapowanie znacznie przyśpiesza zapis (zapisujesz od razu blok 32 bajty, a nie każdą komórkę z osobna). Ale też przyśpiesza (chociaż miniminalnie) odczyt. Zamiast adresować EEPROM poprzez jej rejestry adresowe dokonujesz po prostu odczytu tak jak z SRAM. Dodatkowa zaleta jest taka, że nie musisz tego robić poprzez funkcje z eeprom.h lecz robiąc to tak jak z każdą zmienną w C.
  • #13 15304709
    MateuszW_
    Poziom 8  
    Być może coś jest z zasilaniem, choć wydaje się ono ok. Resety z BOD na 3V następują z częstotliwością kilka razy na sekundę. Czyli program startuje, coś pokazuje się na ekranie i reset. Być może w momencie uruchamiania następuje na chwilę niewielki spadek napięcia, bo w czasie pracy napięcie na pewno wynosi już 3,3V.
    Tak, są kondensatory odciągające i filtrujące przy regulatorze napięcia.

    A czy przy mapowaniu mam swobodną kontrolę nad położeniem zmiennych w pamięci? Chodzi mi o to, czy po dodaniu kolejnej zmiennej do eepromu nie zmieni się nagle organizacja pamięci i nie stracę dostępu do danych zapisanych przez poprzednią wersje programu. Po prostu z czasem wraz z aktualizacjami będę być może dokładał nowe dane do pamięci i chciałbym zachować zgodność z tymi, które już tam są.
  • #14 15304774
    tmf
    VIP Zasłużony dla elektroda
    Skoro resetuje BOD to znaczy, że jednak z zasilaniem jest coś nie tak. Dopóki tego nie poprawisz będzie kłopot. Można oczywiście ustawić BOD na niżej, lecz to nie usuwa problemu, tylko go maskuje. Może zasilacz niewydala?
    Co do mapowania i kontroli położenia zmiennych - masz takie same możliwości jak w C. W EEPROM też jak sądzę zdajesz się na kompilator, a nie podajesz bezpośrednio adresów? Dobrym rozwiązaniem jest użycie struktury i umieszczenie zmiennych jako pól - masz gwarancję, że kompilator nie zmieni ich kolejności. Przykłady zresztą możesz sobie ściągnąć z książek z mojej stopki - są tam różne knify jak dobrać się do EEPROM w XMEGA.
  • #15 15304864
    MateuszW_
    Poziom 8  
    Zasilacz jest dobry, stawiałbym bardziej na jakieś zakłócenia od sterownika silnika krokowego. Sprawdzę na oscyloskopie.

    Na razie podaję jawnie adresy. Mam pełną kontrolę. Użycie struktury to dobry pomysł, tylko, czy wtedy pierwsza zmienna jest na początku eeprom, czy nie jest to określone? No i jak będę chciał dołożyć coś między obecne zmienne, a nie na koniec, żeby zachować klarowność kodu, to sobie zepsuję.

    Czytałem jakiś czas temu w Twojej książce o eeprom, jednak w każdej z metod dostępu widziałem jakieś wady, niej lub bardziej istotne. Niestety, nie da się zrobić tak idealnie, jak z ramem.
  • #16 15304884
    kamyczek
    Poziom 38  
    0,3V spadku to mało jak dla mnie to niezbyt duży margines pewnie następuje pik i spadek bo nie wyrabia się zasilanie i BOD ustawił bym na takie napięcie przy którym działa jeszcze układ poza tym w odpowiednich miejscach kondensatorki na zasilanie i bod na 2,5V wystarczy wpiąć oscyloskop na zasilanie i zobaczyć jak spada napięcie jak startuje wyświetlacz ...
  • #17 15304924
    MateuszW_
    Poziom 8  
    Właśnie, startuje wyświetlacz, zaświecają się diody. A regulator napięcia musi mieć jakiś czas na reakcję, żeby wyrównać napięcie. Pewnie BOD jest szybszy od niego. Ale zerknę na oscyloskop w najbliższym czasie.
  • #18 15305782
    tmf
    VIP Zasłużony dla elektroda
    MateuszW_ napisał:
    Zasilacz jest dobry, stawiałbym bardziej na jakieś zakłócenia od sterownika silnika krokowego. Sprawdzę na oscyloskopie.

    Na razie podaję jawnie adresy. Mam pełną kontrolę. Użycie struktury to dobry pomysł, tylko, czy wtedy pierwsza zmienna jest na początku eeprom, czy nie jest to określone? No i jak będę chciał dołożyć coś między obecne zmienne, a nie na koniec, żeby zachować klarowność kodu, to sobie zepsuję.

    Czytałem jakiś czas temu w Twojej książce o eeprom, jednak w każdej z metod dostępu widziałem jakieś wady, niej lub bardziej istotne. Niestety, nie da się zrobić tak idealnie, jak z ramem.


    Nic nie jest idealne, ale nie ma różnic pomiędzy EEPROM i SRAM jeśli chodzi o kontrolę rozmieszczenia zmiennych. Jeśli wstawisz jakieś zmienne pomiędzy, to przecież ich adresy się zmienią, więc jawne podawanie adresów nic nie daje, a wręcz szkodzi. Jeśli wszystkie dane w EEPROM będą w ramach jednej struktury, to masz gwarancję, że jej początek będzie na początku EEPROM - wynika to ze skryptu linkera.
  • #19 15307150
    MateuszW_
    Poziom 8  
    Hmm, no faktycznie masz rację. Operując na adresach zostawiałem sobie trochę wolnych komórek między używanymi dla późniejszego wykorzystania. Stosując struktury będę sobie pewnie robił jakieś "zapychacze", których nie będę używał.
REKLAMA