Napisałem program, ale zastanawiam się jakie są szanse na jakiś sprzętowy błąd w atmedze8.
Mam dwa przerwania TIMER i UART. Timer uruchamia się co ~8000 cykli na 1000 cykli. UART uruchamia się maksymalnie co 2000 cykli na zaledwie 100, bo tam w sumie wszystko usunąłem na próbę. UART niczego modyfikuje tylko jedną zmienną, ale to zwykła zmienna globalna (wszystko co obliczane usunąłem).
TIMER ma sei(), żeby UART uruchamiał się obowiązkowo zawsze, ale za względu na logikę, to uruchomi max 1 (no liczmy 2) razy w czasie przerwania TIMER, czyli nadal mieścimy się w okienku.
Dodałem pułapki sprawdzające stan SP i Heap na wszelki wypadek, ale to bez znaczenia, bo choć sprawdziłem czy działają i chyba jest z nimi ok, to nie wyłapują jakiegoś nadpisywania.
Przejrzałem wszystko co tylko się da, pomiędzy dolną pamięcią na zmienne i heap jest jeszcze kilkaset bajtów wolnej przestrzeni do górnej granicy zmiennych lokalnych SP. Z malloca nie korzystam poza w/w kodem.
W TIMERze mam jedną lokalną tablicę 160 elementów. I jak ona jest w timerze to nadpisuje mi pamięć globalną raz na ileś sekund w czasie odbierania danych przez UART (uart nie modyfikuje nawet tego obszaru pamięci, który ulega uszkodzeniu, TIMER też nie modyfikuje tej pamięci globalnej). W TIMERze jest te 160 elementów utworzone i tam jest tylko kopiowana zawartość pamięci z globalnej takiej samej tablicy (to na przyszłość kodu, żeby UART modyfikował globalną, a TIMER zawsze dostawał tablicę niezmodyfikowaną, co tutaj nie ma znaczenia dla tego przykładu).
Jak tablicę lokalną 160 elementów wyrzucę przed przerwanie, to wszystko działa elegancko.
Dodałem jeszcze na wszelki wypadek licznik na początku i na końcu przerwań. Na początku jest ++ na końcu -- i za każdym razem po wejściu do przerwań sprawdzam, czy wcześniej się nie uruchomiło. I wszystko jest ok.
Na symulatorze, podgląd ASM też bez zarzutów.
Myślałem, że może problem jest w płytce czy coś, ale nic nie znalazłem, napięcia wzorowe, włączony dodatkowo BOR, żeby jak coś skoczy to mi reset zrobił. Zmieniłem nawet zasilanie z przetwornicy na zwykły stabilizator. Nic nie jest obciążone, procesor się nie grzeje, problem powtarza się w 3szt. urządzeń, które mam. Nie ma żadnych zakłóceń dodatkowych, żadnych obciążeń na pinach, no dosłownie nic. Kondensatory po 100nF na zasilaniu przy samym procesorze. Wszędzie wszystko jest.
Nawet sprawdziłem dodatkowo czy SP nie schodzi jakoś niżej niż normalnie (0x45F-240 bajtów) i wszystko w najlepszym porządku, a nadpisuje mi i koniec.
memcpy (działa w TIMERze w sekcji gdzie przerwanie jest wyłączone jeszcze) użyte do kopiowania zmieniłem też na zwykłą pętlę i też nic.
Brak mi jakiekolwiek wyjaśnienia tej sytuacji. Wygląda jakby gdzieś na ślepo strzelał nie w tym miejscu pamięci co potrzeba raz na jakiś czas kiedy jedno przerwanie uruchomi się w drugim.
Dla formalności kod przerwań:
Jak widać przerwania są pozbawione wszystkiego, a ewentualne zmienne są zwykłe globalne i funkcje są jakieś prymitywne do włączania tylko diod.
Wyrzucenie tablicy przed przerwanie i wszystko działa.
Co o tym sądzicie?
Dodano po 12 [minuty]:
Jeszcze sprawdziłem opcje optymalizacji. Zarówno -Os jak i -O0 dają ten sam rezultat. Nawet -O0 nie powoduje, że TIMER nie uruchamia się drugi raz w czasie jednego przerwania.
Dodano po 2 [godziny] 3 [minuty]:
To jest nie możliwe. Próbowałem zrobić ten sam efekt z TIMER1 i TIMER2 zamiast TIMER1 i UART i z samymi TIMERami chodzi poprawnie ten sam kod, mimo, że drugi TIMER startował co 600 cykli i problemu nie było. A z UARTem jest. Sądzicie, że to możliwy problem z samymi procesorami? Jeśli ktoś jest zainteresowany sprawdzeniem dogłębnym tego do czego doszedłem to piszcie, podeślę wtedy jakiś kompletny kod do testowania. Nie wiem czy kogoś prócz mnie to interesuje.
Mam dwa przerwania TIMER i UART. Timer uruchamia się co ~8000 cykli na 1000 cykli. UART uruchamia się maksymalnie co 2000 cykli na zaledwie 100, bo tam w sumie wszystko usunąłem na próbę. UART niczego modyfikuje tylko jedną zmienną, ale to zwykła zmienna globalna (wszystko co obliczane usunąłem).
TIMER ma sei(), żeby UART uruchamiał się obowiązkowo zawsze, ale za względu na logikę, to uruchomi max 1 (no liczmy 2) razy w czasie przerwania TIMER, czyli nadal mieścimy się w okienku.
Dodałem pułapki sprawdzające stan SP i Heap na wszelki wypadek, ale to bez znaczenia, bo choć sprawdziłem czy działają i chyba jest z nimi ok, to nie wyłapują jakiegoś nadpisywania.
Kod: C / C++
Przejrzałem wszystko co tylko się da, pomiędzy dolną pamięcią na zmienne i heap jest jeszcze kilkaset bajtów wolnej przestrzeni do górnej granicy zmiennych lokalnych SP. Z malloca nie korzystam poza w/w kodem.
W TIMERze mam jedną lokalną tablicę 160 elementów. I jak ona jest w timerze to nadpisuje mi pamięć globalną raz na ileś sekund w czasie odbierania danych przez UART (uart nie modyfikuje nawet tego obszaru pamięci, który ulega uszkodzeniu, TIMER też nie modyfikuje tej pamięci globalnej). W TIMERze jest te 160 elementów utworzone i tam jest tylko kopiowana zawartość pamięci z globalnej takiej samej tablicy (to na przyszłość kodu, żeby UART modyfikował globalną, a TIMER zawsze dostawał tablicę niezmodyfikowaną, co tutaj nie ma znaczenia dla tego przykładu).
Jak tablicę lokalną 160 elementów wyrzucę przed przerwanie, to wszystko działa elegancko.
Dodałem jeszcze na wszelki wypadek licznik na początku i na końcu przerwań. Na początku jest ++ na końcu -- i za każdym razem po wejściu do przerwań sprawdzam, czy wcześniej się nie uruchomiło. I wszystko jest ok.
Na symulatorze, podgląd ASM też bez zarzutów.
Myślałem, że może problem jest w płytce czy coś, ale nic nie znalazłem, napięcia wzorowe, włączony dodatkowo BOR, żeby jak coś skoczy to mi reset zrobił. Zmieniłem nawet zasilanie z przetwornicy na zwykły stabilizator. Nic nie jest obciążone, procesor się nie grzeje, problem powtarza się w 3szt. urządzeń, które mam. Nie ma żadnych zakłóceń dodatkowych, żadnych obciążeń na pinach, no dosłownie nic. Kondensatory po 100nF na zasilaniu przy samym procesorze. Wszędzie wszystko jest.
Nawet sprawdziłem dodatkowo czy SP nie schodzi jakoś niżej niż normalnie (0x45F-240 bajtów) i wszystko w najlepszym porządku, a nadpisuje mi i koniec.
memcpy (działa w TIMERze w sekcji gdzie przerwanie jest wyłączone jeszcze) użyte do kopiowania zmieniłem też na zwykłą pętlę i też nic.
Brak mi jakiekolwiek wyjaśnienia tej sytuacji. Wygląda jakby gdzieś na ślepo strzelał nie w tym miejscu pamięci co potrzeba raz na jakiś czas kiedy jedno przerwanie uruchomi się w drugim.
Dla formalności kod przerwań:
Kod: C / C++
Jak widać przerwania są pozbawione wszystkiego, a ewentualne zmienne są zwykłe globalne i funkcje są jakieś prymitywne do włączania tylko diod.
Wyrzucenie tablicy przed przerwanie i wszystko działa.
Co o tym sądzicie?
Dodano po 12 [minuty]:
Jeszcze sprawdziłem opcje optymalizacji. Zarówno -Os jak i -O0 dają ten sam rezultat. Nawet -O0 nie powoduje, że TIMER nie uruchamia się drugi raz w czasie jednego przerwania.
Dodano po 2 [godziny] 3 [minuty]:
To jest nie możliwe. Próbowałem zrobić ten sam efekt z TIMER1 i TIMER2 zamiast TIMER1 i UART i z samymi TIMERami chodzi poprawnie ten sam kod, mimo, że drugi TIMER startował co 600 cykli i problemu nie było. A z UARTem jest. Sądzicie, że to możliwy problem z samymi procesorami? Jeśli ktoś jest zainteresowany sprawdzeniem dogłębnym tego do czego doszedłem to piszcie, podeślę wtedy jakiś kompletny kod do testowania. Nie wiem czy kogoś prócz mnie to interesuje.
