Forum: Mikrocontroller und Digitale Elektronik kontrollierter Softwarereset


von Tobias H. (Gast)


Lesenswert?

Hi

Ich würde gerne meinen Prozessor auf einen Tastendruck neustarten, damit 
die Werte aus dem EEPROM neu gelesen werden, Variablen wieder auf den 
Initialisierungswert am Anfang gesetzt werden usw.

Gelesen habe ich, dass das mit dem Watchdog geht - aber den wollte ich 
eigentlich nicht nehmen. Habe Angst, dass ich dann 
unkontrollierte/ungewollte Resets hinzubekomme.

asm volatile ("RJMP 0") tut auch nix.

Gibt es noch eine Möglichkeit ohne externe Beschaltung?

Ciao Tobias

von Altera (Gast)


Lesenswert?

Auf Tastendruck schaltest du den Watchdog ein, fertig. Warum sollte da 
was ungewollt kommen?

von Peter D. (peda)


Lesenswert?

Wer sagt denn, daß Du den EEPROM nur nach nem Reset lesen darfst und die 
Variablen nur nach einem Reset schreiben ???

Du darfst das alles immer und zu jeder Zeit machen.

Ein Reset mag ich nicht, da dann alle Port kurz auf hochohmig gehen.


Peter

von Tobias H. (Gast)


Lesenswert?

nein, lesen und schreiben darf ich immer. aber die komplette 
Initialisierung aufs neue würde ich mir sparen. Halt ein Knopfdruck, 
Neustart und alles ist wieder, als hätte ich gerade erst den Strom 
angeschlossen. Wie rücksetzen auf Werkszustand.

Auf Tastendruck erst den Watchdog einschalten, so einfach und doch 
effektiv, das hätte was. Habe die ganze Zeit gedacht, ich müsste den 
Watchdog einschalten, immer schön resetten und für einen gewollten Reset 
dann einfach mal den Reset des Watchdog "vergessen" - aber auf deine 
einfache Idee bin ich nicht gekommen! :-) Manchmal steht man einfach auf 
dem Schlauch...
Danke!

Ciao Tobias

von 42 (Gast)


Lesenswert?

Es soll Leute geben, die den Reset-Taster am Resetpin anschließen.

von Tobias H. (Gast)


Lesenswert?

>>Es soll Leute geben, die den Reset-Taster am Resetpin anschließen.
Zitat von mir:
>>>"Gibt es noch eine Möglichkeit ohne externe Beschaltung?"

Ich habe eine Art Tastatur und ein Display und man soll quasi einen 
Menüpunkt auswählen können, der den Neustar bewirkt.

von Dieter Werner (Gast)


Lesenswert?

Wie wäre es denn mit einem Jump zum Resetvektor ?

von Tobias H. (Gast)


Lesenswert?

1
#include <avr/wdt.h> //Watchdog
2
3
strcpy(ausgabetext,"Neustart?");
4
lcd_ausgabe(1,ausgabetext);
5
if (bit_is_clear(PINB,PB2))
6
{
7
loop_until_bit_is_set(PINB,PB2);
8
wdt_enable(WDTO_15MS);
9
while(1);      
10
}
tut bereits Wunderbar seinen Dienst.

strcpy(ausgabetext,"Neustart?"); ist aufgrund einer noch folgenden 
Funktion nötig.

>Wie wäre es denn mit einem Jump zum Resetvektor ?

asm volatile ("RJMP 0")
Tut leider rein gar nix... Aber ich kann kein Assembler, ist der denn 
überhaupt richtig?

Ciao Tobias

von Besenstil (Gast)


Lesenswert?

Ein RJMP 0, resetted die internen Register nicht. Weshalb sollte es? 
Zudem sollte die Schaltung so gebaut sein, dass die Pins tristate sein 
koennen, ohne das unkontrollierte oder schaedliche Zustaende eintreten. 
Dies, da es immer einen Zeitpunkt ohne Programm gibt. zB auch waehrend 
der Programmentwicklung.

B.

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

RJMP 0 sollte bei jedem guten Programm funktionieren ... (und C-Compiler 
sollten ja eigentlich guten code produzieren) Denn jedes Register sollte 
mit einem Wert geladen werden bevor es benutzt wird. Du kannst natürlich 
auch am start des controllers alle register auf 0 setzen (mit Pointer 
und SRAM zugriff)

von Stefan Salewski (Gast)


Lesenswert?

>auch am start des controllers alle register auf 0 setzen

Vorsicht: Nicht für alle Register ist der Wert nach einem Hardwarereset,
d.h. der Soll-Startwert, identisch mit dem Wert 0!

von Karl H. (kbuchegg)


Lesenswert?

Ein RJMP 0 wird da natürlich nicht gehen.
Das R steht ja für "Relativ". Die 0 bezeichnen
den Offset zur momentanen Position im Programm.
Ein RJMP 0 ist daher kein Sprung zur absoluten Adresse
0, sondern ein Sprung .... zur Anweisung nach dem
RJMP 0.

Wenn schon, dann muss das ein normaler JMP sein
und kein relativer.

von FBI (Gast)


Lesenswert?

Hi,

wobei WinAVR20060421 aus "RJMP 0" alles mögliche macht, nur keinen 
Sprung auf den nächsten Befehl :)
Bsp
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
ISR(TIMER0_COMP_vect)
6
{
7
}
8
9
10
ISR(TIMER0_OVF_vect)
11
{
12
}
13
14
15
int main(void)
16
{
17
  asm volatile ("RJMP 0"::);
18
  while(1);
19
}

wird zu
1
@00000047: __vector_19
2
---- rjmp_tst.c -----------------------------------------------------------------------------------
3
6:        {
4
+00000047:   921F        PUSH    R1               Push register on stack
5
+00000048:   920F        PUSH    R0               Push register on stack
6
+00000049:   B60F        IN      R0,0x3F          In from I/O location
7
+0000004A:   920F        PUSH    R0               Push register on stack
8
+0000004B:   2411        CLR     R1               Clear Register
9
+0000004C:   900F        POP     R0               Pop register from stack
10
+0000004D:   BE0F        OUT     0x3F,R0          Out to I/O location
11
+0000004E:   900F        POP     R0               Pop register from stack
12
+0000004F:   901F        POP     R1               Pop register from stack
13
+00000050:   9518        RETI                     Interrupt return
14
@00000051: __vector_9
15
11:       {
16
+00000051:   921F        PUSH    R1               Push register on stack
17
+00000052:   920F        PUSH    R0               Push register on stack
18
+00000053:   B60F        IN      R0,0x3F          In from I/O location
19
+00000054:   920F        PUSH    R0               Push register on stack
20
+00000055:   2411        CLR     R1               Clear Register
21
+00000056:   900F        POP     R0               Pop register from stack
22
+00000057:   BE0F        OUT     0x3F,R0          Out to I/O location
23
+00000058:   900F        POP     R0               Pop register from stack
24
+00000059:   901F        POP     R1               Pop register from stack
25
+0000005A:   9518        RETI                     Interrupt return
26
@0000005B: main
27
16:       {
28
+0000005B:   E5CF        LDI     R28,0x5F         Load immediate
29
+0000005C:   E0D4        LDI     R29,0x04         Load immediate
30
+0000005D:   BFDE        OUT     0x3E,R29         Out to I/O location
31
+0000005E:   BFCD        OUT     0x3D,R28         Out to I/O location
32
17:         asm volatile ("RJMP 0"::);
33
+0000005F:   CFE7        RJMP    PC-0x0018        Relative jump
34
18:         while(1);
35
+00000060:   CFFF        RJMP    PC-0x0000        Relative jump

Wie man sieht geht der Sprung zur Adresse von 'TIMER0_COMP_vect'!
Wenn ich die Interuptroutinen auskommentiere springt er übrigens auf den 
Anfang von main.

CU Frank

von FBI (Gast)


Lesenswert?

Hi,

nach einigen weiteren Tests ist klar was passiert. Bei "RJMP 0" springt 
er immer auf den ersten generierten Code der aktuellen 'Compilation 
Unit' (sprich dem C-File in dem der RJMP steht).
Kann man sicher ganz witzige Programme mit schreiben, ist aber wohl 
meist nicht das was will.

CU Frank


BTW: WinAVR20070122 scheints übrigens genauso zu machen

von Peter D. (peda)


Lesenswert?

FBI wrote:

> nach einigen weiteren Tests ist klar was passiert. Bei "RJMP 0" springt
> er immer auf den ersten generierten Code der aktuellen 'Compilation
> Unit' (sprich dem C-File in dem der RJMP steht).
> Kann man sicher ganz witzige Programme mit schreiben, ist aber wohl
> meist nicht das was will.


Ja, dieser Bug ist eigentlich schon lange bekannt.


Peter

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.