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

Lokowanie zmiennych w EEPROM-ie pod konkretnym adresem

robiw 20 Wrz 2022 13:59 726 19
REKLAMA
  • #1 20199188
    robiw
    Poziom 26  
    Witajcie.
    Avrgcc i plik nagłówkowy eeprom.h. Nie znalazłem prostego sposobu. Czy da się umieścić zmienne w pamięci EEPROM pod konkretnym adresem nie zostawiając pola dla linkera? Potrzebuję tablicę uint16_t Tablica[16] EEMEM umieścić (a potem odczytywać) od pierwszej komórki pamięci EEPROM (czy jakiejkolwiek innej). Da się to zrobić prosto bez pisania własnych (aczkolwiek prostych) funkcji tylko z użyciem tych z eeprom.h? Pozdrawiam. Robert
  • REKLAMA
  • #2 20199354
    khoam
    Poziom 42  
    robiw napisał:
    Potrzebuję tablicę uint16_t Tablica[16] EEMEM umieścić (a potem odczytywać) od pierwszej komórki pamięci EEPROM (czy jakiejkolwiek innej).

    To powinno być bardzo proste z użyciem funkcji eeprom_read_block, eeprom_write_block i eeprom_update_block.
  • #3 20199362
    robiw
    Poziom 26  
    Nie wyraziłem się, jak widać, precyzyjnie. Potrzebuję zmienne umieścić pod konkretnym adresem w EEPROM, np. żeby tablica zaczynała się od adresu 0x01 czy innego i była zawsze przypisana do tego miejsca. Czy jakąkolwiek inną zmienna. Nie znalazłem prostej metody z pliku EEPROM.h. robiw
  • #4 20199684
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #5 20199694
    robiw
    Poziom 26  
    Raczej nie na temat. Używam AVR-GCC i pliku eeprom.h. Oczywiście można te funkcje napisać samemu, bo są proste, ale chciałem wykorzystać wbudowane. robiw
  • #6 20199791
    khoam
    Poziom 42  
    @robiw Tutaj to masz wyjaśnione: Link
  • #7 20199799
    robiw
    Poziom 26  
    Chyba nadal się nie rozumiemy. Wiem doskonale, jak to działa i wiem, że zmienne w strukturze zachowają swoje pozycje...ale nie o to chodzi. Mam jakieś zmienne w EEPROM zadeklarowane w programie i chce je umieścić pod konkretnymi adresami w pamięci EEPROM, bo chce dać możliwość użytkownikom ich podmiany, więc muszę wskazać w jakich znajdują się miejscach. Oczywiście w disasemblacji (i nie tylko) mogę podejrzeć, gdzie one "wędrują" i opisać to użytkownikom, ale nie chcę by przy którejś kompilacji (i modyfikacji programu) zmieniły swoje miejsce. One muszą być pod konkretnymi adresami, zawsze, niezależnie ile innych zmiennych dodam w pliku źródłowym. Robert
  • REKLAMA
  • #8 20199843
    StaryVirus_e_Wiarus
    Poziom 21  
    Cześć
    Jeżeli masz zainstalowany AVR Toolchain, czy Microchip Sudio; to masz tam folder "doc" a w nim "avr-libc" i zawarte pliki manualu. W nich znajdziesz jak obsłużyć EEPROM.
  • #9 20199849
    khoam
    Poziom 42  
    robiw napisał:
    Oczywiście w disasemblacji (i nie tylko) mogę podejrzeć, gdzie one "wędrują" i opisać to użytkownikom, ale nie chcę by przy którejś kompilacji (i modyfikacji programu) zmieniły swoje miejsce.

    One nie zmienią swojego miejsca - zawsze będą umiejscawiane (te z atrybutem EEMEM) od początku EEPROM w takiej kolejności, w jakiej zostały zadeklarowane. Oczywiście na "upartego" możesz sobie zdefiniować własny atrybut z innym punktem startowym w EEPROM, ale wtedy przy kompilacji musisz podać parametr "--section-start" z adresem sekcji. Tylko po co?
  • #10 20199854
    robiw
    Poziom 26  
    Jeśli zmienię z jakiegoś powodu kolejność deklaracji tych zmiennych (a mogę je używać w różnych modułach aplikacji) to nie mam takiej pewności moim zdaniem. R
  • #11 20199861
    khoam
    Poziom 42  
    robiw napisał:
    Jeśli zmienię z jakiegoś powodu kolejność deklaracji tych zmiennych (a mogę je używać w różnych modułach aplikacji) to nie mam takiej pewności moim zdaniem.

    To w takiej sytuacji moim zdaniem lepiej odwoływać się bezpośrednio do ustalonych adresów w EEPROM, standardowymi fukcjami eeprom_*.
  • REKLAMA
  • #12 20199867
    robiw
    Poziom 26  
    Zgadza się. O to mi chodzi. Tylko, jak w deklaracji umieścić te zmienne pod wskazanymi adresami? Chyba, że w argumencie podawać zwyczajnie adres bez deklaracji zmiennych w kodzie? R
  • #13 20199871
    khoam
    Poziom 42  
    robiw napisał:
    Chyba, że w argumencie podawać zwyczajnie adres bez deklaracji zmiennych w kodzie?

    Adresy takie mogą być zdefiniowane jako stałe, więc odwoływać się będziesz przez ich nazwy, a nie fizyczne adresy.
  • #14 20199880
    robiw
    Poziom 26  
    Hmm. Tak też nie mogę. Zmienna w EEPROM to tablica uint16_t, do której elementów chce się odwoływać w pętli poprzez indeksację, więc stałe odpadają, tak mi się wydaje. Nie chcę deklarować stałych do każdego elementu tablicy. Chce to zrobić najprościej, jak możliwe. R
  • #15 20199890
    khoam
    Poziom 42  
    Nie musisz, wystarczy do początku tablicy. Kolejne adresy będą wynikały z tego właśnie początku i kolejnego indeksu. Prosta arytmetyka.
  • #16 20199897
    robiw
    Poziom 26  
    To wiadomo, co 2 bajty... tyle, że jak to zapisać, jako argument funkcji eeprom_read_word? Np. tak: eeprom_read_word((uint16_t *) 0x00), jako wskaźnik na zerowy element pamięci EEPROM, czyli LSB pierwszego słowa uint16_t? R
  • #17 20199911
    tmf
    VIP Zasłużony dla elektroda
    Jeżeli w EEPROM deklarujesz wyłącznie tą jedną tablicę, to masz gwarancję, że jej adres początkowy wyniesie 0. Więc problem rozwiązuje się sam. Jeśli masz w EEPROM zadeklarowane także inne zmienne, to wracamy do początku - nie ma gwarancji. W takiej sytuacji są co najmniej dwa rozwiązania:
    - jak już poradzono, wszystkie zmienne umieścić w strukturze - proste i skuteczne,
    - zadeklarować nowe sekcje pamięci w obrębie EEPROM i podać adres takiej sekcji linkerowi.
  • #18 20200426
    robiw
    Poziom 26  
    tmf napisał:
    - jak już poradzono, wszystkie zmienne umieścić w strukturze - proste i skuteczne,


    To znam i wiem, że tak to działa. Niestety, jeśli zmienne występują w różnych modułach aplikacji nie jest to możliwe a już na pewno proste.

    tmf napisał:
    - zadeklarować nowe sekcje pamięci w obrębie EEPROM i podać adres takiej sekcji linkerowi.


    Znalazłem to rozwiązanie, ale jest ono uciążliwe.

    Niemniej jednak można to obejść bez deklaracji takich zmiennych, o czym pisałem post wyżej. Znalezione:

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


    I jeszcze to - odczyt słowa Word spod adresu 46:

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


    Wniosek z tego taki, że aby użyć tego w przypadku tablicy uint16_t ("zaczynającej" się od adresu 46) i indeksowania należy:

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


    Tak? To rozwiązanie wydaje się najprostsze. I nie ma potrzeby deklaracji żadnych zmiennych w EEPROM, wystarczy podać adres. robiw
  • #19 20201300
    tmf
    VIP Zasłużony dla elektroda
    Ale w tym "rozwiązaniu" ręczine rozmieszczasz dane w EEPROM. Jeśli dwóm "zmiennym" nadasz ten sam "adres", lub będą one na siebie nachodzić to nie masz szans wykryć taką sytuację. Szyli jeżeli odpada struktura, to z tych samych powodów odpada takie ręczne rozmieszczanie zmiennych.
    Jest jeszcze jedno rozwiązanie - napisać kilka funkcji realizujących dostęp do EEPROM poprzez nadanie zmiennym etykiet, po których są identyfikowane. Wtedy odnosisz się do zmiennych poprzez ich etykiety, funkcja wyszukuje odpowiedni adres i go zwraca. Daje to narzut pamięciowy, ale za to jest uniwersalne - rozmieszczenie ziennych jest kompletnie bez znaczenia.
  • #20 20201308
    robiw
    Poziom 26  
    To zrozumiałe, że wtedy sam muszę o to zadbać, jednak to nie problem. Moim zdaniem to najwygodniejsze rozwiązanie, gdyż muszę podac użytkownikowi pod jakimi adresami w EEPROMie musi umieścić swoje wartości, jeśli chce zmodyfikować działanie programu. Struktura odpada, bo mam zmienne EEPROM w dwóch plikach c zupełnie ze sobą niepowiązane. robiw

Podsumowanie tematu

W dyskusji poruszono problem umieszczania zmiennych w pamięci EEPROM pod konkretnymi adresami przy użyciu pliku nagłówkowego eeprom.h w AVR-GCC. Użytkownik poszukiwał prostego sposobu na przypisanie tablicy uint16_t do określonego adresu w EEPROM, aby umożliwić użytkownikom ich modyfikację. Odpowiedzi sugerowały użycie funkcji eeprom_read_block i eeprom_write_block, jednak użytkownik podkreślał potrzebę stałego przypisania adresów, niezależnie od kolejności deklaracji zmiennych. Wskazano na możliwość użycia atrybutu EEMEM oraz na konieczność zdefiniowania sekcji pamięci w linkerze, co jednak nie rozwiązywało problemu w przypadku zmiennych w różnych modułach. Proponowano również tworzenie funkcji do zarządzania dostępem do EEPROM poprzez etykiety, co pozwala na elastyczne zarządzanie adresami.
Podsumowanie wygenerowane przez model językowy.
REKLAMA