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



Teraz jest 12 gru 2024, o 21:44


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 16 ] 
Autor Wiadomość
PostNapisane: 15 sie 2014, o 18:02 
Offline
Nowy

Dołączył(a): 15 sie 2014
Posty: 5
Pomógł: 0

Witam serdecznie.
Chciałbym i ja dorzucić swoje "trzy grosze" do tej skarbnicy wiedzy jaką jest to forum i zwrócić uwagę na pewne niebezpieczeństwo związane ze stosowaniem zmiennej typu volatile większej niż 1 bajt na procesorach 8-bitowych.
Najpierw przygotuję poligon doświadczalny, którym będzie w tym wypadku programik z użyciem "timera programowego". Zainstaluję "minę" wykorzystując zmienną, która będzie zadeklarowana jako - volatile uint16_t licz_ms - i na koniec postaram się świadomie na nią nadepnąć aby pokazać, że skutki jej działania mogą się nam nie spodobać.
Ciekawostką może być to, że "zwykły" program może nigdy na taką minę nie natrafić a jeśli już to w zupełnie przypadkowym (z naszego punktu widzenia) momencie i trudno będzie wyłapać przyczynę tego błędnego zachowania. Dodam jeszcze, że aby nastąpiła eksplozja musi jednocześnie wystąpić kilka przesłanek... ale może o tym później.

Na początek poligon czyli pomigamy diodą (ja używam ATmega88, kwarc 11.0592MHz)

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


Uruchamiamy program i ... nic specjalnego się nie dzieje. Dioda miga sobie leniwie co ok. 0,5s co widać na poniższym obrazku.

Obrazek
LED_TOG w przerwaniu

Ponieważ w "prawdziwym" programie po osiągnięciu przez licz_ms wartości 0x0000 wykonujemy z reguły coś bardziej skomplikowanego i czasochłonnego niż zmianę stanu diody uwolnijmy od tego przerwanie i wyrzućmy obsługę "migania" ze środka przerwania do pętli głównej i stwórzmy obsługę pseudo zdarzenia.

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


Uwaga!!! Właśnie zainstalowaliśmy "minę"!!! Jaką "minę"? Przecież z punktu widzenia programisty nie popełniliśmy żadnego błędu.
Uruchamiamy program i ... wreszcie coś się dzieje (przynajmniej u mnie) . Dioda, która ma zmieniać stan co ok. 0,5s u mnie co trzeci takt skraca sobie pracę o ok. 250ms. co widać na poniższym obrazku.

Obrazek
LED_TOG w pętli głównej

Jest to właśnie efekt działania naszej "miny" ale i my możemy się nazwać szczęśliwcami, że udało się to zobaczyć. Dlaczego?

Dzieje się tak dlatego, że... ale o tym w następnym poście. Żartuję. Jednak żeby nie zanudzić postaram się o bardzo krótką analizę.
Takie błędne przełączanie diody zdarzyć się może jeżeli czas cyklu ustawiany w licz_ms ma wartość większą niż 255 (0x00FF) (tzn. gdy bardziej znaczący bajt licz_ms, który jest - przypomnę - typu uint16_t jest różny od zera). Tak jest w naszym przypadku bo 500 to 0x01F4. Ale to jeszcze za mało. Przerwanie musi nastąpić w czasie badania warunku if (!licz_ms) w pętli głównej, którego kod kompilator zamienił sobie "beztrosko" na następujący widziany z poziomu asemblera:

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

Przerwanie musi trafić dokładnie w momencie pomiędzy pobraniem bajtu do r24 ale przed pobraniem bajtu do r25.
Ale i to nie wystarczy. Dopiero gdy wartość w licz_ms będzie w tym momencie równa 0x0100 spełnione zostaną wszystkie przesłanki do tego aby nasza mina eksplodowała.
Spójrzmy co się stanie. Popatrzmy na kod w asemblerze. Jak wiemy pobranie do analizy słowa 16-bitowego w mikrokontrolerze 8-bitowym musi nastąpić w dwóch cyklach i jak widzimy tak się dzieje. W chwili, o której mówimy w r24 jest już przechowywany mniej znaczący bajt zmiennej licz_ms czyli 0x00. Teraz przychodzi przerwanie, które zatrzymuje wykonywanie pętli głównej, zmniejsza zawartość naszego licz_ms o 1 i zamiast 0x0100 mamy w licz_ms 0x00FF. Pętla główna może teraz dokończyć swoje zadanie i pobiera do r25 bardziej znaczący bajt licz_ms czyli 0x00 (a nie 0x01 jak było przed przerwaniem)!!! Teraz właśnie eksplodowała nasza mina i samowolnie skróciła czas odliczania naszego timera o 0xFF przerwań (w naszym przypadku o ok. 255ms) bo dla pętli głównej jest spełniony warunek r24=0x00 i r25=0x00 czyli licz_ms = 0x0000 i można przełączyć diodę, i załadować do licz_ms początkową wartość czyli 500 (0x01F4).
Nazwałem nas wcześniej "szczęśliwcami", że możemy zobaczyć efekt eksplozji naszej miny bo widać ile warunków musi być jednocześnie spełnionych aby to nastąpiło.
Na koniec mając już świadomość na jakie niebezpieczeństwo naraził nas kompilator nie blokując przerwań na czas analizy warunku if (!licz_ms) (bo przecież my nie popełniamy błędu z punktu widzenia sztuki programowania) zróbmy to za niego i zobaczmy czy rzeczywiście rozbroimy minę.

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


Odpalamy (może niefortunne określenie w tym kontekście) program i.... dioda miga sobie równo co ok. 0,5s co widać na poniższym obrazku

Obrazek
LED_TOG w pętli głównej po poprawce

Jak widać istnieje realne niebezpieczeństwo użycia volatile większej niż 1 bajt na procesorach 8-bitowych (z takim kompilatorem). Im dłuższy program, więcej przerwań, rozgałęzień programu itp. tym mniejsze prawdopodobieństwo, że program natknie się na taką "minę" ale i większy ból głowy z wykryciem tego błędu. Np. po odebraniu jakiś danych przez UART tak się takty procesora ułożą, że "mina" np. zakłóci pracę jakiegoś ważnego "timera programowego" a my będziemy szukali błędu w obsłudze przerwania od UART-a. Jeżeli tych timerów jest kilka może się zacząć naprawdę niezła zabawa doprowadzająca do wniosku, że język C to g... albo, że my jesteśmy programistami do d... No, może mnie trochę poniosło ale mając teraz świadomość "zagrożenia" sami, świadomie będziemy mogli zadecydować czy to w naszym programie jest bez znaczenia, czy od razu rozbroimy tę minę.

Pozdrawiam wszystkich saperów a szczególnie Sapera Wszystkich Saperów - Mirka.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 sie 2014, o 19:19 
Offline
Moderator
Avatar użytkownika

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

Dokładnie - niebezpieczeństw z volatile nie ma, bo podobnie mogą się zachowywać i zwykłe zmienne 16-bitowe

więc albo ATOMIC_BLOCK ;) i to jest rozwiązanie - atomowość

albo chociaż ręcznie

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



no ale to jest właśnie dokładnie to samo co ATOMIC tylko widziane od środka

_________________
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: 15 sie 2014, o 21:01 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Udało mi się kiedyś uzyskać takie przebiegi, jak zaczynałem się bawić timerami programowymi, połapałem się co jest nie tak właśnie po tym czasie ok. 255 ms. ATOMIC_BLOCK załatwia sprawę, można też ręcznie zapamiętać zawartość SREG, zablokować przerwania, wykonać if-a który może się wysypać i odblokować przerwania. Co do flagi, najlepiej chyba użyć w takim wypadku sprzętowej, albo wykonać całą obsługę timera w przerwaniu. Teraz już nie pamiętam dokładnie ale przy przerwaniu co 1 ms, jego obsługa zajmowała mi kilka us, więc procesor się bezproblemowo wyrabiał nawet przy sporej ilości timerów.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 09:32 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1967
Lokalizacja: Lipsko
Pomógł: 125

Hehe, stary problem 8-) Miałem tak kiedyś z bascomem nieświadomy, że przerwania potrafią w połowie instrukcji się wywołać (co zresztą logiczne) swego czasu otworzyłem watek nawet na forum mscelc - podaje adres może ktoś skorzysta:

http://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=11855&highlight=

Obecnie inaczej konstruuję liczniki (odświeżanie umieszczam w przerwaniach) albo za pomocą flag (jeśli licznik ma być regulowany) - ustawiona flaga to gotowy uaktualniony wpis licznika i wtedy przerwania nie są groźne.

W każdym razie dobrze, że temat został poruszony, bo kiedy ja szukałem coś na ten temat to nic nie mogłem znaleźć (stąd post na obcym forum), a taka mina, o której piszesz może wpłynąć na... minę niejednego programisty podczas nauki programowania :lol:

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 14:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 maja 2013
Posty: 568
Zbananowany użytkownik

Pomógł: 31

Wystarczy zamienić instrukcje Assemblera LDS miejscami i problem nie wystąpi.
Drugi sposób jaki mi przychodzi na myśl to zmiana sposobu zliczania, z dekrementacji na inkrementacje.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
Und schreien

Spring
Erlöse mich
Spring
...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 20:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1967
Lokalizacja: Lipsko
Pomógł: 125

@PROTON obawiam się, że nie masz racji. Tu chodzi o zapis świeżej wartości do zmiennej 16-o bitowej i jeśli w trakcie zapisu przejdzie tylko pierwsze 8 bitów tej zmiennej i zacznie się wykonywać przerwanie to problem gotowy, bo w przerwaniu już się zmieni te wpisane 8 bitów i kiedy przyjdzie reszta to nijak będzie się miała ta wartość do tego co było zamiarem przesłania dla timera programowego.

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 20:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sty 2013
Posty: 123
Lokalizacja: Warszawa
Pomógł: 10

Ja ze swej strony, nie polecam flag w postaci 'pól bitowych' na procesorach 32 bitowych (może na 8-bitowcach, gdzie są bezpośrednie rozkazy ustawiające/kasujące poszczególne bity w rejestrach, to działa).
Ile ja miałem "dziwnych przypadków działania" zanim nie przeszedłem na pełne bajty :?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 21:19 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1967
Lokalizacja: Lipsko
Pomógł: 125

Kiedyś na attiny13 w jakimś prostym programie głupoty mi się działy przez flagę bitową - kompletnie w przypadkowych momentach pojawiały się bzdury. Wystarczy że tą flagę zmieniłem na pełny bajt i jak ręką odjął...

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 22:55 
Offline
Nowy

Dołączył(a): 15 sie 2014
Posty: 5
Pomógł: 0

Dziękuję wszystkim kolegom za te interesujące uwagi. Dzięki temu wszyscy mamy okazję się czegoś nowego nauczyć, niekoniecznie na własnych błędach. I o to w tej zabawie chodzi.
mirekk36 napisał(a):
Dokładnie - niebezpieczeństw z volatile nie ma, bo podobnie mogą się zachowywać i zwykłe zmienne 16-bitowe

Dokładnie to jest tak jak napisałem. Niebezpieczeństwo istnieje, jest jak najbardziej realne i może dać o sobie znać w zupełnie nieprzewidywalnym dla nas momencie. Wydaje mi się, że jasno to opisałem (ale może mi się tylko wydaje).
Również autorzy dokumentu cytowanego przez kolegę o nicku mokrowski widzą to zagrożenie i nawet podają na tacy jedno z lekarstw na tę dolegliwość.
Drugiej części Twojej opinii nie rozumiem. Chcesz powiedzieć, że jakieś przerwanie może spowodować taki sam efekt gdy program główny realizuje instrukcję warunku na zmiennej nie będącej volatile? Jedyna możliwość jaka mi przychodzi do głowy to taka, że programista dał przerwaniu dostęp do tej zmiennej np. przez referencję (lub jak ktoś woli przez wskaźnik) bo w innym wypadku... No, ale ja dopiero zaczynam przygodę z C i chętnie się dowiem co miałeś na myśli bo to byłaby dla mnie prawdziwa bomba.

Ponieważ z większości uwag w tym wątku powoli rodzi się temat "jak rozbroić tę minę" chciałbym przypomnieć, że moim celem było jedynie zwrócenie uwagi na możliwość błędnego zachowania się programu gdy używamy "timerów programowych" korzystających ze zmiennej typu volatile większej niż 1 bajt na procesorach 8-bitowych pomimo, że program jest napisany poprawnie z punktu widzenia języka C.
Chciałem, żeby po przeczytaniu tego wątku każdy kto zamierza stosować tę technikę miał świadomość istnienia takiego niebezpieczeństwa i zawsze świadomie decydował czy trzeba taką "minę" rozbroić.
Jeżeli używam takiego timera jak w przykładzie z początku postu np. do odczytu temperatury co 5s to mam świadomość, że może się zdarzyć sytuacja, że ten czas będzie krótszy o 255ms i świadomie nic z tym nie robię bo to dla mnie jest bez znaczenia. W sytuacji gdy potrzebuję np. w miarę precyzyjnego odliczania 300ms mam świadomość, że może się zdarzyć odliczenie 5ms zamiast 300 i świadomie inaczej realizuję to odliczanie itp.
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 16 sie 2014, o 23:11 
Offline
Moderator
Avatar użytkownika

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

Do tego zagadnienia można podchodzić na dwa sposoby, tak jak ze szklanką, która może być:

1. napełniona do połowy
2. albo do połowy pełna

:lol:

dlatego np z mojego punktu widzenia to nie są żadne miny .... czy niebezpieczeństwa albo inne jakieś tam groźne rzeczy. Bo równie dobrze można by tak samo powiedzieć że MINĄ jest gdy początkujący nie da pętli nieskończonej w głównej funkcji programu main() ;) i dziwi się, że program mu nie działa. Ale to nie jest mina im więcej poznajemy język i techniki programowania tym więcej się uczymy jak należy programować i to tylko tyle ...

kamasz napisał(a):
chciałbym przypomnieć, że moim celem było jedynie zwrócenie uwagi na możliwość błędnego zachowania się programu gdy używamy "timerów programowych" korzystających ze zmiennej typu volatile większej niż 1 bajt na procesorach 8-bitowych pomimo, że program jest napisany poprawnie z punktu widzenia języka C


Ja szczególnie na początku drogi zwykle polecam oddalać od siebie myśli, że program jest poprawnie napisany ale nie działa bo mamy minę ... czyli co ? kompilator źle działa ? czyli co? procesor źle działa ? ... nie, nie, nie - nie tędy droga wg mnie

Jeśli ty jako programista napiszesz program, który nie działa to ty jesteś za to odpowiedzialny a nie kompilator, procesor, prąd itp ... Tyle że na różnym stopniu zaawansowania poznajesz nowe i coraz ciekawsze techniki ... i o to chodzi - to są te fajne smaczki - przynajmniej jak dla mnie ..

kamasz napisał(a):
hcesz powiedzieć, że jakieś przerwanie może spowodować taki sam efekt gdy program główny realizuje instrukcję warunku na zmiennej nie będącej volatile? Jedyna możliwość jaka mi przychodzi do głowy to taka, że programista dał przerwaniu dostęp do tej zmiennej np. przez referencję (lub jak ktoś woli przez wskaźnik) bo w innym wypadku... No, ale ja dopiero zaczynam przygodę z C i chętnie się dowiem co miałeś na myśli bo to byłaby dla mnie prawdziwa bomba.


nie ma tu bomby ... nawet gdyby dostęp do zmiennej (16-bitowej) był w warunku i to przez wskaźnik ... to i tak twoim zadaniem jest pomyślenie o atomowości ... ale wiesz kiedy jest łatwiej o tym myśleć ? ... gdy się chociaż troszkę asemblera zawsze liźnie - bo wtedy zawsze można podejrzeć wygenerowany kod i zobaczyć - że każda operacja w ASM na zmiennej większej niż 8-bit w 8-bitowcach oczywiście, gdy jest wykonywana za pomocą kilku rozkazów ASM bo inaczej nie da rady - to wtedy od razu widać ... że pomiędzy te rozkazy może "wkraść" się przerwanie i czasem pomieszać nam szyki ...

Poza tym nie zawsze o zmienne chodzi ale chociażby o zmianę czasem wartości 16-bitowych rejestrów timerów z poziomu programu głównego itp ...

kamasz napisał(a):
Jeżeli używam takiego timera jak w przykładzie z początku postu np. do odczytu temperatury co 5s to mam świadomość, że może się zdarzyć sytuacja, że ten czas będzie krótszy o 255ms i świadomie nic z tym nie robię bo to dla mnie jest bez znaczenia. W sytuacji gdy potrzebuję np. w miarę precyzyjnego odliczania 300ms mam świadomość, że może się zdarzyć odliczenie 5ms zamiast 300 i świadomie inaczej realizuję to odliczanie itp


I to jest bardzo dobry wniosek ;)

_________________
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: 17 sie 2014, o 19:56 
Offline
Nowy

Dołączył(a): 15 sie 2014
Posty: 5
Pomógł: 0

mirekk36 napisał(a):
Do tego zagadnienia można podchodzić na dwa sposoby, tak jak ze szklanką, która może być:

1. napełniona do połowy
2. albo do połowy pełna

:lol:

dlatego np z mojego punktu widzenia to nie są żadne miny .... czy niebezpieczeństwa albo inne jakieś tam groźne rzeczy.

Oczywiście masz prawo do takiego zdania. Ja pozostaję przy swoim.

mirekk36 napisał(a):
Bo równie dobrze można by tak samo powiedzieć że MINĄ jest gdy początkujący nie da pętli nieskończonej w głównej funkcji programu main() ;) i dziwi się, że program mu nie działa. Ale to nie jest mina im więcej poznajemy język i techniki programowania tym więcej się uczymy jak należy programować i to tylko tyle ...

Przecież zdajesz sobie sprawę, że nie o taki błąd tutaj chodzi?

mirekk36 napisał(a):
Ja szczególnie na początku drogi zwykle polecam oddalać od siebie myśli, że program jest poprawnie napisany ale nie działa bo mamy minę ... czyli co ? kompilator źle działa ? czyli co? procesor źle działa ? ... nie, nie, nie - nie tędy droga wg mnie

Ja z kolei trochę żałuję, że na początku mojej drogi nie spotkałem się z przykładem tak prostego kodu jak w przykładzie - z ostrzeżeniem, że chociaż program jest napisany poprawnie pod względem składni języka C to może działać błędnie bo kod sprawdzania warunku jest w takiej sytuacji skompilowany ułomnie (nazwałem to "beztrosko") bo bez wiedzy o kontekście tej operacji i muszę mieć tego świadomość.

mirekk36 napisał(a):
Jeśli ty jako programista napiszesz program, który nie działa to ty jesteś za to odpowiedzialny a nie kompilator, procesor, prąd itp ... Tyle że na różnym stopniu zaawansowania poznajesz nowe i coraz ciekawsze techniki ... i o to chodzi - to są te fajne smaczki - przynajmniej jak dla mnie ..

Pisząc program w asemblerze mam kontrolę nad każdym taktem procesora. Pisząc w C lub innym języku wyższego poziomu posługuję się narzędziem (kompilatorem) skonstruowanym przez innych ludzi i muszę mieć wiedzę o ograniczeniach tego narzędzia (nic nie jest przecież doskonałe). Wiedzą o jednej z takich ułomności chciałem się podzielić z forumowiczami i nie jest to dla mnie żaden "smaczek".

mirekk36 napisał(a):
nie ma tu bomby ... nawet gdyby dostęp do zmiennej (16-bitowej) był w warunku i to przez wskaźnik ... to i tak twoim zadaniem jest pomyślenie o atomowości ... ale wiesz kiedy jest łatwiej o tym myśleć ? ... gdy się chociaż troszkę asemblera zawsze liźnie - bo wtedy zawsze można podejrzeć wygenerowany kod i zobaczyć - że każda operacja w ASM na zmiennej większej niż 8-bit w 8-bitowcach oczywiście, gdy jest wykonywana za pomocą kilku rozkazów ASM bo inaczej nie da rady - to wtedy od razu widać ... że pomiędzy te rozkazy może "wkraść" się przerwanie i czasem pomieszać nam szyki ...

Rozumiem, że pora jest późna i można mieć problemy z koncentracją. Przecież właśnie o tym napisałem wyjaśniając w czym tkwi problem.

mirekk36 napisał(a):
Poza tym nie zawsze o zmienne chodzi ale chociażby o zmianę czasem wartości 16-bitowych rejestrów timerów z poziomu programu głównego itp ...

Fakt. Dzięki.

mirekk36 napisał(a):
I to jest bardzo dobry wniosek ;)

Jest to raczej "łopatologiczne" wytłumaczenie moich intencji.;)
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 sie 2014, o 20:05 
Offline
Moderator
Avatar użytkownika

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

kamasz napisał(a):
Oczywiście masz prawo do takiego zdania. Ja pozostaję przy swoim.


Ależ ja ciebie nie namawiam do przyjęcia mojego zdania - powiedziałem swoje - a twoje też szanuję ;)

kamasz napisał(a):
Przecież zdajesz sobie sprawę, że nie o taki błąd tutaj chodzi?


To porównanie błędów na różnym poziomie własnej świadomości hmm wiedzy na temat C ... więc w zasadzie ogólnie chodzi o to samo.

kamasz napisał(a):
Wiedzą o jednej z takich ułomności chciałem się podzielić z forumowiczami i nie jest to dla mnie żaden "smaczek".


Ależ po to jest forum żeby się dzielić - ja jednak znając i ASM i C w jakimś stopniu muszę pozostać przy swoim, że nie można beztrosko pisać o ułomności kompilatorów itp .. gdy coś mi nie wychodzi - bo nie wiem jak tego tak naprawdę jeszcze używać ... tylko to miałem na myśli

_________________
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: 17 sie 2014, o 20:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sty 2013
Posty: 123
Lokalizacja: Warszawa
Pomógł: 10

mirekk36 napisał(a):
Ja jednak znając i ASM i C w jakimś stopniu

Obawiam się, że zmierzamy w kierunku sytuacji, kiedy znajomość ASM będzie umiejętnością zanikającą. Ci którzy zaczynali od 8-bitowców naturalną koleją rzeczy musieli zapoznać się z ASM.
Teraz jednak króluje C, a w większych procesorach już prawie tylko i wyłącznie, więc nie ma motywacji do zagłębiania się w ASM.
W tej sytuacji ludzie będą w coraz większym stopniu polegać na kompilatorach, ale wiedza ta będzie coraz bardziej powierzchowna - nie uwzględniająca tego co się dzieje "pod spodem".
No ale - taka kolej rzeczy :-)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 sie 2014, o 21:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sty 2013
Posty: 123
Lokalizacja: Warszawa
Pomógł: 10

No - ja tylko zauważyłem pewien ciąg przyczynowo skutkowy - Kolega wyłapał błąd, bo mógł sobie podejrzeć i zanalizować kod jaki mu kompilator wygenerował i na tej podstawie domyślił się w czym leży problem i dzięki temu mógł zaaplikować właściwy "workarouond". Znajomość ASM mu w tym pomogła.
W innym przypadku musiałby się nauczyć na pamięć, "że nie należy takich rzeczy robić" - co oczywiście można zaliczyć do dobrych zasad programowania - aczkolwiek dobrze wiedzieć dlaczego tak nie należy robić ;-)
Do programowania w samym ASM rzecz jasna nie namawiam - chyba, że akurat jest to niezbędne z jakiś przyczyn.

Może szkoda, że wątek nie będzie kontynuowany, bo przecież takich pułapek-min nie brakuje - jak to wiemy z codziennej praktyki, a gdyby je zebrać w jednym miejscu, to by się człowiek na pewne rzeczy uczulił ;-)
Ale może lepiej jak każdy uczy się na własnej skórze.... :roll:



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 sie 2014, o 22:40 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sty 2013
Posty: 123
Lokalizacja: Warszawa
Pomógł: 10

Ja z PIC8 przeskoczyłem na 32bity, a AVR tylko "musnąłem w locie", więc nie podam konkretnych dla tych procesorów przypadków.
Ale miałem raz ciekawy przypadek z obsługą przerwania (dla 32bit).
Rzecz dotyczyła SPI.
Procedura przerwania miała wysyłać ciąg bajtów pobieranych z bufora - w każdym przerwaniu kolejny bajt.
Jednakże po wysłaniu kilku bajtów proces ich wysyłania zanikał - tak jakby przerwanie się przestało wywoływać.
Początkowo podejrzewałem, że może gdzieś jakieś flagi, coś nadpisuje dane, etc ,etc...
Ale po "ciężkich bojach" okazało się, że winowajcą jest niewłaściwe miejsce kasowania flagi przerwania od SPI.
Początkowo znajdowało się ono na końcu przerwania - po przeniesieniu go na sam początek IRQ - błędy ustały.
W czym był problem.
Ponieważ szybkość transmisji SPI była dość duża (40MHz), to okazało się, że bajt zdąży się wysłać zanim bieżąco obsługiwane przerwanie zakończy się. Następowało więc jakby nadpisanie flagi przerwania, a dodatkowo podczas wychodzenia z IRQ flaga ta była kasowana i tym samym zanikało dalsze wyzwalanie się przerwań.

Od tej pory zawsze kasuję flagę przerwania od razu po wejściu do niego ;-)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 18 sie 2014, o 07:48 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 maja 2013
Posty: 568
Zbananowany użytkownik

Pomógł: 31

Panowie, każdy kto programuje trafia na różne problemy, pomimo prawidłowo napisanego kodu coś czasem nie działa. Czasem są to "Undefined behavior",czasem zachowanie sprzętu. Znajomość asemblera pomaga w diagnozie, nie zawsze.

_________________
Und schreien

Spring
Erlöse mich
Spring
...



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: 16 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 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:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO