Guten Tag
Ich habe ein komisches Verhalten nach einem Watchdog Reset im
Boodloader. Nach dem Reset bleibt der Controller vermutlich in einer
Reset-Schlaufe. Die LEDs blinken mit etwa 12Hz. Das KO-Bild im Anhang
zeigt auf Kanal 1 PB1 und auf Kanal 2 PB2. Ein Reset über den Reset-Pin
bringt keine Abhilfe. Nur nach dem trennen der Stromversorgung verhält
sich der Controller wieder normal.
Das Schema vom Aufbau des Controllers (ATmega88) ist angehängt. Der Code
wurde im Atmel Studio 7.0.1417 geschrieben und kompiliert. Die Fuses
sind auf Extended 0xF9, High 0xDE, Low 0xE2 gesetzt.
Als erstes programmiere ich den Controller mit der Bootloader.hex über
den ISP. Das Programm für den Bootloader stammt ursprünglich vom Artikel
AVR Bootloader in C - eine einfache Anleitung und wurde von mir
angepasst.
Anschliessend lade ich mit PuTTY die Programm.hex Datei auf den
Controller. Geplant ist, dass nach erfolgreichem Upload ein Reset
erfolgt und der Controller direkt in das Hauptprogramm springt (aus
diesem Grund wurde die Extended.Bootrst Fuse nicht gesetzt). Der
Controller zeigt aber das oben beschriebene Verhalten.
Nach dem Neuanklemmen der Versorgungsspannung wird, wie gewünscht, das
Programm ausgeführt d.h. die grüne LED blinkt mit 1Hz, die rote LED
leuchtet konstant. Durch eine Eingabe in PuTTY von einem 'p', springt
der Controller wie gewünscht in den Bootloader.
Hat jemand eine Idee was ich falsch mache?
Vielen Dank
Bei einem Reset wird bei AVRs (alle?) NICHT der Watchdog abgeschaltet.
Das ist dann eine Aufgabe für den Bootloader.
Der Prescaler des Watchdog wird bein Reset auf den kleinsten Wert
gesetzt.
Am Anfang vom Hauptprogramm wird er zur Sicherheit deaktiviert
1
wdt_disable();
Für die Funktionen nutze ich
1
#include<avr/wdt.h>
Ich benötige den Watchdog im ganzen Programm nicht. Ich möchte nur einen
sauberen Reset nachdem der Bootloader seine Arbeit verrichtet hat.
Deshalb der Einsatz des Watchdog.
Christian R. schrieb:> Ich benötige den Watchdog im ganzen Programm nicht. Ich möchte nur einen> sauberen Reset nachdem der Bootloader seine Arbeit verrichtet hat.> Deshalb der Einsatz des Watchdog.
Ja. Schwachsinn. Schreibe statt dessen den Bootloader so, dass er alle
benutzte Hardware ordentlich in den Urzustand bringt und du kannst diese
Watchdog-Scheisse komplett knicken. Du brauchst sie dann einfach nicht.
Der Watchdog gehört der Anwendung. Nur im Kontext einer Anwendung macht
er (wenigstens ein wenig) Sinn.
Ich selber hab' ihn noch nie benötigt, jedenfalls nicht in der
eigentlichen Funktion als Watchdog. Als Timer benutze ich ihn hingegen
gelegentlich schon.
Ich gebe aber zu, dass es Anwendungen (nicht aber Bootloader!) geben
kann, bei denen der Watchdog als solcher sinnvoll eingesetzt werden
könnte. Sind aber sehr, sehr rar.
Falls dein Bootloader etwas länger braucht (z.B. auf Daten von UART
wartet), musst du den Watchdog beim Starten des Bootloaders bereits
abschalten - im Hauptprogramm ist es zu spät, da kommt er gar nicht mehr
hin.
@c-hater: Ursprünglich bin ich nach dem Bootloader wieder zur Adresse
0x0000 gesprungen:
1
void(*start)(void)=0x0000;
Und dann den Aufruf
1
start();
Da hat allerdings das Programm nicht mehr ganz korrekt funktionert. Ich
kam nicht dahinter, was ich nicht richtig zurückgesetz hatte. Dashalb
die Idee für einen "sauberen Reset".
Der Bootloader ist noch so, wie ich ihn im Endsystem nutze. Soviel zum
Zurücksetzen gibt's ja nicht. Es wird ja nur die UART gebraucht und die
inizialisiere ich ja beim Programmstart wieder. Das und auch der Rest
wird ja beim Sprung an den Start neu inizialisiert. Oder übersehe ich da
etwas?
@foobar: Beim Neustart/Reset springe ich nicht in den Bootloader sondern
direkt in das Hauptprogramm. Der Bootloader kann nur über das
Hauptprogramm angesprungen werden (oder bei der ersten programmierung,
da ja sonst noch nichts auf dem Controller ist).
Christian R. schrieb:> @c-hater: Ursprünglich bin ich nach dem Bootloader wieder zur Adresse> 0x0000 gesprungen:
1
void(*start)(void)=0x0000;
> Und dann den Aufruf>
1
start();
Schon fast OK. Da fehlt nur noch die Korrektur des Stackpointers.
> Ich> kam nicht dahinter, was ich nicht richtig zurückgesetz hatte.
Dann musst du halt dein Werk weiter Analysieren. Was denn sonst?
> Soviel zum> Zurücksetzen gibt's ja nicht. Es wird ja nur die UART gebraucht
Du bist definitiv ein C&P-Idiot, wenn du nichtmal geschnallt hast, dass
du auch die Interrupvektortabelle umschaltest...
Im Übrigen ist auch das "Zurückschalten" der UART nicht ganz trivial.
Aber für beides gilt: alles, was man dazu wissen muss, steht in den DBs.
Man muss sie einfach nur lesen und verstehen...
Ja, für C&Pler mag das eine neue Erfahrung sein, aber es ist ein
nützliche...
@c-hater: Vielen Dank für deine Beleidigung. Da freut man sich immer
besonders. Es gibt halt Leute, die können nicht alles so gut wie du und
es gibt bestimmt auch solche, die Sachen viel besser können.
Habe ich viel kopiert? Ja, gebe ich auch zu (im Anfangspost).
Habe ich alles verstanden? Nein. Das werde ich auch nie von einem Thema
behaupten.
Sind Foren dafür da, das einem andere Leute Tips geben könne? Ja, ich
denke schon.
Muss man sich in diesen Foren beleidigen? Nein, das bringt keinen
weiter.
Die Vektoren wurden mit
Falls jemand mal das gleiche Problem hat, hier die Lösung die bei mir
funktioniert hat.
Ich habe das mit dem Watchdog Reset im Bootloader aufgegeben. D.h. ich
springe wieder wie im Artikel [[AVR Bootloader in C - eine einfache
Anleitung]] beschrieben an Adresse 0x0000.
Das Problem bei mir war, dass ich im Hauptprogram sehrwohl die USART0
benutzt hatte, aber nicht zusammem mit Peter Fleury's Bibliothek. Das
hat dann in meinem Hauptprogramm zu Unstimmigkeiten geführt.
ACHTUNG: Die Änderung wurde für ein ATmega88 in Zusammenhang mit der
USART0 geschrieben. Für andere Prozessoren können die Register und Bits
andere Namen haben.
Das Ende vom Code des Artikels wurde von:
Christian R. schrieb:> @c-hater: Vielen Dank für deine Beleidigung.Christian R. schrieb:> Noch ein kleiner Nachtrag. Es reicht einfach die Interrupts von der> USART zu deaktivieren.
Nun, aus deinem Eröffnungspost kann man durchaus ablesen, daß du zu den
Leuten gehörst, die sich etwas vornehmen, was gemessen an ihrem
momentanen Wissens- und Könnens-Stand etwas zuviel ist.
Salopp gesagt: Beiße nie mehr ab, als du schlucken kannst, sonst
bleibt's dir im Halse stecken.
Nun scheint mir ein AVR nicht garzu kompliziert in seiner inneren
Architektur zu sein, weswegen das Zurücksetzen der HW auf einen Stand,
wie er exakt nach einem echten Reset vorliegt, wohl durchaus möglich
ist. Ob das für den USART gilt, ob die zugehörigen Pins tatsächlich
wieder im Ur-Zustand sind, wenn du mal bloß den Int sperrst, das
bezweifle ich.
Und nun meinst du, daß du als Allererstes dich an ein Diskussionsforum
wendest, weil all die anderen ja nur dazu da sind, dir zu helfen. OK,
das haben sie auch. Aber mit der Zeit wird da der eine oder andere
derart genervt, daß ihm der Kragen platzt.
Christian R. schrieb:> Als erstes programmiere ich den Controller mit der Bootloader.hex über> den ISP.
Ah ja. Und warum programmierst du deine Anwendung nicht gleich damit?
Dann hättest du all die Probleme mit dem Bootlader überhaupt nicht.
Ich schätze, du solltest über deine Software-Architektur in deinem µC
nochmal gründlich nachdenken.
W.S.
Das gepostete Programm und das Schema sind nur ein vereinfachter Teil
von einem grösseren Projekt. Ich habe versucht alles so zu beschreiben,
dass das Verhalten reproduzierbar ist. Dadurch scheinen gewisse Aspekte
vielleicht etwas komisch. Das ein Watchdog Reset nach dem Ende des
Bootlaoders wohl keine gute Idee ist, wusste ich nicht.
Ich bin mit dem gesammten Endresultat zufrieden und das Thema ist für
mich somit abgeschlossen.
Darf ich bitte noch eine Frage fragen?
Christian R. schrieb:> Anschliessend lade ich mit PuTTY die Programm.hex Datei auf den> Controller.
Machst du das von der Kommandozeile mit plink o.ä. oder aus dem
eigentlichen putty heraus? Letzteres kann zwar seriell, aber ich finde
nichts, wie man eine Datei senden könnte.
Zuerst stelle ich mit PuTTY eine Verbindung zu meinem Controller her.
Dann öffne ich die hex-Datei mit einem Editor (z.B. Notepad++), markiere
und kopiere alles. Anschliessen wähle ich das PuTTY-Fenster wieder an.
Mit einem klick mit der rechten Maustaste in das Fenster wird alles
eingefügt/auf den Controller übertragen.
Christian R. schrieb:> Mit einem klick mit der rechten Maustaste in das Fenster wird alles> eingefügt/auf den Controller übertragen.
Ja, okay... also eigentlich geht es nicht, aber die Natur findet immer
einen Weg ;)
Dankeschön!
Meine hex-Dateien haben so zwischen 2000 und 5000 Zeilen, deswegen hatte
ich auf etwas direkteres spekuliert. Putty ist so ein nettes Programm
und kann ziemlich viel, aber so eine Kleinigkeit darf es nicht können?
Danke, das ist nett. Irgendwie anders geht es natürlich, der
entscheidende Unterschied wäre, wenn es mit dem sowieso installierten
Putty ginge. Manche Leute dürfen nicht so einfach "irgendwelche
verseuchten" Programme installieren :(
Bauform B. schrieb:> Christian R. schrieb:>> Mit einem klick mit der rechten Maustaste in das Fenster wird alles>> eingefügt/auf den Controller übertragen.>> Ja, okay... also eigentlich geht es nicht, aber die Natur findet immer> einen Weg ;)> Dankeschön!>> Meine hex-Dateien haben so zwischen 2000 und 5000 Zeilen, deswegen hatte> ich auf etwas direkteres spekuliert. Putty ist so ein nettes Programm> und kann ziemlich viel, aber so eine Kleinigkeit darf es nicht können?
Ja, das habe ich auch schon ab und an vermisst.
Aber auch bie 10k Zeilen hilft noch immer Ctrl-A; Ctrl-C - und der
Rechtsklick ist auch nicht sooo schwer, aber irgendwie auch ein
Windows-Ding :D ;)
Wenn ich mal mit nem Bootloader arbeite, ist dieser (oder das HEX-File)
so "modifiziert", dass ein "cat file.hex > /dev/ttyS0" reicht (oder eine
beliebige andere Schnittstelle)
Lobenswert ist auf jedenfall zu erwähnen, dass Bootloader UND Programm
hier als C, sowie auch als HEX im ERSTEN Beitrag angehängt waren! :)
Was den Beitrag von W.S. angeht: Ich stimme ihm in den ersten paar
Zeilen zu,
W.S. schrieb:> Aber mit der Zeit wird da der eine oder andere> derart genervt, daß ihm der Kragen platzt.
Hier hörte es aber bei mir auf. - c-hater ist ja bekannt dafür, in
dieser Richtung ausfallend zu werden - und das halt auch nicht erst seit
gestern...
Von einem anderen, der ausfallend wurde oder dem der "Kragen geplatz"
sei, habe ich in diesem Thread nichts lesen können.
Falls sich noch jemand für die (mutmassliche) Lösung des ursprünglchen
Problems interessiert. Ich hätte auch vor dem Watchdog Reset die
Vektor-Tabelle wieder anpassen müssen. In dem Fall hier ist er nach dem
Reset nicht nach 0x0000 gesprungen (an den Anfang vom Hauptprogramm),
sondern nach 0x0C00. Also an den Anfang vom Bootloader. Am Anfang vom
Bootloader wurde der Watchdog nicht deaktivert, somit hat er immer
wieder zugeschlagen. Die Timeout-Zeit von 16ms (Die Timeout-Zeit wird
nach dem Reset zurückgesetzt) entspricht auch schön der Länge des
Low-Pegels auf Kanal 1 des Oszilloskop-Bildes. Die Zeit des High-Pegels
entspricht den 65ms Boot-Delay (gem. LOW.SUT_CKSEL Fuse).
Das erklärt auch, warum ein Reset mit Taster keine Abhilfe brachte, aber
ein ab- und anklemmen der Stromversorgung schon.