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

[XMEGA][C] Odczyt flash w isr i eeprom w programie głównym

lupin22 01 Wrz 2021 10:26 489 5
REKLAMA
  • #1 19590484
    lupin22
    Poziom 10  
    Cześć,

    zagłębiam się trochę w wykorzystanie pamięci eeprom i flash i przeglądając avrowe funkcje nvm natknąłem się na takie stwierdzenie:

    Cytat:
    The functions in this module are modifying the NVM.CMD register.
    * If the application are using program space access in interrupts
    * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts
    * needs to be disabled when running EEPROM access functions. If not
    * the program space reads will be corrupted.


    i chyba dobrze, bo wydaje mi się, że występuje u mnie taka sytuacja. W przerwaniu czytam trochę danych z pamięci flash zadeklarowanych tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    do których później "dobieram się" normalnie jak do każdej innej zmiennej w moim ISR. Jednocześnie w pętli głównej programu korzystam z biblioteki eeprom.h i funkcji odczytu i zapisu z niej. Stąd chciałbym prosić o pomoc w rozwianiu kilku niejasności:

    Czy dobrze rozumiem, że dostęp do pamięci flash oraz EEPROM w xmegach zawsze wykorzystuje kontroler NVM? Czyli niezależnie, czy używam funkcji z eeprom.h, czy korzystam z funkcji z biblioteki nvm.h żeby odczytywać/zapisywać dane w EEPROM, to powinienem wykonywać je w atomic block ze względu na to, że odczytuję też pamięć flash w obsłudze przerwania?
  • REKLAMA
  • #2 19590581
    tmf
    VIP Zasłużony dla elektroda
    lupin22 napisał:
    Czy dobrze rozumiem, że dostęp do pamięci flash oraz EEPROM w xmegach zawsze wykorzystuje kontroler NVM?

    Zawsze wykorzystuje hardware NVM, ale niekoniecznie modyfikuje stan tego układu. Odczyt FLASH odbywa się bez konieczności modyfikacji NVM (o ile mówimy o odczycie bajtów/słów), więc dostęp do EEPROM nie powinien tu robić problemów. Problem zaczyna się jeśli wykonujesz operację, która zmienia stan rejestru CMD kontrolera NVM i taka operacja ma miejsce i z poziomu pętli głównej programu i przerwań. Wtedy istotnie powinna być atomowa. To dotyczy rónoczesnego dostępu do EEPROM lub dostępu do stron pamięci FLAH, obszarów specjalnych, bootloadera itd.
    Ogólnie, funkcje dostępu do EEPROM nie do końca przystają do XMEGA - nie wykorzystują potencjału tego MCU. Ponadto wobec możliwości zmapowania EEPROM bezpośrednio w przestrzeń adresową MCU, czynią korzystanie z funkcji odczytu EEPROM praktycznie zbędnym.
  • REKLAMA
  • #3 19590681
    lupin22
    Poziom 10  
    tmf napisał:
    Odczyt FLASH odbywa się bez konieczności modyfikacji NVM (o ile mówimy o odczycie bajtów/słów),

    Cytat:
    If the application are using program space access in interrupts
    * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts


    A czy to, co ja robię to nie jest ten __flash pointer? Co prawda korzystam z GCC, ale tutaj na forum doradzono mi, że nie trzeba używać makr pgm, tylko można dane zapisać w taki właśnie sposób, a potem odnosić się do nich jak do każdej innej zmiennej. Przeglądając makra pgm (chociaż assemblera nie znam) i internet wydedukowałem, że w tym przypadku będzie użyta instrukcja LPM. W dokumencie XMEGA Self-programming jest taki wycinek:

    Cytat:
    LPM-based commands are commands where the LPM instruction is used. The LPM
    instruction is executed after the required control registers are set up. LPM-based
    commands are used for reading Flash memories. In XMEGA devices, the application
    code, calibration bytes, and signature bytes are located in Flash memory.

    The exact procedure is as follows:
    1. Load address or index into the Z pointer register (R31 and R30) if required.
    2. Load the command code into the Command register (CMD).
    3. Execute the LPM instruction.
    4. The operation finishes immediately.
    5. Results from the operation will be available in registers R0.

    The following operations use LPM-based commands:
    • Reading calibration bytes
    • Reading user-accessible signature bytes
    • Read Flash memory


    Czyli jednak rejestr CMD jest tutaj używany?

    tmf napisał:
    Ogólnie, funkcje dostępu do EEPROM nie do końca przystają do XMEGA - nie wykorzystują potencjału tego MCU.

    Wiem, trzymam pod ręką AVR Praktyczne Projekty i zawsze najpierw przeglądam tam rozdział o NVM. Niemniej jednak u mnie w programie eeprom wykorzystywany jest w następujący sposób:

    Przy włączeniu urządzenia odczytywane są do struktury informacje konfiguracyjne (jest ich kilka zestawów, między którymi użytkownik może się przełączać), około 220 bajtów, potem są one wykorzystywane i modyfikowane na różne sposoby, czasem wielokrotnie w trakcie działania programu, a na sam koniec, przy jego wyłączaniu te 220 bajtów jest zapisywane z powrotem do EEPROM i przechowywane. Ten zapis korzystając z funkcji eeprom.h trwa dość długo, także przymierzam się do skorzystania z nvm i wykorzystania zapisu całymi stronami. Tam też jest kilka niejasności (głównie jak to jest z włączaniem i wyłączaniem mapowania), o które będę chciał zapytać, ale to może w innym temacie, żeby tutaj nie zaśmiecać. Także przy odczycie mógłbym zrobić to atomowo, bo wykonuje się to bardzo szybko, ale przy zapisie liczonym w milisekundach na każdy bajt (albo stronę) to jest już problematyczne, bo moje przerwania muszą wywoływać się co około 10ms, żeby nadążyć z zapełnianiem buforów danych, które potem idą do DAC.
  • REKLAMA
  • #4 19591255
    tmf
    VIP Zasłużony dla elektroda
    lupin22 napisał:
    Czyli jednak rejestr CMD jest tutaj używany?

    Bezpośrednio nie jest używany, ale musi mieć wartość 0x00 (no command).
    lupin22 napisał:
    en zapis korzystając z funkcji eeprom.h trwa dość długo, także przymierzam się do skorzystania z nvm i wykorzystania zapisu całymi stronami.

    Napisz własne funkcje - zapisując stronami zapisujesz 32 bajty na raz, czyli operacja jest 32-razy szybsza. Biorąc pod uwagę możliwość wcześniejszego skasowania strony ma jeszcze dwukrotny zysk czasowy - czyli łącznie 64 razy szybciej.
    lupin22 napisał:
    am też jest kilka niejasności (głównie jak to jest z włączaniem i wyłączaniem mapowania), o które będę chciał zapytać, ale to może w innym temacie, żeby tutaj nie zaśmiecać.

    Z wyjątkiem serii E5 mapowanie można włączać i wyłączać. Ja bym je włączył i olał odczyt przez funkcje eeprom, a zamiast tego zrobił zwykły odczyt, co przy okazji rozwiązuje problem z dostępem do FLASH.
    lupin22 napisał:
    Także przy odczycie mógłbym zrobić to atomowo, bo wykonuje się to bardzo szybko

    Jeśli włączysz mapowanie to nie musisz się przejmować atomowością odczytu, bo masz dostęp tak jak do SRAM.
    lupin22 napisał:
    ale przy zapisie liczonym w milisekundach na każdy bajt (albo stronę) to jest już problematyczne, bo moje przerwania muszą wywoływać się co około 10ms

    Nie musisz blokować przerwań na cały czas zapisu do EEPROM, tylko na czas zapisu strony. W efekcie to będzie ok. 4 ms dla samego zapisu lub 8 ms dla sekwencji kasowanie/zapis.
    lupin22 napisał:
    żeby nadążyć z zapełnianiem buforów danych, które potem idą do DAC.

    To użyj DMA.
  • REKLAMA
  • #5 19591384
    lupin22
    Poziom 10  
    tmf napisał:
    To użyj DMA.

    Tak jest zrobione. DMA podaje próbki na DAC, ale bufory trzeba co jakiś czas zapełnić. Bazuję na przykładzie z książki.

    tmf napisał:

    Z wyjątkiem serii E5 mapowanie można włączać i wyłączać. Ja bym je włączył i olał odczyt przez funkcje eeprom, a zamiast tego zrobił zwykły odczyt, co przy okazji rozwiązuje problem z dostępem do FLASH.

    Czyli wtedy eeprom do odczytu nie korzysta z kontrolera NVM? Odpalam mapowanie na początku i cały odczyt traktuję jak SRAM, tak samo w przerwaniu jak i w pętli głównej? Jeśli tak, to rzezczywiście bardzo wygodne.

    tmf napisał:
    Nie musisz blokować przerwań na cały czas zapisu do EEPROM, tylko na czas zapisu strony. W efekcie to będzie ok. 4 ms dla samego zapisu lub 8 ms dla sekwencji kasowanie/zapis.

    tmf napisał:
    Bezpośrednio nie jest używany, ale musi mieć wartość 0x00 (no command).


    Dobrze rozumiem, że do problemu dojdzie, gdy akurat korzystam z rejestru CMD kontrolera i odpali się przerwanie, które będzie czytało z flash, a rejestr CMD nie będzie wtedy 0x00? Czy w takim razie nie wystarczyłoby atomowo wykonywać funkcji

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ?

    Wtedy wyglądałoby to tak:

    1. Wypełniam bufor strony moimi danymi.
    2. Wykonuję atomowo funkcję nvm_issue_command z poleceniem NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc
    3. Czekam aż kontroler przestanie być zajęty i wracam do punktu 1 z kolejnymi danymi do kolejnej strony.

    Czy dobrze myślę?

    Czytając datasheeta natknąłem się też na taki fragment:
    Cytat:
    Programming any part of the NVM will automatically block:
     All programming to other parts of the NVM
     All loading/erasing of the flash and EEPROM page buffers
     All NVM reads from external programmers
    All NVM reads from the application section

    Jak rozumiem chodzi tutaj o bezpośrednie używanie nvm do np. czytania stron z flash, itd. a odczyt, którego dokonuję ja działa bez tego?
  • #6 19591408
    tmf
    VIP Zasłużony dla elektroda
    lupin22 napisał:
    Odpalam mapowanie na początku i cały odczyt traktuję jak SRAM, tak samo w przerwaniu jak i w pętli głównej? Jeśli tak, to rzezczywiście bardzo wygodne.

    Dokładnie tak.
    lupin22 napisał:
    Dobrze rozumiem, że do problemu dojdzie, gdy akurat korzystam z rejestru CMD kontrolera i odpali się przerwanie, które będzie czytało z flash, a rejestr CMD nie będzie wtedy 0x00? Czy w takim razie nie wystarczyłoby atomowo wykonywać funkcji

    Dokładnie tak, przy czym atomowo należy zrealizować wykonywanie polecenia NVM., ew. w przerwaniu zachowywać i odtwarzać rejestr CMD i czekać na ew. zniknięcie flagi busy. Czyli pokazany kod jest ok, tylko wcześniej trzeba sprawdzić busy.
    lupin22 napisał:
    Czy dobrze myślę?

    Dokłądnie tak. Ew. można podzielić dostęp na osobne sekwencje erase i write, co umożliwi pomiędzy obsługę przerwania, jeśli latencja przerwań jest istotna.
    lupin22 napisał:
    Jak rozumiem chodzi tutaj o bezpośrednie używanie nvm do np. czytania stron z flash, itd. a odczyt, którego dokonuję ja działa bez tego?

    To dotyczy zapisu.
REKLAMA