Forum: Mikrocontroller und Digitale Elektronik Programm beenden - aber wie?


von Paul (Gast)


Lesenswert?

Hallo Gemeinde
in meinen Projekt muss ich in Abhängigkeit den Ablauf unterbrechen bzw. 
beenden. Danach muss ein Neustart durch ein Reset erfolgen.
Sonst geht es ja so:
1
while(0)
2
  {
3
    Programm ...
4
    void ende;
5
  }
6
7
void ende()
8
  { 
9
    Unendliche Schleife oder Stop ???
10
  }
Arbeite mit c. Leider habe ich keine Idee dazu. Kann mir jemand weiter 
helfen?
LG Paul

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Paul schrieb:
> while(0)
>   {
>     Programm ...
>     void ende;
>   }
>
> void ende()
>   {
>     Unendliche Schleife oder Stop ???
>   }

Schreib doch einfach
1
main(void) {
2
// init kram
3
ResetFlag = FALSE;
4
5
6
  while (!ResetFlag)
7
    {
8
 // acker durch die Hauptschleife
9
    }
10
// ResetFlag war TRUE
11
// Reset z.B. durch  Ablaufen des Watchdog
12
 doMyHardwareReset();
13
} // End main

: Bearbeitet durch User
von Leo (Gast)


Lesenswert?

Hallo Paul,

ich nehme mal an, dein C-Programm ist für ein Embedded Programm.

Als erstes muss deine Hauptschleife, so ungefähr aussehen:
1
while (1)
2
{
3
   if (Bedingung)
4
   {
5
      Ende();
6
   }
7
8
   //sonstige Programm-Logik
9
   ...
10
}
11
12
void Ende (void)
13
{
14
   while (1)
15
   {
16
      //sonstiger Clean-Up Code bevor Reset
17
      ...
18
      
19
      mc_reset();
20
   }
21
}

Ich denke, das soll es gewesen sein...
Gruß Leo

von Karl M. (Gast)


Lesenswert?

Hallo Paul,

zB bei den Atmel AVR, kann man per Software einen Software Reset JMP 
0x0000 auslösen, einen WDT ablaufen lassen oder auch ein Pin mit dem 
#Reset Eingang verbinden und darüber Hardware Reset ausführen.

Dazu konfiguriet man das Pin als Ausgang und legt ihn auf 0 Pegel.

von Paul (Gast)


Lesenswert?

Hallo Leo
dein Vorschlag sieht einfach aus. Habe mal in mein C-Buch geschaut, 
leider reset nicht gefunden. Gibt es das in C (nicht C++)

Matthias S. schrieb:
> // ResetFlag war TRUE
> // Reset z.B. durch  Ablaufen des Watchdog
>  doMyHardwareReset();

Hallo Matthias
mit der letzten Zeile rufsts du doch ein Unterprogramm auf oder sehe ich 
das falsch?
Es reicht auch eine unendliche Schleife um zu stoppen.
LG Paul

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Paul schrieb:
> Es reicht auch eine unendliche Schleife um zu stoppen.

Ja, um zu stoppen, reicht das natürlich. Ich hatte deine ursprüngliche 
Frage so verstanden, das du dann einen Reset auslösen möchtest. Aber 
wenn das händisch passiert, reicht ein geordneter Rückzug und dann eine 
Endlosschleife.

von Leo (Gast)


Lesenswert?

Hallo Paul,

wie du nun dein Programm zum "Stoppen" bringst scheint nun geklärt.

Falls du auf deinem AVR doch einen Software-Reset durchführen möchtest, 
gibt es zwei Möglichkeiten. Karl M. hat das schon angedeutet

1.
Du kannst einen Inline-Assembler ausführen mit
JMP 0x0000

2.
Du kannst einen Watchdog aktivieren, welcher den Reset durchführt.
http://www.atmel.com/webdoc/avrlibcreferencemanual/FAQ_1faq_softreset.html

Die AVR Chips haben leider keine direkte Möglichkeit einen Reset anders 
durchzuführen.

Frohes Programmieren.
Gruß Leo

von Paul (Gast)


Lesenswert?

Hallo Leo

Leo schrieb:
> 1.
> Du kannst einen Inline-Assembler ausführen mit
> JMP 0x0000

Das habe ich noch nie gemacht und passe lieber dabei.

Leo schrieb:
> 2.
> Du kannst einen Watchdog aktivieren, welcher den Reset durchführt.
> http://www.atmel.com/webdoc/avrlibcreferencemanual/FAQ_1faq_softreset.html

Watchdog ist eine gute Idee. Habe allerdings noch keine Peilung wie ich 
das einfügen kann.
Bin immer noch an der Schleife. Hatte es schon mal in einem Programm 
drin zur Abfrage eines Slave. Slave vorhanden-Programm geht weiter, kein 
Slave Programm stopt. Find ich leider im Moment nicht
LG Paul

von Einer K. (Gast)


Lesenswert?

Aus meiner Sicht:
Es macht keinen Sinn ein µC Programm zu stoppen.
Es macht auch keinen Sinn einen Reset auszuführen.

(meistens)

OK, ein vom WDT ausgelöster Reset mag manchmal Sinn machen.
So wie die Notrutschen des Airbus 380. Die machen auch Sinn.
Aber sie zu einem oft genutzten Prinzip machen?
Voranden sollen sie sein. Bereit auch.
Aber wirklich aufblasen? Bitte nicht!

OK, eine vollständige Abschaltung, um Batterie Strom zu sparen...
Auch gut...

von Leo (Gast)


Lesenswert?

Hallo Paul,

falls du mit dem Thema Watchdog nicht weiter kommst...
Zwei gute Howtos von mikrocontroller.net

https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_Watchdog

https://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog

Im Prinzip genügen die 3x Funktionen

.wdt_enable(uint8_t timeout)
.wdt_disable()
.wdt_reset()

Gutes Gelingen!

Gruß Leo

von Nop (Gast)


Lesenswert?

Arduino F. schrieb:

> Es macht auch keinen Sinn einen Reset auszuführen.

Also neben dem Reset im Absturzfall (der idealerweise nicht vorkommen 
sollte) haben viele Geräte auch eine Funktion "auf Werkseinstellungen 
zurücksetzen", und sowas implementiere ich auch mit einem 
Watchdog-getriggerten Systemreset.

Allein schon aus Supportgründen ist das sinnvoll, weil man dann weiß, in 
welchem Zustand das Gerät danach wirklich ist, wenn man das dem Kunden 
beim Troubleshooting empfiehlt.

Zumal man da mit einer simplen Endlosschleife auch gleich noch testen 
kann, ob der Watchdog überhaupt korrekt implementiert ist.

von Noch einer (Gast)


Lesenswert?

Ist ein JMP 0x0000 das selbe wie ein Reset?

Bei einem echten Reset werden die IO Register wieder auf den initial 
value gesetzt (z.B. Timer abgeschaltet, Interrupt enable 
abgeschaltet...). auch bei einem JMP 0000 ?

von Norbert S. (norberts)


Lesenswert?

Moin,

Wenn ASM (für den Reset) nicht genehm ist:
In Bascom geht z.B. auch

Goto _reset

Aber Achtung, das ist kein echter Reset, wenn ich das richtig in 
Erinnerung habe.

Ansonsten ist der Watchdog sauberer für einen Neustart.

Um anzuhalten geht natürlich ne Endlosschleife aber wenn man Strom 
sparen will:
Alles abschalten (Watchdog, ADC, BOD und alles was sonst noch Strom 
verbraucht), Ints global deaktivieren und dann ab in den tiefsten 
Schlafmodus, den der Controller kennt.
Da kommt man dann aber auch nur mit Hardware- oder Power-On-Reset wieder 
raus.

Gruß,
Norbert

von Markus L. (rollerblade)


Lesenswert?

Paul schrieb:
> Habe mal in mein C-Buch geschaut,
> leider reset nicht gefunden. Gibt es das in C (nicht C++)
C ist eine Programmiersprache. Ein Programm soll laufen. Warum sollte 
eine Programmiersprache einen Sprachkonstrukt aufweisen, der sie selbst 
ad absurdum führt?

von Noch einer (Gast)


Lesenswert?

> Warum sollte eine Programmiersprache einen Sprachkonstrukt aufweisen,
> der sie selbst ad absurdum führt?

C hat doch so ein absurdes Sprachkonstrukt.
1
:~/tmp$ cat r.c
2
void main() {
3
 void (*reset)() = 0;
4
 reset();
5
}
6
:~/tmp$ cc r.c
7
:~/tmp$ ./a.out 
8
Speicherzugriffsfehler (Speicherabzug geschrieben)

von Nop (Gast)


Lesenswert?

Noch einer schrieb:
> Ist ein JMP 0x0000 das selbe wie ein Reset?

Nein, und zwar aus genau dem Grund, den Du nanntest.

von michael_ (Gast)


Lesenswert?

Quatsch!

Noch einer schrieb:
> Bei einem echten Reset werden die IO Register wieder auf den initial
> value gesetzt (z.B. Timer abgeschaltet, Interrupt enable
> abgeschaltet...). auch bei einem JMP 0000 ?

Die Register und Einstellungen, die gebraucht werden, werden gleich 
danach definiert. So wie sie gebraucht werden.
Die anderen werden nicht angefasst, so wie nach dem Ur-Reset.
Das bleibt auch so nach einem Soft-Reset.

von Nop (Gast)


Lesenswert?

michael_ schrieb:

> Die Register und Einstellungen, die gebraucht werden, werden gleich
> danach definiert. So wie sie gebraucht werden.

Hast Du noch nie eine Firmware mit dynamischer Taktung geschrieben? Da 
ändert sich die komplette Takteinstellung je nach Betriebszustand.

von Nop (Gast)


Lesenswert?

michael_ schrieb:

> Die Register und Einstellungen, die gebraucht werden, werden gleich
> danach definiert. So wie sie gebraucht werden.

Ach ja, und dann kann man ja auch eine Tastatur anschließen, wobei die 
Keys als Matrix verschaltet werden. Dann braucht man z.B. für 9 Tasten 
nur 6 IOs statt 9. Das geht aber nur, wenn Input/Output laufend 
umgeschaltet werden.

von michael_ (Gast)


Lesenswert?

Nop schrieb:
> Hast Du noch nie eine Firmware mit dynamischer Taktung geschrieben? Da
> ändert sich die komplette Takteinstellung je nach Betriebszustand.

Nee, hab ich nicht.
Aber Assembler.

Was im ersten Durchlauf nicht angefasst wurde, besteht auch nach 
Soft-Reset noch.
Und was initialisiert wird, wird dann auch wieder neu initialisiert.

Was verstehst du da nicht?

von Norbert S. (norberts)


Lesenswert?

michael_ schrieb:
> Die Register und Einstellungen, die gebraucht werden, werden gleich
> danach definiert. So wie sie gebraucht werden.
> Die anderen werden nicht angefasst, so wie nach dem Ur-Reset.
> Das bleibt auch so nach einem Soft-Reset.

Jein, kommt auf den Compiler an.
Beim Sprung an den Anfang macht der µC (AVR8) erstmal nix.
Dann kommt es darauf an, was der Compiler auf default setzt oder eben 
die Software.
Da sollte man schon ganz genau wissen was man tut.
Nach einem echten Reset (Hardware, Watchdog oder was auch immer) hat man 
die Register alle auf default, darauf kann man sich verlassen.

Gruß,
Norbert

von Nop (Gast)


Lesenswert?

michael_ schrieb:

> Nee, hab ich nicht.

Eben.

> Und was initialisiert wird, wird dann auch wieder neu initialisiert.

Nur wird die Initialisierung dann mit irgendeiner Taktung durchlaufen, 
je nachdem, aus welchem Zustand das Teil gerade bootet. Das ist allein 
schon zum seriösen Testen aufwendig, weil anders als bei fester Taktung 
"einfach mal jmp 0" nicht ausreicht.

Zudem schaltet ein "jmp 0" auch nicht die Interrupts ab, die dann 
während der Initialisierung folglich auch noch zuschlagen können. Das 
kann nette race conditions und nicht reproduzierbare Phänomen geben.

von Norbert S. (norberts)


Lesenswert?

Nop schrieb:
> Nur wird die Initialisierung dann mit irgendeiner Taktung durchlaufen,
> je nachdem, aus welchem Zustand das Teil gerade bootet. Das ist allein
> schon zum seriösen Testen aufwendig, weil anders als bei fester Taktung
> "einfach mal jmp 0" nicht ausreicht.

Das hat aber mit AVR-8Bittern nichts zu tun.
Da gibt es nur einen Takt.

Nee, grundsätzlich ist auch bei AVR8 der Sprung zu Null keine gute Idee.
Man hebelt alles aus, was einem normalerweise das Leben einfacher machen 
soll und handelt sich ev. unbekannte Probleme ein.
Been there, done that. (Mit einem Bootloader)

Gruß,
Norbert

von michael_ (Gast)


Lesenswert?

Norbert S. schrieb:
> Jein, kommt auf den Compiler an.

Compiler vielleicht, bei Assembler kennt man jedes Bit.

Norbert S. schrieb:
> Beim Sprung an den Anfang macht der µC (AVR8) erstmal nix.

Ach, ja?

Norbert S. schrieb:
> Dann kommt es darauf an, was der Compiler auf default setzt oder eben
> die Software.

Eben, er fasst nur das an, was er braucht. Der Rest bleibt wie er ist.

Nop schrieb:
> Zudem schaltet ein "jmp 0" auch nicht die Interrupts ab, die dann
> während der Initialisierung folglich auch noch zuschlagen können.

Nö, Interrupts sind das Erste, was bei der Initialisierung festgelegt 
wird.
Mindestens bei Assembler.

von Nop (Gast)


Lesenswert?

Norbert S. schrieb:

> Das hat aber mit AVR-8Bittern nichts zu tun.

Das Ausgangsposting aber auch nicht.

michael_ schrieb:
> Nö, Interrupts sind das Erste, was bei der Initialisierung festgelegt
> wird.

Zwischen "jmp 0" und dem ersten Interrupt-Disable vergeht Zeit, in der 
ein Interrupt reinschlagen kann. Falls beim Booten überhaupt Interrupts 
disabled werden und nicht einfach nur die Interrupts wie gewänscht 
nacheinander aufgesetzt werden.

von Norbert S. (norberts)


Lesenswert?

Moin,

Hoppla, es ist ja gar nicht klar, um welchen µC es geht.
Das wäre bei dem Sprung zu 0 schon entscheidend aber das ist bei AVR8 
schon eine so ausreichend blöde Idee, daß man das nicht empfehlen kann.

Können wir uns darauf einigen?

Gruß,
Norbert

von Harry L. (mysth)


Lesenswert?

michael_ schrieb:
> Norbert S. schrieb:
>> Jein, kommt auf den Compiler an.
>
> Compiler vielleicht, bei Assembler kennt man jedes Bit.
>
Glaubst du wirklich, daß alle C-Programmierer Volltrottel wären?
Die kennen die Hardware genausogut wie du (sind nur schneler fertig als 
du)

> Norbert S. schrieb:
>> Beim Sprung an den Anfang macht der µC (AVR8) erstmal nix.
>
> Ach, ja?
>
> Norbert S. schrieb:
>> Dann kommt es darauf an, was der Compiler auf default setzt oder eben
>> die Software.
>
> Eben, er fasst nur das an, was er braucht. Der Rest bleibt wie er ist.
>
Das ist deine Annahme, ist aber nirgendwo definiert, und als 
vorausschauender Programmierer wird man sich darauf sicher nicht 
velassen.

> Nop schrieb:
>> Zudem schaltet ein "jmp 0" auch nicht die Interrupts ab, die dann
>> während der Initialisierung folglich auch noch zuschlagen können.
>
> Nö, Interrupts sind das Erste, was bei der Initialisierung festgelegt
> wird.
> Mindestens bei Assembler.

Ein jmp 0 ist nicht das selbe wie ein Hardware-Interrupt, da es nicht 
das selbe macht.....PUNKT

Und wenn ein "gewollter Neustart" oder WDT funktionieren soll, setzt das 
eindeutige Startbedingungen voraus, die man mit einem jmp 0 eben nicht 
erreicht.

Wenn nämlich genau bei der ersten Instruction ein vorher eingeschalteter 
Interrupt zuschlägt, ist das ein nicht ganz leicht zu debuggendes 
Problem.

Und dabei ist es vollkommen egal, ob man in Assembler oder einer 
Hochsprache programmiert.

von Norbert S. (norberts)


Lesenswert?

Harry L. schrieb:
> Und wenn ein "gewollter Neustart" oder WDT funktionieren soll, setzt das
> eindeutige Startbedingungen voraus, die man mit einem jmp 0 eben nicht
> erreicht.
>
> Wenn nämlich genau bei der ersten Instruction ein vorher eingeschalteter
> Interrupt zuschlägt, ist das ein nicht ganz leicht zu debuggendes
> Problem.
>
> Und dabei ist es vollkommen egal, ob man in Assembler oder einer
> Hochsprache programmiert.

Moin,

Genau das meinte ich.
Man startet bei 0 mit allem was vorher gesetzt war.
Irgendwas setzen AVR8 wieder zürück meine ich aber das meiste eben 
nicht.
Das ist ne Scheissidee, wenn man nicht ganz genau weiss, was man tut.
Auch bei ASM.
Das Flag des externen Ints kann z.B. gesetzt sein und dann schlägt der 
zu.
Dafür muss kein Int aktiviert sein.
Das dürfte auch bei ASM der Fall sein und man bildet sich nur ein, jedes 
Bit unter Kontrolle zu haben.

Gruß,
Norbert

von Einer K. (Gast)


Lesenswert?

Norbert S. schrieb:
> Das dürfte auch bei ASM der Fall sein und man bildet sich nur ein, jedes
> Bit unter Kontrolle zu haben.

Ich finde diese Argumentation ganz klasse.

Wer jedes Bit unter Kontrolle hat, der macht doch keinen Soft- Reset!
Wo zu soll das dann gut sein?
Ist doch dann völlig Sinn befreit.
Geradezu Absurd.
Oder?

Vorm Reset weiß man genau, was los ist, und danach auch.
Also scheint ein Soft- Reset an der Stelle doch dann irgendwie flüssiger 
als Wasser zu sein.
Überflüssig.

von Paul (Gast)


Lesenswert?

Bevor sich einige zu stark aufregen oder gar das Messer wetzen, einiges 
zur Klarstellung
Es ist Atmega 8 , Arbeite mit dem AVR Studio in C.
Es geht dabei um ein Spiel. Es soll ein Ball geschlagen werden, trifft 
er, geht es weiter. Trifft er nicht, soll das Spiel von Vorn beginnen. 
Vorn bedeutet dabei es wird der Startbildschirm gezeigt und es beginnt 
wenn die Startzeit auf 0 steht. Dazu werden wieder alle Daten neu 
geladen.
LG Paul

von Einer K. (Gast)


Lesenswert?

Also nur ein ganz normaler Zustand einer Ablaufsteuerung.

Fein!
Dann ist ja kein Reset nötig.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Paul schrieb:
> in meinen Projekt muss ich in Abhängigkeit den Ablauf unterbrechen bzw.
> beenden. Danach muss ein Neustart durch ein Reset erfolgen.
Das ist die lange Schreibweise für "Programmierfehler".

Paul schrieb:
> Dazu werden wieder alle Daten neu geladen.
Aber es wird eben nicht "neu gebootet".
Sondern du setzt ein paar Zähler auf null und zeigst die Startgrafik an. 
Ein ganz normaler Programmablauf. Man muss den Fernseher zum 
Programmwechsel ja auch nicht neu starten...

von Nop (Gast)


Lesenswert?

Arduino F. schrieb:

> Vorm Reset weiß man genau, was los ist, und danach auch.
> Also scheint ein Soft- Reset an der Stelle doch dann irgendwie flüssiger
> als Wasser zu sein.

Neben der Funktion, auf Werkseinstellungen zu gehen, wofür man einen 
richtigen Reset nehmen sollte, gibt's ja auch noch den Fall eines 
Absturzes. Ja, den gibt es auch bei Assembler-Programmen, hab ich genug 
von gesehen.

Wenn man dann in irgendeiner Art von Handler dafür ist, dann ist das 
ganze System offensichtlich undefiniert, so daß man am Ende des Handlers 
einen Reset braucht. Sinnigerweise harter Reset mit Watchdog, weil der 
Systemzustand eben undefiniert ist.

von majortom (Gast)


Lesenswert?

example, mein sw reset

#include <avr/wdt.h>
...

void initWDT(void) __attribute__((naked)) 
__attribute__((section(".init3")));

void initWDT(void) {
  MCUSR = 0;
  wdt_disable();
}

#define INITWDT() initWDT()

#define SOFTRESET() do { \
  wdt_enable(WDTO_15MS); \
  while (1) {;} \
} while(0)

von Veit D. (devil-elec)


Lesenswert?

Hallo,

jump 0 ist kein sauberer Reset, dass ist nur Krampf, weiß nicht wer das 
in die Welt gesetzt hat.

Schreibe das Programm sauber und du brauchst keine Krücken. Auch ein 
Watchdog ist eigentlich Krampf. Auch dieser sollte nie bewusst für 
Pfusch im Code missbraucht werden.

von Norbert S. (norberts)


Lesenswert?

Veit D. schrieb:
> jump 0 ist kein sauberer Reset, dass ist nur Krampf, weiß nicht wer das
> in die Welt gesetzt hat.

Moin,

Es gibt Ausnahmefälle, wo man das nutzen kann aber wie ich bereits 
schrieb, nur wenn man wirklich ganz genau weiß, was man tut.
Bei selbstgefrickelten Bootloadern kann das mal nötig sein.
Aber ne, das ist eigentlich nix.

Veit D. schrieb:
> Auch ein
> Watchdog ist eigentlich Krampf. Auch dieser sollte nie bewusst für
> Pfusch im Code missbraucht werden.

Das sehe ich nicht so. Ist bei AVR8 nunmal die einzige Lösung für einen 
sauberen Reset per Software. Wenn man den denn braucht.
Braucht man ihn im ursprünglichen Sinne, also wenn das Programm hängt, 
hat man eher vorher schon was falsch gemacht (kein Timeout bei 
Kommunikation oder sowas).

Hier ist das aber alles Quatsch. Er will das Spiel nur neu starten. Da 
ist das alles kompletter Unsinn.
Spiel wird abgebrochen und neu gestartet, das hat nun echt nicht mit 
Reset zu tun. Da muss jemand nur noch etwas Programmieren lernen.

Gruß,
Norbert

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.