Programm beenden - aber wie?

Gast #5224977
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
(Firma: matzetronics) #5224984
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
Gast #5224993
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
Gast #5225046
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.
Gast #5225107
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
Gast #5225175
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
Gast #5225191
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
Gast #5225234
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...
Gast #5225383
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.
Gast #5225393
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 ?
#5225398
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
Gast #5225411
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)
Gast #5225431
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.
Gast #5225456
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.
Gast #5225474
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?
#5225481
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
Gast #5225494
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.
#5225506
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
Gast #5225515
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.
Gast #5225520
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.
#5225539
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.
#5225544
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
Gast #5225554
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.
Gast #5226413
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
Moderator (Firma: Titel) Persönliche Seite #5226447
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...
Gast #5226506
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.
Gast #5226543
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)
#5226808
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren