zewnętrzne, usypianie i bud

W dniu 2013-02-22 00:26, Michoo pisze:

No cóż... Mi chodziło o sytuację odwrotną - UNIKNIĘCIE resetowania zewnętrznego urządzenia (moduł) GSM i napisanie kodu w taki sposób, żeby ATmega po ewentualnym restarcie sama zorientowała się gdzie stoi.

Załóżmy, że sam uC (ale nie modem) wiesza się w trakcie aktywnej rozmowy telefonicznej. Watchdog go restartuje, ale moduł GSM działa dalej (co najwyżej chwilowo tracąc komunikację z Atmegą).

Procedura inicjacji modułu jest tak napisana, żeby radzić sobie z sytuacją, kiedy natknie się na już zainicjowany moduł - wtedy zostawia go w spokoju spokoju.

W pętli znajduje się instrukcja sprawdzająca podniesienie słuchawki. Jeśli słuchawka zostanie podniesiona (lub program po włączeniu natknie się na podniesioną słuchawkę) wykonuje się seria instrukcji (m.in. wybudzenie modułu). Potem odwołuję się do funkcji, która wysyła "AT+CPAS\r\n" na potem czeka na ciąg +:CPAS: 00". Gdy ciąg się pojawi funkcja oczekuje jeszcze na ostatnią cyferkę i zwraca wartość odpowiadającą znakowi ASCII.

Dalej jest instrukcja switch(), która w zależności od zwróconej wartości podejmuje odpowiednie działanie:

- Jeśli moduł zgłosił gotowość - uruchomienie procedury wybierania numeru.

- Jeśli moduł zgłosił połączenie przychodzące - odebranie odebranie go i uruchomienie procedury obsługującej rozmowę

- Jeśli moduł zgłosił już aktywne połączenie (poprzednia sesja, przerwana przez reset) - uruchomienie procedury obsługującej połączenie.

Reply to
Atlantis
Loading thread data ...

Ale czemu atmega miała się zresetować?

Oznacza to: a) błąd w programie. należy go wyeliminować b) błąd w module albo zakłócenie w komunikacji. stan systemu jest prawdopodobnie niespójny. Twardy reset jest w takiej sytuacji najbezpieczniejszym wyjściem.

Ja bym w takim wypadku zrobił sprawdził na ile stan wygląda "dobrze" i w rzie czego zrobił power-cycle. Skoro był reboot to znaczy, ze coś się poważnie spieprzyło. Nic ci nie gwarantuje, że moduł będzie po czymś takim pracował poprawnie. (Któreś telefony tak miały, że po padzie komunikacji robiły soft reset podsystemu GSM, w efekcie wszystko wyglądało ok (zasięg, sieć, etc), tylko moduł nie sygnalizował przychodzących połączeń.)

foo: Czekasz na

+:CPAS: 00 a dostajesz +:CPAS: 01 (albo jeszcze lepiej 05, bo wybudzenie się nie powiodło) watchdag robi reset, goto foo.

A jeżeli zgłosił 1,2,5?

Reply to
Michoo

W dniu 2013-02-22 21:00, Michoo pisze:

W powodu watchdoga? Może inaczej. Czy przypadkiem mikrokontrolerowi nie zdarza się czasem (choćby niezmiernie rzadko) zawiesić się, tak po prostu zaprzestać pracy? Jeśli tak, to chodzi mi właśnie o ochronę przed taką sytuacją.

Bo rozumiem, że czasem jakiś niuans w samym kodzie (np. pętla, która w określonych okolicznościach zacznie się wykonywać w nieskończoność) może spowodować zawias, ale to na razie pomijam.

Dla jasności: nigdy takiej sytuacji nie miałem. Nie zdarzyło mi się, żeby moduł albo uC się zawiesił. Wszystkie przypadki, kiedy coś działało nieprawidłowo okazywały się efektem jakiegoś drobnego błędu w programie.

A co do twardego resetu, to modem D15 nie ma nawet odpowiedniego pinu. Jedynym rozwiązaniem z tego co widzę jest odcięcie zasilania, a to mogę zrobić ręcznie.

Proces inicjacji modułu GSM oczywiście przeprowadza elementarną diagnostykę, nawet jeśli zastanie go w stanie włączonym. Jeśli coś jest nie tak, zgłasza kod błędu migając diodą. Trochę "diagnostyki" jest też po podniesieniu słuchawki - pytanie o status, sprawdzenie poziomu sygnału itp. Słowem raczej można się połapać, gdy coś nie działa.

Tak swoją drogą co zwraca "+CPAS: 001" gdy modem jest niedostępny albo "+CPAS: 005" gdy znajduje się w stanie uśpienia, skoro przecież jest niedostępny albo znajduje się w stanie uśpienia? ;) Tutaj chyba chodzi o jakieś bardzo specyficzne sytuacje? W funkcji sprawdzającej o stan modemu umieściłem po prostu licznik. Funkcja zwraca odpowiednią wartość, gdy program nie otrzyma odpowiedzi przed upływem 500 ms. Jeszcze tego nie zagospodarowałem, ale myślałem o zwykłym komunikacie błędu.

Jeszcze niezagospodarowane, ale to kwestia dodania kolejnego "case" wewnątrz instrukcji switch(). Jak już mówiłem funkcja odpowiedzialna za obsługę CPAS czeka po prostu aż przyjdzie stała część komunikatu (+CPAS:

00) a potem czeka na pojawienie się ostatniej cyferki, pobiera ją, konwertuje z ASCII na liczbę i zwraca programowi.
Reply to
Atlantis

To jest skutek równoważny z - "dlaczego watchdog zadziałał" - bo coś go nie zresetowało, ale dlaczego?

Po odliczeniu błędów zasilania - nie. [1] To by oznaczało, że nie można go bezpiecznie używać.

[1] W teorii możesz mieć przypadek w którym jakiś błąd jest zależny od czasu i temperatury, ale prawdopodobieństwo jest minimalne. W praktyce zdarza się czasami jakiś błąd w przerwaniach (na krzemie) i w określonym przypadku procesor się nie budzi, ale to będzie raczej tylko missed interrupt a nie zwis, w bardzo specyficznych warunkach (no i trafi do erraty). Może też oberwać cząstką wysokoenergetyczną, ale to raczej na orbicie.

Taka sytuacja byłaby nielogiczna - na co komu urządzenie, które się losowo zawiesza?

Załóżmy, że masz szansę na zadziałanie w cyklu 6σ - to by oznaczało, że procesor lecący na 20MHz zawiesza się średnio co 25 sekund...

Błędnie - to jest jedyne z czym się będziesz musiał mierzyć w typowych przypadkach.

Oczywiście. Weź tylko pod uwagę, że moduł to też jakiś uC z jakimś oprogramowaniem.

PMOS na zasilaniu.

W sprzęcie bateryjnym trochę z tym gorzej - dlatego robi się obwód resetu na długim przytrzymaniu włącznika.

A co robi jeżeli uC zwisł w trakcie komunikacji? (Wysłał pół polecenia, przyszło przerwanie, gdzieś nie było volatile i resetuje się w momencie gdzie moduł dostał jakieś śmieci?)

Jest to jedno z podejść "skontaktuj się z serwisem". Drugim jest "spróbujemy się zrestartować".

Moduł. Moduł składa się z:

- radia

- modemu

- uC, który nim steruje (czasami w jednym scalaku)

A spora część współczesnych SoC ma odrębne bloki funkcjonalne z niezależnym wejściem zegara i asynchroniczne moduły komunikacyjne po to, żeby cała reszta mogła spać.

No tak, ale właśnie w ten sposób - przez zostawienie nieobsłużonych przypadków - tworzy się zawieszające się urządzenia. Dobra praktyka - zawsze dajesz default a jak nie wiesz co tam wstawić to wstawiasz logowanie błędu + reset.

A co w momencie gdy przyjdzie zakłócenie i zamiast cyferki przyjdzie coś niezrozumiałego?

Reply to
Michoo

W dniu 2013-02-23 12:54, Michoo pisze:

Chodziło mi raczej o znacznie, znacznie rzadsze przypadki. Kiedy uC pracuje non stop. Założyłem, że w pewnym momencie może wystąpić jakaś "sprzętowa" przyczyna zawieszenia i w związku z tym stosowanie watchdoga ma sens.

Rozumiałem przez to "pomijam w tych rozważaniach" a nie "pomijam w całym projekcie udając, że zagadnienie nie istnieje". ;)

Sprzętowy włącznik też przecież można zainstalować. ;)

Z tego co wyczytałem w dokumentacji, to w D15 działa to trochę inaczej. Żeby wybudzić moduł ze stanu uśpienia trzeba wysłać jakikolwiek, krótki ciąg znaków i odczekać 30ms. Wysłana wiadomość przepada. Dopiero potem można nawiązać właściwą komunikację.

Nieobsłużony jest w tej chwili, bo jak na razie nie mam nawet wykonanych połączeń, które umożliwiłyby mi przeprowadzenie resetu modułu z poziomu mikrosterownika.

Przedstawione rozwiązanie było tymczasowym. Teraz wyciągam liczbę za pomocą sscanf(). Przy czym rzecz jasna przed zakłóceniem w komunikacji przez USART mnie to nie obroni. Jak będzie miało dojść do przekłamania, to do niego dojdzie. Jeśli zastosuję twoje rozwiązanie - całe urządzenie się wtedy zrestartuje. Jeśli zrobię to po mojemu - dioda zamiga informując mnie, że coś jest nie tak. Odłożę słuchawkę i spróbuję podnieść ją ponownie.

Jak widać każda filozofia ma swoje złe i dobre strony. ;)

Reply to
Atlantis

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.