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

[avr-gcc][PROGMEM] - Wskaźnik do tablicy wskaźników na teksty

DXFM 13 Wrz 2013 00:13 3939 8
  • #1 12729943
    DXFM
    Poziom 20  
    Trochę się zamotałem. Mam taką sytuację:

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


    Coś chyba jest nie tak z linią
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    bo kompilator pluje się o przypisanie do zmiennej language:
    .language = lang_polish
    z komunikatem:
    Cytat:
    Warning: assignment discards 'const' qualifier from pointer target type [enabled by default]


    Chcę, aby maszynka od menu wyświetlała teksty w wybranym języku, czyli dostawała adres jednej z tablic zawierającej wskaźniki do napisów. Już miałem to zrobione w starszym gcc według nongnu.org i działało. Teraz wziąłem Atmel Studio 6.1 i gcc 4.7.2. Z domyślnymi ustawieniami pluł się o const przy stałych umieszczonych we flash (PROGMEM). Uzupełniłem więc. Tylko nie wiem co z tą felerną linią. const char ** to powinien być wskaźnik na wskaźnik na stałą typu char. Tylko że ja już się pogubiłem.
    Pomoże ktoś?
  • Pomocny post
    #2 12729949
    BlueDraco
    Specjalista - Mikrokontrolery
    Tak na oko masz o jedno const za mało w deklaracji language. Ma to być zmienny wskaźnik na stały wskaźnik na stałą. A u Ciebie jest zmienny wskaźnik na zmienny wskaźnik na stałą.
  • #3 12730242
    DXFM
    Poziom 20  
    BlueDraco napisał:
    Tak na oko masz o jedno const za mało w deklaracji language. Ma to być zmienny wskaźnik na stały wskaźnik na stałą. A u Ciebie jest zmienny wskaźnik na zmienny wskaźnik na stałą.

    Masz rację! Dziękuję! Deklaracja zmiennej wskaźnikowej określającej język powinna wyglądać w ten sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    i teraz już wystarczy przypisać
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

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

    aby otrzymać właściwe wskazanie (na tablicę wskaźników na ciągi znakowe).
    Co ciekawe, już taką konfigurację wcześniej próbowałem, ale widocznie gdzieś wcześniej miałem źle, bo kompilator raportował błędy.

    Nie do końca jednak rozumiem, dlaczego w
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    kompilator domaga się tego drugiego const? Bez niego:
    Cytat:
    Error: variable 'lang_english' must be const in order to be put into read-only section by means of '__attribute__((progmem))'

    Czy nawiasy kwadratowe przy lang_polish nie mówią, że lang_polish, czyli nazwa tablicy, jest stałym wskaźnikiem na pierwszy element tablicy?
  • #4 12730383
    stanleysts
    Poziom 27  
    Atrybut progmem wymusza włożenie do sekcji tylko do odczytu, a tylko do odczytu może być zmienna const. Inną mógłbyś próbować zmienić, a tak się nie da.
  • #5 12733437
    DXFM
    Poziom 20  
    stanleysts napisał:
    Atrybut progmem wymusza włożenie do sekcji tylko do odczytu, a tylko do odczytu może być zmienna const. Inną mógłbyś próbować zmienić, a tak się nie da.

    A w jaki sposób zmienić lang_polish? Nazwa tablicy jest stałym wskaźnikiem do pierwszego jej elementu (o ile pamiętam z książek i studiów). Nie da się w programie zrobić tak, żeby tablica zawierała elementy znajdujące się pod innym adresem. Żeby uprościć:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Poza tym dlaczego kompilator nie zawrzeszczał przy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    ?
    Tu tak samo jest PROGMEM, a const mówi tylko tyle, że elementy tablicy są tylko do odczytu.
    ---
    A, chyba że linię
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    powinienem czytać tak:
    tablica stałych wskaźników na stałe typu char (czytam od końca). Czyli drugie const (tuż za gwiazdką) jest z tego powodu, że elementami są stałe wskaźniki (na char), a nie dlatego, że ta tablica jest we flash.
    Czy tak?

    (Czy tu można dyskutować na ten temat? Chcę zrozumieć składnię.)
  • Pomocny post
    #6 12733542
    stanleysts
    Poziom 27  
    Cytat:
    A w jaki sposób zmienić lang_polish? Nazwa tablicy jest stałym wskaźnikiem do pierwszego jej elementu (o ile pamiętam z książek i studiów). Nie da się w programie zrobić tak, żeby tablica zawierała elementy znajdujące się pod innym adresem. Żeby uprościć:


    Sama nazwa tak, ale tu chodzi o to, co trzymasz w tej tablicy, a tam w niej musisz trzymać coś const (to, że akurat to jest wskaźnik to swoją drogą)
    Tu nie chodzi o to, że tablica ma zawierać elementy spod innego adresu, ale to tablicy przecież możesz coś wpisać, a ten const spowoduje, że nie będzie się dało i możesz tylko raz tą tablicę wypełnić tymi stałymi wskaźnikami na stałą :D (oczywiście const ma się nie rozumieć jak stały, ale bardziej jako read-only, ale tak mi wygodniej pisać)

    Patrz ja to rozumiem tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Teraz masz tablicę wskaźników do zmiennych char, które są read-only. To znaczy, że możesz sobie dowolnie wpisywać do tej tablicy inne wskaźniki, tylko, że wartość na którą one wskazują nie może być modyfikowana, ale do samej tablicy możesz potem w programie taki wskaźnik wpisać.

    No a PROGMEM to takie coś będzie starał się umieścić w pamięci programu, jako, że ona jest tylko read-only, to nie może pozwolić ci na próbę wpisywania pod ten adres czegoś, więc wymusza, aby te wskaźniki też były read-only, co prowadzi do tego:

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


    I tu masz dokłądnie stały wskaźnik na stałą zmienną i przez to, że jest on stały to możesz go bez problemu do pamięci kodu wpisać za pomocą PROGMEM.

    Nie mam zdolności dydaktycznych, ale mam nadzieję, że trochę pomogłem :P
  • #7 12737725
    DXFM
    Poziom 20  
    stanleysts napisał:

    Sama nazwa tak, ale tu chodzi o to, co trzymasz w tej tablicy, a tam w niej musisz trzymać coś const (to, że akurat to jest wskaźnik to swoją drogą)
    Tu nie chodzi o to, że tablica ma zawierać elementy spod innego adresu, ale to tablicy przecież możesz coś wpisać, a ten const spowoduje, że nie będzie się dało i możesz tylko raz tą tablicę wypełnić tymi stałymi wskaźnikami na stałą :D

    OK, czyli tak jak ostatecznie wydedukowałem. Ten przykład pokazuje jak świadomie kontrolować typy wydawało by się dość prostego przypadku podwójnego wskaźnika. Jak widać, przykłady http://www.nongnu.org/avr-libc/user-manual/pgmspace.html są już nieaktualne. Czy znacie coś aktualniejszego?
    I coś o "__flash", bo widzę zmiany: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#flash_und_Embedded-C.
    Dziękuję!
  • #9 12781369
    DXFM
    Poziom 20  
    Przykłady niby są, ale czy doskonale opisane to nie wiem. Niemieckiego ni w ząb, przetłumaczone Googlem na polski trochę lepiej, ale jakoś słabo łapię. Myślałem, że jest jakiś poradnik w wersji angielskiej nawet. Na AVR freaks też raczej szczątkowe informacje. Nie zrozumiałem też, czy __memx tyczy się tylko RAM, czy również stałych we flash-u.
REKLAMA