Skocz do zawartości

Oryginalność mikrokontrolerów AVR z Chin


Sabre

Pomocna odpowiedź

nse, o ile ja rozumiem ideę tego programu, obsługa przerwania kończy się ponownym włączeniem przerwań. Sabre nie idzie na łatwiznę i nie wraca z przerwania do miejsca jego wystąpienia - zamist tego chce przekierować program w nowe miejsce. Wbrew pozorom czasem takie sztuczki można stosować, chociaż nie jest to takie proste.

W przypadku tego programu problem polega na gubieniu zawartości stosu. Jeśli coś na nim było przed wystąpieniem przerwania, to zostanie już na zawsze. Albo raczej do przepełnienia stosu.

Link do komentarza
Share on other sites

Jak masz zdefiniowane bardzo dużo diod, to masz tam w pamięci duża tablicę i zajmuje więcej czasu zanim się stos przez nią przetoczy i dojdzie do jakichś krytycznych fragmentów programu -- w międzyczasie masz "losowe" zmiany w tej tablicy, ale to jeszcze nic nie zawiesza.

A próbowałeś wgrać na ten "dobry" procesor program skompilowany nową wersją bascoma?

Link do komentarza
Share on other sites

If Indeks = 0 Then

Waitms 500 " /// tu jest podstawowy problem zwróć uwagę ile czasu trwa obsługa przerwania

stosuj zasadę czas wykonywania podprogramu w przerwaniu ma być jak najkrótszy, a na pewno krótszy od czasu odstępu czasowego pomiędzy kolejnymi jego wywołaniami !

Jakie to ma znaczenie w tym przypadku, skoro przerwanie wywoływane jest co 5 sekund?

EDIT:

A próbowałeś wgrać na ten "dobry" proces program skompilowany nową wersją bascoma?

Nie rozumiem, mam cały czas najnowszą wersję Bascoma. On za każdym razem, gdy się uruchamia sprawdza, czy mam najnowszą wersję.

Jest tak jak napisał Elvis, tak działa mój program.

Link do komentarza
Share on other sites

Sabre, przerwania są trudnym tematem, bo występuje w nich wiele niedeterminizmu. Możesz mieć szczeście i program będzie otrzymywał przerwania w momencie kiedy nic nie ma na stosie. Możesz też mieć szczęście, zapełniać stos, a po "zawinięciu" wskaźnika dookoła całego RAM-u dalej działać.. To trochę loteria, ale lepiej niż eksperymentować z procesorami byłoby poprawić progam. Ciekawy problem odkryłeś 🙂

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@Sabre

Przerwanie jest Ci potrzebne jedynie do odebrania danej z pilota i nic więce, cała resztę obsłużysz w pętli głównej

/// pętla główna

do

cała reszta programu

obsługa odebranej danej

odblokowanie przerwań

loop

przrwanie:

blokada przerwąń

odbiór danej z pilota

return

Proste i to wszystko 😉

Link do komentarza
Share on other sites

Przyszedł mi do głowy taki eksperyment - czy mógłbyś na początku procedury obsłgi przerwania resetować stos? Nie wiem jak to zrobić z poziomu Bascom-a, ale może ktoś na forum będzie wiedział?

Wydaje mi się że potrzebna będzie wstawka w asemblerze, coś typu:

ldi r16,low(RAMEND)
out Spl,r16
ldi r16,high(RAMEND)
out sph,r16
Link do komentarza
Share on other sites

A próbowałeś wgrać na ten "dobry" procesor program skompilowany nową wersją bascoma?

Chyba załapałem o co Ci chodzi. Nie, nie dotykałem mikrokontrolera z lampek z uwagi na to, że tam wszystko działa. Zacząłem robić podświetlenie do szafki na diodach WS2812B sterowane z pilota IR na płytce arduino mini, które dostałem po świętach. Na 100% nie zmieniła się wersja Bascoma od 8 stycznia, a wtedy po raz ostatni modyfikowałem program lampek (dodawałem kolejne efekty). Zaczęło się od wieszania czyli braku reakcji na pilota po 36-37 zmianach efektów. Więc stwierdziłem, że coś jest nie tak z tym kodem. Wziąłem więc działający kod z lampek, gdzie obsługa przerwań jest spod przycisku a nie odbiornika IR i się zaczęło. Program wgrałem do mikrokontrolera, który dostałem razem z tymi arduino mini od jednego sprzedawcy z ebaya. No i się zaczęło, po kilku dniach walki z tym mikrokontrolerem powstał ten wątek.

Link do komentarza
Share on other sites

Już o tym napisałem, koledzy też, ale podkreślę raz jeszcze:

Przerwanie na tym najniższym poziomie jest z definicji obsługiwane w ten sposób, że procesor sprzętowo wysyła na stos adres powrotu. On tam siedzi już wtedy gdy wchodzisz do funkcji obsługi niezależnie od tego czy napiszesz nosave czy nie. Dopiero wtedy program może wypychać na stos rejestry, które ma zamiar zniszczyć. Jeżeli nigdy z przerwania nie wychodzisz instrukcją return (w asemblerze RETI - specjalny rodzaj powrotu którego kompilator używa po zakończeniu funkcji ISR) a odpalasz w nim nieskończoną pętlę jakiegoś efektu, to już masz na stosie nawis. Kolejne przerwanie - kolejny nawis. I tak z biegiem czasu każde kolejne przerwanie obniża sufit wskaźnika stosu i wolnej pamięci aż wchodzi na stertę (ale tej nie używasz) a potem zwykłe zmienne. Napisanie nosave tylko oddala katastrofę, ale niczego nie zmienia w złej koncepcji. Rozumiesz?

Link do komentarza
Share on other sites

nse, o ile ja rozumiem ideę tego programu, obsługa przerwania kończy się ponownym włączeniem przerwań. Sabre nie idzie na łatwiznę i nie wraca z przerwania do miejsca jego wystąpienia - zamist tego chce przekierować program w nowe miejsce. Wbrew pozorom czasem takie sztuczki można stosować, chociaż nie jest to takie proste.

W przypadku tego programu problem polega na gubieniu zawartości stosu. Jeśli coś na nim było przed wystąpieniem przerwania, to zostanie już na zawsze. Albo raczej do przepełnienia stosu.

Nie idzie na łatwiznę, tylko sobie życie komplikuje 🙂

Ja tą tematykę przerabiałem bez niczyjej pomocy, ale dla mnie praca z oscyloskopem to codzienność 🙂

Link do komentarza
Share on other sites

@Sabre

Przerwanie jest Ci potrzebne jedynie do odebrania danej z pilota i nic więce, cała resztę obsłużysz w pętli głównej

/// pętla główna

do

cała reszta programu

obsługa odebranej danej

odblokowanie przerwań

loop

przrwanie:

blokada przerwąń

odbiór danej z pilota

return

Proste i to wszystko 😉

Ale nie zrobię tego tak jak chcę, gdy obsługę danych z przerwania przerzucę do pętli głównej. Zauważ co się stanie w takim wypadku. Gdy z pętli głównej skoczę do podprogramu z efektem i wywołam przerwanie to po wykonaniu przerwania wrócę do pętli podprogramu z którego nie wyjdę do kolejnego podprogramu.

Choć z drugiej strony w zasadzie jest to możliwe. ale nie nastąpi to od razu. Musiałbym na początku każdego podprogramu z efektem zrobić sprawdzanie zmiennej Indeks i jeśli się ona zmieni (w przerwaniu) to z jednego podprogramu skoczyć do drugiego. Nie nastąpi to od razu, ale też nie spowoduje, że program będzie działał w pętli głównej, będzie działał dalej w samych podprogramach, a tylko raz za pierwszym wykonaniem w pętli głównej.

Jeśli masz jakiś pomysł jak to zrealizować tak, aby było poprawnie i aby działało tak jak ja chcę to słucham.

EDIT:

No dobra da się to zrobić w pętli głównej bez żadnych podprogramów. Każdy efekt mogę umieścić w pętli While -Wend z warunkiem na wartość zmiennej Indeks zmienianej w obsłudze przerwania. Ok, zrobię tak wieczorem i zdam relację. Usunę też "nosave" z przerwania. Kod zrobi się wtedy koszmarnie długi w jednym miejscu i będzie trudniejsze dodawanie nowych efektów (przez brak podprogramów).

Link do komentarza
Share on other sites

Też uważam, że czystość struktury programu - szczególnie mikrokontrolerowego, gdzie możemy zrobić wszystko bez żadnego nadzoru systemu operacyjnego - jest sprawą nadrzędną. Wszelkie sztuczki z nietypową manipulacją stosem albo taki przykład wykorzystania przerwań jak u Sabre to prosta droga do kłopotów. To nigdy nie jest uzasadnione i zawsze obraca się przeciwko nam. Można czasem coś podkrecić ale te sytuacje muszą być bardzo głęboko przemyślane, wymagają dogłębnej wiedzy o mechanizmach procesora, bardzo dobrze skomentowane i powinny przynosić spektakularne efekty niemożliwe do zrealizowania normalnymi metodami - przypadek chyba nigdy normalnie nie spotykany. Procesory mają tyle fajnych mechanizmów i takie moce obliczeniowe, że nie warto kombinować.

A w tym szczególnym przypadku, Sabre: przycisk jest ostatnią rzeczą jaką należy obsługiwać na przerwaniu. Ani nie wymaga tego prędkość reakcji ani też sama jego "mechaniczność" i przypadkowość działania nie pozwalają na myślenie o nim jak o źródle bezpośrednich przerwań sprzętowych. To błąd w sztuce, założenie które legło u podstaw dalszych problemów, podobnie jak niezgodne ze zdrowym rozsądkiem korzystanie z systemu przerwań.

Wiedząc już chyba wszystko o celach i założeniach funkcjonalnych możemy za to zastanowić się jak powinna być struktura tego programu żeby spełniała wymagania czystego kodu. Propozycje w jakimś pseudokodzie?

Link do komentarza
Share on other sites

Wychodź z podprogramu jak się zmieni indeks, a w pętli głównej wchodź do następnego.

Tak też się da, zapomniałem zupełnie o tym, że można na żądanie wyjść z podprogramu, ale znowu nie będzie to od razu tylko w obiegu pętli. Przy efekcie na 8 diodach tego czasu się nie da zauważyć, ale przy 100 diodach, gdzie obieg pętli trwa długo to przeskok do kolejnego efektu przy konstrukcji innej niż obecna będzie trwał nawet kilka sekund niestety a to jest w zasadzie niedopuszczalne w mojej konstrukcji lampek choinkowych (ale ze względu na to, że tamten kod działa na tym mikrokontrolerze bez problemu to nie będę tam zmieniał kodu na "zgodny ze sztuką").

Link do komentarza
Share on other sites

@Sabre

Obsługa przerwania ma w tle programu odebrać daną z pilota, a program w pętli głównej ma zadecydować co z tą daną zrobić i jakie zmiany ona wprowadziła, po obsłużeniu tego zezwalasz

na odebranie kolejnej danej z pilota, wtedy pętla główna programu będzie jedynie przerywana na czas odebrania danej co statystycznie trwa ok 10 - 100ms zależy od pilota, takiego sporadycznego zakłócenia w pracy programu nie zauważysz.

Nad takimi problemami siedziałem kilka lat temu i nie miałem z kim o tych problemach pogadać 🙂

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.