| Author |
Message
|
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#1
26 Dec 2010 18:00 [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Witam,
mam sobie meżkę z bootloaderem usbasploader (polecam btw). W programie chciałbym umieścić funkcję powrotu do bootloadera. Robię to w ten sposób:
| Code: |
| void reset() { cli();wdt_enable(WDTO_15MS);while(1); } |
Słyszałem, że watchdog działa tak, jak fizyczne zwarcie linii RESET do masy. Jednak po wywołaniu reset() program wraca do swojego początku, zamiast w pełni resetować urządzenie. Co innego, jeśli zewrę reset – wtedy odpala się bootloader. Moim pytaniem jest, czy da się z poziomu programu zrobić pełniejszy reset? :D
Żeby nie trzeba było za dużo szukać, przeklejam maina bootloadera:
| Code: |
int __attribute__((noreturn)) main(void)
{
/* initialize */
wdt_disable(); /* main app may have enabled watchdog */
bootLoaderInit();
odDebugInit();
DBG1(0x00, 0, 0);
#ifndef NO_FLASH_WRITE
GICR = (1 << IVCE); /* enable change of interrupt vectors */
GICR = (1 << IVSEL); /* move interrupts to boot flash section */
#endif
if(bootLoaderCondition()){
uchar i = 0, j = 0;
initForUsbConnectivity();
do{
usbPoll();
#if BOOTLOADER_CAN_EXIT
if(requestBootLoaderExit){
if(--i == 0){
if(--j == 0)
break;
}
}
#endif
}while(bootLoaderCondition()); /* main event loop */
}
leaveBootloader();
} |
(bootLoaderCondition() to po prostu sprawdzenie zworki)
Wesołych Świąt :)
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#2
26 Dec 2010 18:56 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| krdln wrote: |
W programie chciałbym umieścić funkcję powrotu do bootloadera. Robię to w ten sposób:
| Code: |
| void reset() { cli();wdt_enable(WDTO_15MS);while(1); } |
Słyszałem, że watchdog działa tak, jak fizyczne zwarcie linii RESET do masy. Jednak po wywołaniu reset() program wraca do swojego początku, zamiast w pełni resetować urządzenie. Co innego, jeśli zewrę reset – wtedy odpala się bootloader. Moim pytaniem jest, czy da się z poziomu programu zrobić pełniejszy reset? :D |
Dobrze syłyszałeś, tak się własnie programowo w pełni i prawidłowo resetuje procka. Ja tylko i wyłącznie tak zawsze robię w jeśli działam ze swoim bootloaderem.
Jeśli ci coś działa nie tak to znaczy, że coś jeszcze gdzie indziej źle robisz. Poza tym można ustawiać najkrótszy czas zamiast 15ms. Ale to nie ma akrat wpływu na to czy taki sposób resetu zadziała czy nie.
No i nie jest to żaden sposób na powrót do bootloadera tylko jest to sposób na programowe pełne zresetowanie procesora, po którym rozpoczyna on program od miejsca określonego za pomocą fusebitów. Jeśli są odpowiednio ustawione (pamiętaj o tym) to rozpocznie się od bootloadera ;)
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#3
26 Dec 2010 20:45 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
No tak, błąd był gdzie indziej, przyjrzałem się dokładniej funkcji bootLoaderInit() i oto, co znalazłem:
| Code: |
if(!(MCUCSR & (1 << EXTRF))) /* If this was not an external reset, ignore */
leaveBootloader(); |
Nie mam niestety żadnego innego programatora, więc nie mogę zmodyfikować bootloadera, żeby zrobić tam np. jakąś flagę. Wobec tego, da się jakoś oszukać meżkę, że reset z watchdoga był resetem zewnętrznym? Próbowałem dodać
| Code: |
| MCUCSR |= (1<<EXTRF); |
ale nie działa.
|
|
| Back to top |
|
 |
Google

|
#
26 Dec 2010 20:45 |
|
|
|
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#4
26 Dec 2010 21:25 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Wcześniej myślałem że jakąś literówkę walnąłeś, ale widzę, że ty nadal coś o jakiejś
"meżce"
mówisz, człowieku co to jest?
A flagę to możesz sobie ustawiać, i tak po resecie będzie tak jak ma być czyli wyjdzie ci z tego bootloadera. Programator się kłania niestety.
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#5
26 Dec 2010 22:21 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| Quote: |
| człowieku co to jest? |
Atmega, w skrócie mega, g wymienia się na ż, więc zdrobnienie od mega brzmi meżka. Mi tam się podoba :P
| Quote: |
| A flagę to możesz sobie ustawiać, i tak po resecie będzie tak jak ma być czyli wyjdzie ci z tego bootloadera. Programator się kłania niestety. |
Wiem. Mówiąc o fladze miałem na myśli modyfikację bootloadera, myślałem, że wynika to z mojej wypowiedzi:
| Quote: |
| Nie mam niestety żadnego innego programatora, więc nie mogę zmodyfikować bootloadera, żeby zrobić tam np. jakąś flagę. |
Zrobiłeś offtopa i nie odpowiedziałeś w końcu na pytanie.
Wracając do tematu, mam taką funkcję reset
| Code: |
void reset() {
cli();
MCUCSR |= (1<<EXTRF);
wdt_enable(WDTO_15MS);
while(1);
} |
Z tego, co jest w datasheecie wynika, że w tym bicie 0 pojawia się przy załączeniu zasilania, lub gdy się je tam wpisze ręcznie. Więc skoro zapisuję tam jedynkę, to powinna przetrwać. A wygląda, jakby znikała. Ktoś pomoże?
(Nie wkleję całego kodu bootloadera, ponieważ to wiele plików i nie chcę syfić forum.)
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#6
26 Dec 2010 23:20 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Ok, teraz do mnie dotarło co to jest "meżka", przerażający dziwoląg językowy ale niech będzie ;) ważne, że już rozumiem i rzeczywiście nawet śmieszne ;)
Za to co do takie słowa jak "syfić" to już mógłbyś sobie darować.
Żadnego oftopa nie zrobiłem tylko przypomniałem, że bez programatora się nie obejdzie.
A jeśli chodzi o twoje próby ustawiania tego bitu i to co wynika z dokumentacji to:
| Quote: |
Bit 1 – EXTRF: External Reset Flag
This bit is set if an External Reset occurs. The bit is reset by a Power-on Reset, or by writing a
logic zero to the flag. |
ten bit może być ustawiony tylko przez zajście zewnętrznego resetu, a programista ma możliwość co najwyżej zresetowania tej flagi przez wpisanie zera. Jak zatem chciałeś "oszukać" procka? (gdzie tam masz napisane, że można programowo ustawiać ten bit?)
|
|
| Back to top |
|
 |
gdL Poziom 20

Joined: 13 Aug 2004 Posts: 808 Location: Zgierz
|
#7
26 Dec 2010 23:28 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
A nie możesz zrobić zewnętrznego resetu operując pinami procesora, dołączonym tranzystorem ?
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#8
26 Dec 2010 23:37 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
@gdl
Myślałem o tym. Powala prostotą :) Co prawda zrabialne, ale mam już płytkę gotową, poza tym mam chyba tylko 1 pin wolny, i to gdzieś daleko.
Swoją drogą, po co tranzystor? Nie zadziałało by, gdyby pin podpiąć do resetu przez jakiś mały opornik?
@mirekk36
jakoś, hmm, nie wiem dlaczego, wydawało mi się oczywiste, że skoro da się wpisać zero, to jedynkę też. ale skoro jest tak jak mówisz, to szkoda. dzięki za uświadomienie mnie :)
Gdybym miał dostęp do programatora i chciał zrobić to jakąś flagą, to myślicie, że ostatni bajt ramu jest na to dobrym miejscem?
|
|
| Back to top |
|
 |
Google

|
#
26 Dec 2010 23:37 |
|
|
|
|
|
| Back to top |
|
 |
gdL Poziom 20

Joined: 13 Aug 2004 Posts: 808 Location: Zgierz
|
#9
26 Dec 2010 23:52 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Wydaje mi się, że powinno zadziałać bez. Ale można to zrobić dowolnie. Nie wiem jakie są stałe czasowe resetu i jak wygląda Twoja aplikacja. Widziałem już różne. Tranzystor może przyspieszyć resetowanie, jeśli masz kondensator między reset i gnd.
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#10
27 Dec 2010 00:10 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| krdln wrote: |
Gdybym miał dostęp do programatora i chciał zrobić to jakąś flagą, to myślicie, że ostatni bajt ramu jest na to dobrym miejscem? |
Taka próba przekazywania pewnych "wiadomości" pomiędzy resetami, nie jest dobrą praktyką programowania. Wręcz złą ;)
Po pierwsze producent nie gwarantuje, że pamięć RAM nie zostanie w postaci nienaruszonej.
Po drugie ostatnia komórka (jak już się na coś takiego porywać, to najgorszy pomysł bo tam od razu jak coś to zacznie odkładać się coś na stos. Z kolei na początku pamięci będą umieszczane wszystkie zmienne globalne i statyczne. Więc też nie dobrze. Można by było próbować coś w środku, albo skorzystać z którejś z opcji INIT aby tam wstawić własny kod próbujący odczytać taką "sztuczną" flagę.
Prędzej do tego celu przydać by się mogła jakaś komórka w pamięci EEPROM, no ale przy zbyt wielu resetach wiadomo, że taka komórka prędzej czy później to jednak się zapesuje ;)
Próbuj już lepiej coś z tym zewnętrznym resetem poprzez jakiś pin.
No a poza tym to rozumiem, że ten cały problem to chyba tylko przejściowy na krótko, bo zapewne programator gdzieś tam masz - tylko teraz brak do niego dostępu ;)
|
|
| Back to top |
|
 |
Google

|
#
27 Dec 2010 00:10 |
|
|
|
|
|
| Back to top |
|
 |
Fredy Poziom 18

Joined: 05 Oct 2003 Posts: 513
|
#11
27 Dec 2010 00:33 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
A nie można zrobić skoku w asemblerze w miejsce gdzie zaczyna sie bootloader?
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#12
27 Dec 2010 02:17 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
@Fredy
z tego, co mi się wydaje, to skok do pozycji 0 spowoduje przejście do początku programu, nie bootloadera. Chyba, że jakiś „ujemną” tam wstawić [edit: dokładnie to 0x1000 − rozmiar_bootloadera_w_wordach (czyli 0xC00 w tym wypadku)]:D Ale i tak to nie pełny reset.
@mirekk36
No tak, coś słyszałem, że tu stos jest od góry :] Ale zawsze można go przesunąć zostawiając jeden bajt wolny i by było idealnie. Co do zachowania stanu ramu, to niby producent nie gwarantuje, ale mi wystarczy skuteczność np. 60%, żeby za którymś razem poszło.
Możesz przybliżyć co to jest ta "opcja INIT"? Nie mogę za bardzo znaleźć o co chodzi.
|
|
| Back to top |
|
 |
Fredy Poziom 18

Joined: 05 Oct 2003 Posts: 513
|
#13
27 Dec 2010 10:06 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Ja nic nie mówiłem aby skoczyć na pozycję 0 , wręcz przeciwnie , trzeba zrobić jumpa tam gdzie znajduje się początek programu Bootloadera.
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#14
27 Dec 2010 11:44 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| Fredy wrote: |
| Ja nic nie mówiłem aby skoczyć na pozycję 0 , wręcz przeciwnie , trzeba zrobić jumpa tam gdzie znajduje się początek programu Bootloadera. |
Dokładnie jak pisze Fredy, skok do obszaru bootloadera w twoim szczególnym przypadku, chociaż nie jest to pełny reset może być nawet lepszą alternatywą niż kombinacje z zewnętrznym resetem a szczególnie niż kombinacje z zapisem flagi do ram.
Odnośnie sekcji INIT to musisz zaczytać maunala AVR GCC, takich sekcji jest kilka i są wykorzystywane przez kompilator to wstępnej inicjalizacji procka, do niektórych można samemu napisać własny fragment obsługi. Ale jak mówię to przekazywanie poprzez RAM a jeszcze do tego przesuwanie stosu to niezbyt ciekawe rozwiązanie.
Zdecydowanie lepsze będzie skok do obszeru bootloadera bezpośrednio.
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#15
27 Dec 2010 14:39 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Oj, wybaczcie. Mój błąd. Nie wiem skąd to zero wziąłem. Chyba coś z innym tematem mi się pomieszało.
A co do skoku do bootloadera, to po nim stos chyba nie jest czyszczony i po kilku cyklach programowania może mi się pamięć wysypać, dobrze myślę? Więc to też nie jest super rozwiązanie...
A jeśli chodzi o zmienne globalne i statyczne to mam takie poboczne pytanie, czy one są wrzucane do pamięci w takiej kolejności, w jakiej są w kodzie źródłowym? Pamiętam, że jak robiłem testy w c na kompie to właśnie tak było.
|
|
| Back to top |
|
 |
Google

|
#
27 Dec 2010 14:39 |
|
|
|
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#16
27 Dec 2010 14:42 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| krdln wrote: |
A co do skoku do bootloadera, to po nim stos chyba nie jest czyszczony i po kilku cyklach programowania może mi się pamięć wysypać, dobrze myślę? Więc to też nie jest super rozwiązanie... |
Źle myślisz, skok do bootloadera spowoduje ponowne ustawienie stosu we właściwe miejsce, więc akurat o to nie musisz się w ogóle martwić ;)
| krdln wrote: |
A jeśli chodzi o zmienne globalne i statyczne to mam takie poboczne pytanie, czy one są wrzucane do pamięci w takiej kolejności, w jakiej są w kodzie źródłowym? |
Mogą ale nie muszą i tego należy się trzymać ;)
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#17
27 Dec 2010 15:04 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
A, czyli bootloader ma na samym początku jakiś kod „przygotowujący”, czyli ta sekcja INIT pewnie, tak?
To jeszcze mam pytanie, co się dzieje z rejestrami IO po takim skoku domyślnie, bez kombinowania z initem? Są zerowane, jak przy resecie, czy trzeba ręcznie poczyścić przed tym skokiem?
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#18
27 Dec 2010 16:10 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Pisząc o sekcjach INIT miałem na myśli to co standardowo robi kompilator języka C a nie bootloader. A skoro bootloader pisany był w C to musi zawierać takie sekcje ;)
No właśnie rejestry nie będą wyzerowane, ale ponieważ w twoim konkretnym przypadku chodzi TYLKO o bootloader to nie ma to takiego znaczenia i nic samemu nie musisz czyścić ;) ... bootloader gdy skończy swoje działanie to później już dokona prawidłowego RESET'u procka.
|
|
| Back to top |
|
 |
Freddie Chopin Poziom 25

Joined: 12 Dec 2005 Posts: 7300 Location: Zawiercie
|
#19
27 Dec 2010 16:18 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| mirekk36 wrote: |
| Pisząc o sekcjach INIT miałem na myśli to co standardowo robi kompilator języka C a nie bootloader. A skoro bootloader pisany był w C to musi zawierać takie sekcje ;) |
To nie jest żaden standard C, tylko sposób działania avr-libc i avr-gcc.
| Quote: |
| No właśnie rejestry nie będą wyzerowane, ale ponieważ w twoim konkretnym przypadku chodzi TYLKO o bootloader to nie ma to takiego znaczenia i nic samemu nie musisz czyścić ;) ... bootloader gdy skończy swoje działanie to później już dokona prawidłowego RESET'u procka. |
Wyzerowanie rejestrów MA znaczenie, choćby dlatego, że mogą być włączone przerwania, może trwać zapis do EEPROMu, mogą się dziać różne inne dziwne rzeczy. Zaś po skończeniu swojego działania bootloader nie wykona przecież żadnego resetu tylko zwyczajnie skoczy do programu...
4\/3!!
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8708 Location: Szczecin
|
#20
27 Dec 2010 16:35 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| Freddie Chopin wrote: |
| mirekk36 wrote: |
| Pisząc o sekcjach INIT miałem na myśli to co standardowo robi kompilator języka C a nie bootloader. A skoro bootloader pisany był w C to musi zawierać takie sekcje ;) |
To nie jest żaden standard C, tylko sposób działania avr-libc i avr-gcc. |
No to już tylko takie czepianie się słowek, i nie ma to akurat tutaj wielkiego znaczenia, ale oczywiście tak, zgadza się to jest sposób działania avr-gcc ;)
| Freddie Chopin wrote: |
| Quote: |
| No właśnie rejestry nie będą wyzerowane, ale ponieważ w twoim konkretnym przypadku chodzi TYLKO o bootloader to nie ma to takiego znaczenia i nic samemu nie musisz czyścić ;) ... bootloader gdy skończy swoje działanie to później już dokona prawidłowego RESET'u procka. |
Wyzerowanie rejestrów MA znaczenie, choćby dlatego, że mogą być włączone przerwania, może trwać zapis do EEPROMu, mogą się dziać różne inne dziwne rzeczy. Zaś po skończeniu swojego działania bootloader nie wykona przecież żadnego resetu tylko zwyczajnie skoczy do programu...
|
A co do tego to jednak racja, zapomniałem, że ten bootloader wykorzystuje przerwania, zatem zostaną odblokowane jego własne ale także przypadkowo inne to może być niedobrze ;)
Ale nie ma sytuacji bez wyjścia bo można poza zatrzymaniem globalnych przerwań wyłączyć też zezwolenia na wszystkie, które się samemu wcześniej uruchamiało i już.
Wiadomo przecież, że to nie jest elegancki sposób i w zasadzie sam go odradzam od początku, ale przeczytaj sobie Freddie ten temat właśnie od początku - to zrozumiesz dlaczego o takim rozwiązaniu w ogóle mówię ;)
|
|
| Back to top |
|
 |
krdln Poziom 11

Joined: 14 Jul 2009 Posts: 60 Location: Lidzbark Warmiński / Warszawa
|
#21
27 Dec 2010 18:13 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
| mirekk36 wrote: |
| Pisząc o sekcjach INIT miałem na myśli to co standardowo robi kompilator języka C a nie bootloader |
Jak to nie bootloader? :D Skoro kompilator wrzuca to do kodu maszynowego bootloadera, to potem wykonuje to booloader. No ale racja, nie czepiajmy się :P
| mirekk36 wrote: |
| bootloader gdy skończy swoje działanie to później już dokona prawidłowego RESET'u procka. |
Ja bym tego nie nazwał prawidłowym resetem. To wygląda bardziej na ręczne sprzątanie po sobie i bootloader sprząta tylko to, czego używał, czyli jeden port i przerwania. Więc jeśli program nie posprząta, to bootloader za niego tego nie zrobi :]
Istnieje może jakaś wygodna instrukcja/makro/funkcja, do czyszczenia wszystkich rejestrów IO? Może da się to zrobić forką? :D
Poza tym, apostrof po RESET jest niepotrzebny, chyba nawet błędny. Jeśli da radę przeczytać i wygląda normalnie – bez niego jest ok. Apostrofu używamy, gdy odmieniane słowo się kończy na samogłoskę, której nie wymawiamy. Dygresja taka :P
|
|
| Back to top |
|
 |
Fredy Poziom 18

Joined: 05 Oct 2003 Posts: 513
|
#22
27 Dec 2010 18:43 Re: [atmega8][c] Reset z programu do bootloadera? |
|
|
|
Zatem najbezpieczniej byłoby przywrócić wszystkie tknięte rejestry do wartości defaultowych a potem można będzie już jumpa wykonać bezpiecznie.
Chociaż stosu nie trzeba ruszać bo zostanie skorygowany, porty też będą ustawione od nowa.
|
|
| Back to top |
|
 |