Problem lekko OT, ale w WinAVR ;-)

Użytkownik T.M.F. napisał:

Niestety oryginalne z interrupt.h i są one tam zdefiniowane dokładnie tak jak Kolega napisał.

W dużym uproszczeniu ogranicza kompilatorowi możliwości optymalizacji. W stosunku do zmiennej wymusza bezwarunkowe każdorazowe czytanie aktualnej wartości zmiennej z pamięci przed wykonaniem jakichkolwiek operacji na zmiennej. Czyli kompilatorowi nie wolno dla uproszczenia/przyśpieszenia kodu banglać przez cała procedurę na wartości skopiowanej do rejestrów. Inaczej mówiąc zmienna ma być tak traktowana jakby jej zawartość mogła się w każdej chwili zmienić (np. przez inny wątek programu). W kontekście powyższego (chyba, że jest jednak inna definicja volatile) nadal nie mogę zrozumieć z jakiej paki rozkaz sei() umieszczony na końcu funkcji znalazł się nagle na jej początku.

Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk
Loading thread data ...

Użytkownik Zbych napisał:

No to teraz już wiem :-) Dzięki za cenną wskazówkę.

Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk

Nie - to rozkaz = ze srodka funkcji znalazl sie na jej koncu :-)

J.

Reply to
J.F.

Użytkownik J.F. napisał:

No fakt :-) Można to też w taki sposób zinterpretować :-) Co oczywiście nie rozwiązuje kwestii "z jakiej paki".

Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk

Jest potrzebny na koncu [do zwrocenia wartosci], to przerzucaja na koniec .. po co ma wczesniej rejestry zajmowac ?

J.

Reply to
J.F.

Użytkownik J.F. napisał:

To dlaczego w przytoczonej funkcji SetEncoder też tak nie zrobił ? Tam wszystko jest w takiej kolejności jak w źródłówce - sei jest na końcu, choć z "matematycznego" punktu widzenia sei nie ma wpływu na wartość obliczeń i może se być wrzuconym gdziekolwiek ;-)

Ufff... kończmy tę dyskusję, bo się mały flejmik robi :-) Kolega Zbych podał konkretne i skuteczne rozwiązanie problemu, choć nadal nie mogę zrozumieć czemu akurat tak się dzieje ? Cóż trzeba przyjąć to na "wiarę", że tak ma być i koniec ;-)

Jeszcze raz dziękuję Kolegom za udział w dyskusji. Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk

Użytkownik T.M.F. napisał:

Błędów by nie było pod warunkiem, że sei wylądowałoby na końcu tam gdzie je napisałem. W sekcji między cli, a sei program staje się jednowątkowy i nie ma powodu dla którego wartość tej zmiennej mogłby ulec zmianie, ale fakt... Samo volatile też nie załatwiłoby sprawy. Musi być połaczone z sekcją cli/sei.

Ale ja nigdzie nie twierdzę, że to nie moja wina :-) Pewnie, że moja. Wystarczyło dopisać volatile lub zastosować sekcję ATOMIC_BLOCK i jest ok. Poprostu kiedyś tam zasugerowałem się tym, że przecież volatile stosuje się po to aby wymusić każdorazowe czytanie zmiennej z pamięci, a moim celem było uniemożliwienie aby cokolwiek innego zmieniło wartość tej zmiennej na czas wykonywania wnętrza funkcji. A zmienna w tej funkcji czytana jest w sumie tylko raz. Takie małe odwrócenie problemu :-) I co gorsza/lepsza w starszych wersjach WinAVR kompilowało się to "po ludzku", co uśpiło moją czujność ;-)

Jeszcze raz dziękuję Kolegom za cenne wskazówki.

Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk

No bo tam nie bylo takiej potrzeby :-)

Jak sam zreszta zauwazyles - dodanie volatile zaowocowalo dluzszym kodem. No to slusznie bez volatile zoptymalizowal do krotszego :-)

Inna sprawa ze ta kompilacja dziwna jakas i wcale niepotrzebnie dluzsza.

No coz - moral z tego taki ze czasem warto w kod wynikowy zajrzec. Czlowiek sie czegos moze dowiedziec.

Inna sprawa ze w tym miejscu to volatile powinienes z przyzwyczajenia pisac :-)

J.

Reply to
J.F.

W dniu 13.06.2009 02:43, Grzegorz Kurczyk pisze:

Skad masz makra sei() i cli()? To twoja wlasna definicja czy z biblioteki avr-glibc - pliku interrupts.h? Zakladam, ze twoja wlasna, stad problemy. Oryginalna prawidlowa definicja wyglada tak: #define sei() __asm__ __volatile__ ("sei" ::)

Zwroc uwage na slowo volatile. Swoja droga przeczytaj jak volatile dziala to rozwiaze sie wiele twoich dziwnych klopotow.

Reply to
T.M.F.

Zadna to operacja specjalna, po prostu PORTB zdefiniowany jest jako volatile, co implikuje, ze kompilator nie robi dziwnych przetasowan, bo wie, ze mu nie wolno.

Reply to
T.M.F.

W dniu 12.06.2009 07:27, Zbych pisze:

Bo zdefiniowalem takze cialo funkcji, zeby przejsc kompilacje i linkowanie.

Reply to
T.M.F.

W dniu 13.06.2009 06:10, Grzegorz Kurczyk pisze:

To nie jest tak jak piszesz. W twoim przykladzie kompilator zachowal sie zupelnie poprawnie. Zauwaz, ze nie podales nigdzie, ze pEncoderValue jest volatile, w efekcie kompilator slusznie uznal, ze wartosc tej zmiennej nie moze sie zmienic nigdzie poza aktualnie kompilowana sekcja, a wiec miejsce gdzie nastapi przypisanie: int e = *pEncoderValue; jest zupelnie dowolne. W koncu skoro nic w miedzyczasie nie modyfikuje pEncoderValue to umieszczanie tego w sekcji krytycznej nie ma sensu i kompilator sobie zoptymalizowal to tak jak mu pasowalo. Dopiero okreslenie tej zmiennej jako volatile mowi kompilatorowi, ze z ta zmienna trzeba uwazac i nie mozna sobie dowolnie jej przekladac. Z kolei jesli pEncoderValue jest modyfikowane poza procedura, ktora pokazales np. w jakims przerwaniu to okreslenie tej zmiennej jako volatile jest obowiazkowe! Inaczej masz efekty takie jak pokazales. Co wiecej gdybys dalej cops robil z ta zmienna w swojej procedurze to kompilator jej pewnie ponownie by nie ladowal, czyli mialbys kolejne dziwne bledy. Ale to ciagle twoja wina i nie ma co zwalac na gcc.

Reply to
T.M.F.

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.