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



Teraz jest 19 lut 2025, o 15:19


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 4 ] 
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 ]
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: 27359
Lokalizacja: Szczecin
Pomógł: 1042

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: 12
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  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 4 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 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