Forum: Mikrocontroller und Digitale Elektronik ATmega - Inhalt der Register nach externen RESET?


von AVRli (Gast)


Lesenswert?

Hallo,

ist das eigendlich eindeutig definiert das nach einem externen RESET 
oder nach dem Einschalten der Inhalt der Register IMMER 0x00 ist?

Ich möchte einen RESET aus dem Programm ausführen indem ich zu Adresse 
0x000000 springe. Vorher wollte ich im Register 16 einen Wert 
reinschreiben, wenn der dann beim initialisieren mit einem festgelegten 
Wert überein stimmt, soll eine bestimmte Aktion ausgeführt werden.

Kann man das so machen?

MfG AVRli...

von Andy (Gast)


Lesenswert?

Hallo AVRli!

Das springen zur Adresse 0x0000 löst an sich KEINEN Reset aus, sondern 
startet nur das Programm von Neuem. Registerinhalte sollten dabei 
unverändert bleiben (bis auf die Register, die durch den Startup-Code 
verändert werden).
Ein echter Reset per Software kann nur über den Watchdog-Timer erzeugt 
werden.
Dazu gibt es bei den meisten AVRs aber auch entsprchende Status-Bits, 
die abgefragt werden können und sagen, ob der Reset durch Watchdog, 
Reset-PIN, Power-On oder Brown-Out ausgelöst wurde. Dann, und nur dann, 
werden die Register hardwareseitig initialisiert.

Grüße,
Andy

von Hannes L. (hannes)


Lesenswert?

AVRli wrote:
> Hallo,
>
> ist das eigendlich eindeutig definiert das nach einem externen RESET
> oder nach dem Einschalten der Inhalt der Register IMMER 0x00 ist?

Nein, der Registerinhalt (r0..r31) ist Zufall. Übrigens, wie kommst Du 
auf $00? Eine "leere" (nicht initialisierte) Speicherzelle hat in vielen 
Technologien nicht den Inhalt $00, sondern den Inhalt $ff.

>
> Ich möchte einen RESET aus dem Programm ausführen indem ich zu Adresse
> 0x000000 springe.

Ein Sprung zu 0 sollte reichen... ;-)

> Vorher wollte ich im Register 16 einen Wert
> reinschreiben, wenn der dann beim initialisieren mit einem festgelegten
> Wert überein stimmt, soll eine bestimmte Aktion ausgeführt werden.
>
> Kann man das so machen?

Das wird Dir nichts bringen, ein Sprung nach Adresse 0 ist kein Reset.

Aaaaaber:

Du könntest Deinen "Merker" im I/O-Bereich ablegen. Denn der I/O-Bereich 
wird bei einem echten Reset per Hardware initialisiert, siehe im 
Datenblatt die "initial value"-Angaben bei den Registerbeschreibungen.
Wenn Du also einen sonst nicht genutzten Timer (ohne Interrupt) 
einschaltest, bevor Du Deinen Nullsprung machst, dann solltest Du das in 
der Init-Routine wiedererkennen.
Du könntest auch beim Init prüfen, ob der Analog-Comparator bereits 
deaktiviert ist und ihn danach zwecks Stromsparen deaktivieren.

Willst Du einen echten Hardware-Reset auslösen, dann solltest Du den 
Wachhund-Timer starten und in einer Endlos-Schleife auf dessen 
Anschlagen warten.

>
> MfG AVRli...

...

von Andy (Gast)


Lesenswert?

Nachtrag:

Schau mal in den Datenblättern nach dem Register MCUCSR (zumindest beim 
mega8)

Andy

von Falk B. (falk)


Lesenswert?

@ AVRli (Gast)

>ist das eigendlich eindeutig definiert das nach einem externen RESET
>oder nach dem Einschalten der Inhalt der Register IMMER 0x00 ist?

Nein. Die Register der CPU (r0..R31) sind undefiniert, nur die 
IO-Register sind defniert wie im Datenblatt.

>Ich möchte einen RESET aus dem Programm ausführen indem ich zu Adresse
>0x000000 springe. Vorher wollte ich im Register 16 einen Wert

Das ist aber ein Software Reset. Da bleiben alle Register erhalten.

>reinschreiben, wenn der dann beim initialisieren mit einem festgelegten
>Wert überein stimmt, soll eine bestimmte Aktion ausgeführt werden.

Das ist schlecht, denn der Wert kann zufällig auch nach einem echten 
Reset drinstehen. Besser im MCUCR die entsprechenden Bits prüfen. Dort 
sind Power Up, etc. genau dekodiert.

MFG
Falk

von AVRli (Gast)


Lesenswert?

Danke für Eure Antworten,

hmm ich will eigendlich gezielt in den BOOT Bereich springen, da dieser 
bei jedem Start ausgeführt wird und das Programm nur im Bootloader 
stehen bleibt wenn der Programmemory einen Fehler hat, oder eine I/O Pin 
auf L ist.

Wie mache ich das nun das ich vom Programmemory in den BOOT Bereich 
springe?

Danke im voraus, der AVRli...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Den Reset-Vektor per Fuse auf den Bootloader im oberen Flash legen. Per 
Reset wird dann immer zuerst in den Bootloader gesprungen. Dieser 
springt dann nach 0x00 in die Applikation, wenn alles okay ist. Von der 
Applikation mußt Du dann einfach einen Reset auslösen (Watchdog 
überlaufen lassen) und der Bootloader wird wieder aktiv. Hängt sich die 
Applikation auf, hast Du denselben Effekt, der Watchdog löst einen Reset 
aus. Läuft die Applikaton durch, weil ein Stackoverflow oder ähnliches 
eintritt, wird auch der Bootloader erreicht.

von Wolfram Q. (quehl)


Lesenswert?

kann er dann nicht auch mit einem JMP an den Anfang des 
Bootloaderbereichs springen?

Mal einen Hinweis: Ich hatte es schon mal gehabt, daß bei RESET (Taste 
drücken) etwas anderes ablief als beim Entfernen und wiederanschließen 
der Stromversorgung. RESET und PowerOnReset ist daher nicht das Gleiche. 
Beim Reset werden offenbar die Register nicht gelöscht.

mfg

von Nailpainter (Gast)


Lesenswert?

Es gibt ein Reset Register das besagt welche Sorte von Reset geschah. 
Das kann man auswerten oder auch nicht.

von AVRli (Gast)


Lesenswert?

Was Travel Rec. beschrieben hat ist genau das was gerade abläuft, 
Problem ist das er nicht im BOOT hängen bleibt solange der Programemory 
ok ist.

Ich wollte nun bevor ich in den BOOT hüpfe mir irgendwie erkennlich 
machen das er egal was bei der Progeramemory Überprüfung raus kommt er 
immer im BOOT bleibt.

Hmm... ich will mir das externe Taste drücken eigendlich sparen...

Gruß AVRli...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.