www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega128 stürzt ab nachdem man Interrupts einschaltet.


Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Community,

ich habe vor mir einen ATMega128 liegen, dieser ist über einen Original 
Atmel JTAGICE mk2 an meinem PC, worauf AVRStudio4 läuft.

Da ich das erste mal mit diesem Debugger arbeite vermute ich den Fehler 
dort, allerdings ist die Hardware auch gerade frisch, deshalb kann ich 
dort Fehler nicht 100% ausschliessen.

Kommunikation zwischen AtMega128 und PC läuft über JTAG, funktioniert 
auch einwandfrei, ich kann im Debug-Fenster Ausgänge per Hand setzen und 
die Hardware schaltet diese dann auch.

Nun wollte ich alles durchtesten und habe folgendes kleine Testprogramm 
geschrieben:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned int Counter;
volatile unsigned int i;

ISR( TIMER0_OVF_vect )
{
  Counter++;

  if( Counter == 10000 ) {
  i++;
  PORTC=(1<<i);
  if (i==7) i=0;    
    Counter = 0;
  }
}

int main()
{
  Counter = 0;
  DDRA=0xff;
  DDRB=0xFF;
  DDRC=0xff;
  PORTA=0x01;
  PORTB=0x01;
  PORTC=0;



  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ); // Teiler: 1024
  TIMSK = ( 1 << TOIE0 );         // Overflow Interrupt einschalten
  sei();                          // Interrupts an

  while( 1 ){}

}
Dieses soll einfach nur den PortC der Reihe nach durchschalten.
Bei Debuggen passiert folgendes (Ich gehe mit F11 Schritt für Schritt 
jede Zeile durch):

Programm läuft bis zum sei();. Drücke ich dann ein weiteres Mal F11 
bleiben die Schaltflächen im AVR-Studio grau, es passiert gar nichts und 
nach ein paar Sekunden macht anscheinend der Prozessor einen Reset, der 
Programmzeiger ist wieder am Anfang und ich kann von vorne beginnen.

Wo liegt mein Fehler?

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vermutlich wird noch ein weiterer Interrupt ausgelöst, Überschreibe mal 
den DefaultInterupthandler und setze dort einen Breakpoint.
Eventuelle hilft es auch den AVR einmal komplett stromlos zu schalten.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M103 Fuse

Peter

Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die M103 Fuse war tatsächlich an, kann ja keiner Ahnung dass das 
Werkseinstellung ist ;)

Habe die Fuse nun aus gemacht, allerdings läufts immernoch nicht, 
gleicher Fehler!!

Läubi .. schrieb:
> Vermutlich wird noch ein weiterer Interrupt ausgelöst, Überschreibe mal
> den DefaultInterupthandler und setze dort einen Breakpoint.

Wieso sollte das passieren? Bzw. wodurch ausgelöst? (Habs noch nicht 
getestet)

> Eventuelle hilft es auch den AVR einmal komplett stromlos zu schalten.
hilft leider nicht!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Watchdog abschalten?

Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
> Watchdog abschalten?

Ist der nicht per default aus? (siehe Code oben)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Watchdog abschalten?

>Ist der nicht per default aus? (siehe Code oben)

Das ist richtig. Aber vieleicht hast du ihn
eingeschaltet? Hast du die deaktivierte M103C Fuse
auch in den Mega geschrieben?

Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
>> Watchdog abschalten?
>
>>Ist der nicht per default aus? (siehe Code oben)
>
> Das ist richtig. Aber vieleicht hast du ihn
> eingeschaltet?
Das sollte dann doch oben im Code zu sehen sein oder?

> Hast du die deaktivierte M103C Fuse
> auch in den Mega geschrieben?

Japp, und gerade nochmal verifiziert....

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Watchdog abschalten?
>>
>> Das ist richtig. Aber vieleicht hast du ihn
>> eingeschaltet?

>Das sollte dann doch oben im Code zu sehen sein oder?

Es gibt eine WDT Fuse;)

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kontrolliere erstmal alle Fuse-Bits. Ich hab schon AVR's gehabt die 
haben von Werk an unterschiedliche Konfigurationen gehabt.
Kannst du das Programm in einem anderen mega128 testen?

Ansonsten fallen mir nur nicht definierte Interruptvektoren, Watchdog 
oder Stackfehler ein. sofern der obige code auch wirklich alles ist!
es könnte aber auch sein, dass der Compiler das while(1){} wegoptimiert. 
Setze da mal was rein, nur um sicher zu gehen.

du hast übrigens vergessen, i zu initialisieren.

PS: Es gibt eine WDT-Fuse!

Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:


> es könnte aber auch sein, dass der Compiler das while(1){} wegoptimiert.
> Setze da mal was rein, nur um sicher zu gehen.

DAS WARS! Optimierung ausgemacht und schon läufts...
zusätzlich zur M103 natürlich...

THX!!!


> du hast übrigens vergessen, i zu initialisieren.
hatte ich selbst schon gesehen ;)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>DAS WARS! Optimierung ausgemacht und schon läufts...

Der Compiler kann kein while(1){} wegoptimieren;)

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ist das gemeint? Das macht natürlich der Optimierer. Oder willst du 
sagen, dass das überhaupt nicht wegoptimiert werden würde. Ich habe 
schon oft genug gegenteiliges erlebt!

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> Wie ist das gemeint? Das macht natürlich der Optimierer. Oder willst du
> sagen, dass das überhaupt nicht wegoptimiert werden würde. Ich habe
> schon oft genug gegenteiliges erlebt!

Dann ist das ein Bug des Compilers/Optimierers.
int main() {
 int a = 1;
 while(a) {}
 return a;
}
Ist nicht äquivalent zu
int main() {
 int a = 1;
 return a;
}
 folglich darf es auch nicht "wegoptimiert" werden!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>DAS WARS! Optimierung ausgemacht und schon läufts...

Irgendwie werde ich das Gefühl nicht los dass das Programm da oben
nicht das Original ist;)

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wird eine leere schleife nicht immer wegoptimiert?
while(1){}
ist leer und wird wegoptimiert, wobei
while(1){asm("nop");}
geht.

seltsamer weise wird ein
while(1);
nicht wegoptimiert, seltsam!

teilweise glaube ich aber auch, dass es an was anderem gelegen hat und 
er einfach nur alle tipps auf einmal probiert hat und irgend einer 
funktioniert hat!

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> wird eine leere schleife nicht immer wegoptimiert?
nein, sie sollte NIE wegoptimiert werden. Das würde ja das verhalten 
verändern. Der Compiler darf aber alles nach der schleife weglassen weil 
man dort eh nicht hinkommt.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:

>
> while(1){}
> 
> ist leer und wird wegoptimiert,

Bei meiner Toolchain (WinAVR-20100110) und der default -Os Optimierung 
nicht.

*main.c* (Atmega32)
int main(void)
{
  while(1){}
}

*main.lss*
Disassembly of section .text:

00000000 <__vectors>:
   0:  0c 94 2a 00   jmp  0x54  ; 0x54 <__ctors_end>
   4:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
        ... usw ...
  50:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:  11 24         eor  r1, r1
  56:  1f be         out  0x3f, r1  ; 63
  58:  cf e5         ldi  r28, 0x5F  ; 95
  5a:  d8 e0         ldi  r29, 0x08  ; 8
  5c:  de bf         out  0x3e, r29  ; 62
  5e:  cd bf         out  0x3d, r28  ; 61
  60:  0e 94 36 00   call  0x6c  ; 0x6c <main>
  64:  0c 94 37 00   jmp  0x6e  ; 0x6e <_exit>

00000068 <__bad_interrupt>:
  68:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>

0000006c <main>:
int main(void)
{
  6c:  ff cf         rjmp  .-2        ; 0x6c <main>

0000006e <_exit>:
  6e:  f8 94         cli

00000070 <__stop_program>:
  70:  ff cf         rjmp  .-2        ; 0x70 <__stop_program>

Die Zeile
  6c:  ff cf         rjmp  .-2        ; 0x6c <main>
ist das while(1){}

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> wird eine leere schleife nicht immer wegoptimiert?

Da hat nix damit zu tun ob die Schleife leer ist!
while(0) {
ganz
viele
Anweisungen
kommen noch
hier
}
könnte wegoptimiert werden, da der Schleifenrumpf nie erreicht wird.
for(i = 0; i < 100; i++) {

}
könnte wegoptimiert werden das es (funktional) nicht tut, wenn i im 
weiterem Verlauf nicht mehr verwendet wird.
Aber eine Endlosscleife darf einfach nie wegoptimiert werden, da 
hierdurch schlicht der Programmflus verfälscht wird...

Autor: Daniel S. (ds1982)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb im Beitrag
> Irgendwie werde ich das Gefühl nicht los dass das Programm da oben
> nicht das Original ist;)

falsch! Es war das Original!

Christian L. schrieb:
> teilweise glaube ich aber auch, dass es an was anderem gelegen hat und
> er einfach nur alle tipps auf einmal probiert hat und irgend einer
> funktioniert hat!
 Habs gerade nochmal getestet. Die while1 wird tatsächlich NICHT(!) 
wegoptimiert!

Hatte tatsächlich in diesem Schritt noch was geändert, nämlich die 
Taktrate des AtMega in den Debugger Einstellungen so eingestellt wie sie 
auch tatsächlich ist. Daran lags dann.

Nachdem die M103 aus war war das Verhalten auch gar nicht mehr so wie 
oben beschrieben, sondern der Debugger hat dann immer beim Einzelschritt 
mehrere ausgeführt.
Ich war wohl was hektisch und genervt ;) Sry!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.