Forum: Compiler & IDEs Endlosschleife und Interrupt


von M. I. (Gast)


Lesenswert?

Hallo,

machen die folgenden Codebeispiele für eine Endlosschleife einen 
Unterschied?
1
while(1);
2
3
while(1)
4
{
5
}
6
7
while(1)
8
{
9
   ;
10
}

Ich habe nämlich das Problem, dass eine Interrupt-Routine aufgerufen 
wird, wenn ein Interrupt während der Abarbeitung von "sinnvollem" Code 
eintrifft, aber wenn das Programm dann am Ende in die Endlosschleife 
läuft, reagiert die ISR nicht mehr.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

M. I. wrote:
> machen die folgenden Codebeispiele für eine Endlosschleife einen
> Unterschied?

Nein.

> Ich habe nämlich das Problem, dass eine Interrupt-Routine aufgerufen
> wird, wenn ein Interrupt während der Abarbeitung von "sinnvollem" Code
> eintrifft, aber wenn das Programm dann am Ende in die Endlosschleife
> läuft, reagiert die ISR nicht mehr.

Das kann nicht sein, der Fehler hat sicherlich nichts mit der 
Endllosschleife zu tun. Zeig doch mal den kompletten Programmcode.

von M. I. (Gast)


Lesenswert?

Der Code kommt morgen. Es handelt sich aber nicht um einen AVR, und der 
Code besteht eigentlich nur aus Funktionen die den Interruptcontroller 
für diesen Prozessor (xilinx microblaze) vorbereiten.

Kann es auch sein, dass der Gnu-Debugger das nicht auf die Reihe 
bekommt? Kann es nämlich nur dort testen. Wenn er an die Stelle mit der 
Endlosschleife kommt erscheint die Windoof-Sanduhr und man kann nur noch 
durch Schließen des GDB das Programm abbrechen.

von Power (Gast)


Lesenswert?

Außer dass bei
1
while(1);
das
1
do
2
{
3
}
(erzwungenes einmaliges durchlaufen der Bedingung) davor fehlt und
ich
1
while(1)
2
{
3
   ;
4
}
in der Form nicht kenne,
sollte das wirklich keinen Unterschied machen.

von M. I. (Gast)


Lesenswert?

Bleibt also die Frage, ob ein Debugger mit sowas klar kommt, oder 
einfach abstürzt. Werd morgen mal einen Breakpoint auf die Schleife 
setzen.

von johnny.m (Gast)


Lesenswert?

@Power:
Was hat das mit "do" zu tun? Genau, gar nichts. Die Schreibweise
1
while(1);
ist den anderen beiden völlig gleichwertig und sicher die kürzeste. Da 
fehlt gar nichts.

von TechInfo (Gast)


Lesenswert?

So, hier der Quelltext. Die Funktionen werden euch nicht viel sagen, es 
sind Top-Level-Funktionen zur Initialisierung der Interrupts speziell 
für den xilinx microblaze.

Wenn ich während der Abarbeitung der Funktionen ein Zeichen in das 
Terminal eintippe, wird nach der letzten Init-Funktion 
(microblaze_enable_interrupts();) ein Interrupt ausgelöst (die ISR ist 
RecvCallback) und "Angekommen" auf dem Terminal ausgegeben. Wenn ich die 
Terminal-Eingabe allerdings erst in der while-Schleife vornehme, 
passiert nichts.

[c]
int main (void) {


  XInterruptHandler uart_int_handler;
  uart_int_handler=RecvCallback;


  /* Register UART interrupt handler */
  XIntc_RegisterHandler(XPAR_OPB_INTC_0_BASEADDR,
  XPAR_OPB_INTC_0_RS232_INTERRUPT_INTR, uart_int_handler, (void *)0);

  /* Start the interrupt controller */
  XIntc_mMasterEnable(XPAR_OPB_INTC_0_BASEADDR);

  /* Enable uart interrupts in the interrupt controller */
   XIntc_mEnableIntr(XPAR_OPB_INTC_0_BASEADDR,
         XPAR_RS232_INTERRUPT_MASK);
  /* Enable uart interrupts */
  XUartLite_mEnableIntr(XPAR_RS232_BASEADDR);
  /* Enable MicroBlaze interrupts */
  microblaze_enable_interrupts();

  while(1)
  {
  }
        return 0;
}

von TechInfo (Gast)


Lesenswert?

void RecvCallback (void* InstancePtr)
{
  print("Angekommen");
}

von TechInfo (Gast)


Lesenswert?

Wenn ich irgendeinen Code in die while-Schleife packe, wie i++, 
funktioniert es übrigens auch in der Schleife.

von Power (Gast)


Lesenswert?

@  johnny.m:
Wann hast du das letzte mal in ein C-Buch geschaut? Kennst du den 
Unterschied zwischen
1
do
2
{
3
...
4
}
5
while (irgendwas=1);
und
1
while (irgendwas=1)
2
{
3
...
4
}
?
Nix für ungut, aber da ist ein gravierender Unterschied! Und man sollte 
sich nicht eine einfache Schreibweise angewöhnen die etwas anderes 
beinhaltet als nachher 'rauskommt, weil der Compiler wegen nie 
erfüllbarer Bedingung etwas Anderes draus optimiert.

von Karl H. (kbuchegg)


Lesenswert?

Power wrote:
> @  johnny.m:
> Wann hast du das letzte mal in ein C-Buch geschaut? Kennst du den
> Unterschied zwischen
>
1
> do
2
> {
3
> ...
4
> }
5
> while (irgendwas=1);
6
>
> und
>
1
> while (irgendwas=1)
2
> {
3
> ...
4
> }
5
>
> ?
> Nix für ungut, aber da ist ein gravierender Unterschied!

Das ist schon richtig.

Aber das stand gar nicht zur Debatte.
Fakt ist, dass alle 3 Schreibweisen:
1
while(1);
2
3
while(1)
4
{
5
}
6
7
while(1)
8
{
9
   ;
10
}

absolut identisch sind und vor allen Dingen, völlig richtig.
Vor
 while(1);
fehlt keineswegs ein do.

Das ist eine ganz normale while-Schleife bei der der
Schliefenkörper aus einem einzigen Statement besteht,
nämlich aus dem leeren Statement.

Vielleicht siehst du das besser, wenn man das umformatiert

  while(1)
    ;

Vielleicht solltest du in ein C-Buch schauen :-)

> Und man sollte
> sich nicht eine einfache Schreibweise angewöhnen die etwas anderes
> beinhaltet als nachher 'rauskommt, weil der Compiler wegen nie
> erfüllbarer Bedingung etwas Anderes draus optimiert.

Im genannten Beispiel gibt es keine nie erfüllbaren
Bedingungen. Und auch mit Optimieren ist nichts. Eine
Endlosschleife kann auch der dümmste Compiler nicht
wegoptimieren.


von Power (Gast)


Lesenswert?

>while(1)
>    ;

So isses richtig. Da bin ich drüber gestolpert. Habe mir eine saubere 
Strukturierung meiner Programme angewöhnt, so finde ich mich auch nach 
Jahren noch zurecht. Den Semikolon direkt hinter die Klammer zu setzen 
ist eben sehr verwirrend und sollte vermieden werden.
:-D

von ??? ?? (Gast)


Lesenswert?

Was bedeutet die 1 in der Klammer? while(1)
Kann da auch was anderes stehen 2;3;;100?

von Karl H. (kbuchegg)


Lesenswert?

??? ?? wrote:
> Was bedeutet die 1 in der Klammer? while(1)
> Kann da auch was anderes stehen 2;3;;100?

C-Regel:
Alles was nicht 0 ist, hat den logischen Wert 'wahr' (true)

while( 1 )
  ;

ist also nichts anderes als

  while( TRUE )
    ;

oder

  while( 1 == 1 )

oder

  while( 5 )

oder
...

Der springende Punkt ist: Die Bedingung ist immer
wahr und daher kommt die Programmausführung aus dieser
Schleife durch Auswerten der Bedingung nicht mehr heraus
-> eine Endlosschleife ist entstanden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die Endlosschleife kann der Debugger vermutlich nicht als
Breakpoint benutzen.  Du versuchst offenbar, über diese Schleife
(mit einem Einzelschritt oder was auch immer) hinwegzugelangen,
was natürlich nicht geht.

Zum Debuggen ist es sicher am sinnvollsten, in die Schleife irgendeinen
minimalen Code einzufügen, z. B. einen Portausgabe oder sowas.

von Karl H. (kbuchegg)


Lesenswert?

Die frühen Microsoft Debugger hatten
bei solchen Dingen

   while(1);

auch so ihre Schwierigkeiten. Von da hab ich mir auch
angewöhnt, ein Statement (und wenn es nur ein leeres
Statement ist) in eine neue Zeile zu schreiben.

Mit

   while(1)
     ;

hatten diese Debugger niemals ein Problem.

Vielleicht hilfts ja jetzt auch noch.

von ??? ?? (Gast)


Lesenswert?

  Karl heinz
Vielen Dank für die Erklärung

Gruß

von Rolf Magnus (Gast)


Lesenswert?

Extra für Endlosschleifen gibt's bei for-Schleifen die Möglichkeit, die 
Bedingung auch einfach ganz wegzulassen:
1
for(;;)
2
    ;

  

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.