Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 6 kwi 2025, o 10:59


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
    Autor Wiadomość
    PostNapisane: 10 lut 2025, o 07:55 
    Offline
    Użytkownik

    Dołączył(a): 23 sty 2014
    Posty: 1085
    Pomógł: 73

    Cześć, pisząc program na mikrokontroler AVR zauważyłem ciekawą rzecz.
    Mam pewną funkcję o nazwie LCD_refresh, która realizuje operacje odświeżania wyświetlacza LCD,
    po czym zwraca rezultat - zawsze 0 (tylko taki rezultat na ten moment jest obsłużony - nic innego nie może być zwrócone).

    W funkcji lcdRun wywoływana jest LCD_refresh - w wyrażeniu warunkowym sprawdzam rezultat, jeśli jest inny niż 0, to ustawiam flagę lcdError na 1.

    I ku mojemu zdziwieniu, po uruchmieniu programu zmienna lcdError przyjmuje wartość 1, pomimo że LCD_refresh "na sztywno" zwraca 0:

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Jeżeli jednak lekko zmodyfikuję program, przez wołanie funkcji LCD_refresh przed wyrażeniem warunkowym, zapisując rezultat do zmiennej pomocniczej a następnie dokonuję sprawdzenia,
    wtedy wszystko działa zgodnie z założeniami, czyli zmienna lcdError jest równa 0.

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Co o tym myślicie? Wygląda mi na to na niejednoznaczne zachowanie kompilatora. Nie sprawdzałem co by się stało po zmianie optymalizacji podczas kompilacji- mam ustawioną domyślną.

    Dodam że program nie jest wielowątkowy, nie ma tu nawet żadnych przerwań, czysty bare metal.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 lut 2025, o 10:36 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27366
    Lokalizacja: Szczecin
    Pomógł: 1043

    to wynik zbyt agresywnej optymalizacji AVR GCC ale też nie ma co się dziwić gdy stosuje się aż TAK dziwaczne przypadki kodu - sorki ale ta funkcja lcdrefresh twoja jest totalnie bez sensu - więc można się też spodziewać że szczególnie przy jej wykorzystaniu w IF albo w wyrażeniu warunkowym GCC zrobić coś głupiego. W drugim przypadku gdy dajesz jej wartość do zmiennej, wymusza to już na GCC inne wygenerowanie kodu ASM i przerzucenie właściwej wartości do zmiennej bez nadmiernej optymalizacji.

    Mógłbyś sobie sprawdzić - bo pewnie masz (i dobrze) ustawioną opytmalizację na -Os bo tak się stosuje dla AVR ale jak byś zmienił na np -O2 to już mógłby inaczej się zachowywać kod w tym pierwszym przypadku.

    Niestety - moim zdaniem nie ma co testować kodów na TAK aż tak akademickich i nielogicznych przykładach - bo wystarczy że rozbudujesz tę funkcję lcdrferesh o jakieś warunki, sprawdzania, wykonania czegoś i już będzie dobrze się zachowywało w wyrażeniu warunkowym.

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 10 lut 2025, o 12:24 
    Offline
    Użytkownik

    Dołączył(a): 23 sty 2014
    Posty: 1085
    Pomógł: 73

    mirekk36 napisał(a):
    to wynik zbyt agresywnej optymalizacji AVR GCC ale też nie ma co się dziwić gdy stosuje się aż TAK dziwaczne przypadki kodu - sorki ale ta funkcja lcdrefresh twoja jest totalnie bez sensu (...)

    Niestety - moim zdaniem nie ma co testować kodów na TAK aż tak akademickich i nielogicznych przykładach - bo wystarczy że rozbudujesz tę funkcję lcdrferesh o jakieś warunki, sprawdzania, wykonania czegoś i już będzie dobrze się zachowywało w wyrażeniu warunkowym.


    Funkcja nie jest pusta, jest tam obsługa LCD, ustawianie GPIO itd. ale nie umieszczałem tego wszystkiego bo jakby najważniejsza jest zwracana wartość, ale fakt, mogłem wpisać tam komentarz :)

    Co ciekawe, gdy w późniejszym czasie rozbudowałem bardziej program, newralgiczny element
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
    zaczął działać znowu prawidło :)

    Post dodałem bardziej jako ciekawostkę/przestrogę dla tych, którzy też tak upraszczają kod jak ja :)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 17 lut 2025, o 21:18 
    Offline
    Nowy

    Dołączył(a): 12 lis 2024
    Posty: 15
    Pomógł: 1

    Dodał bym jeszcze że volatile przy lcdError brakuje. Kompilator jeśli może zawsze stara się umieszczać dane i zmienne w rejestrach platformy jeśli ma do nich dostęp (czyli np. nie zostały wyczerpane w danym kontekście wykonania). Im bardziej rozbudowany program, tym więcej rejestrów konsumujesz i tym większa szansa że wszystko co konieczne, zostanie "zsynchronizowane". Specyfikator volatile, powoduje zapis do pamięci bez względu na bieżącą gospodarkę rejestrami.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 11 mar 2025, o 21:24 
    Offline
    Nowy

    Dołączył(a): 11 mar 2025
    Posty: 3
    Pomógł: 0

    Jarecki napisał(a):
    Co o tym myślicie? Wygląda mi na to na niejednoznaczne zachowanie kompilatora. Nie sprawdzałem co by się stało po zmianie optymalizacji podczas kompilacji- mam ustawioną domyślną.


    domyślną to znaczy jaką? Do debugu używaj -O0 a do release -O2 albo -Os. Mi się kiedyś zdarzyło że na -O3 kod działał jak chciał (kod na przerwaniach) natomiast na O2 już prawidłwo. Być może na O3 volatile było traktowane z przymrużeniem oka ;) nie mnie avr-gcc to średni kompilator i miewa błędy.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Bing [Bot] i 4 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    cron
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO