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

[M162][GCC] - Wywołanie funkcji z adresem - wskaźnikiem w pamięci FLASH

excray 30 Wrz 2012 16:08 1512 10
  • #1 11363421
    excray
    Poziom 41  
    Temat dotyczy:
    https://www.elektroda.pl/rtvforum/topic2389664.html#11362337
    Niestety zbyt szybko go zamknąłem. Zapewne doświadczeni czytelnicy ww. tematu już doskonale wiedzą w czym jest problem :-) Problem jest w tym że funkcja:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    która świetnie działała z danymi w RAM nie chce działać gdy dane są w pamięci FLASH. Trudno zresztą mieć o to do niej pretensje :-)
    Próbowałem już takich rzeczy:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    oraz tak:
    https://www.elektroda.pl/rtvforum/topic1452425.html
    niestety bez skutku. Dlatego proszę jeszcze raz o pomoc :-)
  • Pomocny post
    #2 11363432
    mirekk36
    Poziom 42  
    No właśnie odpowiadałem ci na tamten wątek ale okazało się że w trakcie go zamknąłeś.

    A pisałem właśnie że nieco inaczej będzie teraz trzeba odczytywać te dane z Flash ale to nie jest jakiś kłopot.

    Tylko na początek - małe sprostowanie bo robisz troszkę albo hmm bardzo dziwne rzeczy :(

    co to jest ?

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


    po co to zero na końcu ? ;) toż taki string będzie miał dwa zera na końcu. Nie doczytałeś że po to stosuje się w C cudzysłowy aby można było zdefiniowaś C-String, a jeśli cudzysłowy to one automatycznie kończą string zerem, a zatem string:

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


    nie będzie miał 5 bajtów tylko 6 bajtów .... i zapamiętaj to sobie na zawsze to ważne w C

    druga sprawa - jeśli stosujesz GCC to odpuść sobie te

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


    i korzystaj z typu

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


    a przechodząc do tematu odczytu z Flash to musisz doczytać i zacząć się posługiwać albo wskaźnikami do struktury albo chociaż operatorem pobierania adresu &

    zauważ że argumentem funkcji pgm_read_byte() jest wskaźnik
  • #3 11363458
    excray
    Poziom 41  
    mirekk36 napisał:
    po co to zero na końcu ? :wink: toż taki string będzie miał dwa zera na końcu.

    Zerżnąłem z gotowca z netu. Też mnie to zero trochę zdziwiło. Ale skoro działało to już nie wnikałem... <wstydzi się>
    Czy mógłbyś mi podpowiedzieć jak będzie wyglądało to wywołanie funkcji?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    current_menu i menu_event to zmienne typu char w ram.
    Prooooszę.... :-)

    Dodano po 18 [minuty]:

    Ok, pogmyrałem, pogdybałem i wyszło mi coś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Działa. Ale na razie nie zamykam tematu :-)
  • #5 11363727
    excray
    Poziom 41  
    Nie. Nic się nie dzieje. Testowany na bieżąco niby działa. Czemu? Widzisz jeszcze jakieś babole które przeoczyłem?
  • Pomocny post
    #6 11363786
    mirekk36
    Poziom 42  
    definiujesz wskaźnik

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


    a potem używasz go do funkcji z argumentem

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


    to jedno a drugie to zamiast tak:

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


    można pozbyć się dodatkowej zmiennej temp

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


    i w warunku

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


    sprawdzać zawartość wskaźnika a nie wartość zmiennej liczbowej temp

    ale jak mówię - nie sprawdzam tego - tylko tak mi się wydaje że powinny się warningi pokazać
  • #7 11363836
    excray
    Poziom 41  
    Racja. Po wprowadzeniu Twoich zmian kod uległ skróceniu o 4B czyli coś to rzeczywiście dało kompilatorowi i też jest OK. Ostrzeżeń wcześniej nie było - pewnie kompilator przyzwyczaił się do mojego sposobu pisania i już sam po cichu poprawia nawet nie wdając się ze mną w dyskusję :-). Dziękuję za pomoc.
  • #8 11363855
    mirekk36
    Poziom 42  
    A sprawdź czy przypadkiem nie masz opcji włączonej, która wyłącza warningi ;) bo może sobie to zrobiłeś wcześniej i zapomniałeś ? ;)

    Dodano po 1 [minuty]:

    I jak programujesz w avr gcc to staraj się korzystać z typów

    uint8_t
    int8_t
    uint16_t

    itd zamiast np

    unsigned int ;) przecież to tutaj uint16_t

    nie dość że krócej się pisze to też nie nadziejesz się na warningi z niezgodnością typów
  • #9 11363875
    excray
    Poziom 41  
    Tzn. normalnie dostaję ostrzeżenia.
    mirekk36 napisał:
    unsigned int :wink: przecież to tutaj uint16_t

    Tak, racja ale z tego co wiem w innych kompilatorach nie ma czegoś takiego jak uint_16t a unsigned int jest wszędzie zrozumiałe. Dlatego tak piszę. Chyba że znowu się mylę :)
    Co do char a unsigned char to stosuję unsigned bo dla mnie to jest naturalny zapis bajta - bez znaku. Takie przyzwyczajenie.
  • Pomocny post
    #10 11364151
    mirekk36
    Poziom 42  
    No to co to znaczy u ciebie że:

    "normalnie dostaję ostrzeżenia"

    ??? ;) a nienormalnie to jak ??? ;)

    źle myślisz o tyle że nie doczytałeś o pewnych modyfikacjach w AVR GCC i stąd twoje problemy i problemiki i jak widzę Warningi

    a wystarczy doczytać że domyślnie przy kompilacji w avr gcc typu char jest zamieniany do unsigned char. Więc po to aby było mniej pisania, ale ciągnie to za sobą dalsze konsekwencje - które wyłażą jak hydra tym którzy mają takie przyzwyczajenia gdy np dojdzie do skorzystania z wbudowanych funkcji, które mają argumenty zdefiniowane jako char właśnie. Bo założono że user doczytał. Więc po tym gdy ty z przyzwyczajenia będziesz przekazywał do takich funkcji swoje zmienne z typem unsigned char to będziesz dostawał warningi ;) niestety. Ale coś czuję - na podstawie powyższej wypowiedzi (ale może się mylę) , że ty w ogóle nie zwracasz uwagi na warningi ...
  • #11 11364170
    excray
    Poziom 41  
    mirekk36 napisał:
    domyślnie przy kompilacji w avr gcc typu char jest zamieniany do unsigned char

    Tego akurat nie wiedziałem.
REKLAMA