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


von Daniel S. (ds1982)


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:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
volatile unsigned int Counter;
5
volatile unsigned int i;
6
7
ISR( TIMER0_OVF_vect )
8
{
9
  Counter++;
10
11
  if( Counter == 10000 ) {
12
  i++;
13
  PORTC=(1<<i);
14
  if (i==7) i=0;    
15
    Counter = 0;
16
  }
17
}
18
19
int main()
20
{
21
  Counter = 0;
22
  DDRA=0xff;
23
  DDRB=0xFF;
24
  DDRC=0xff;
25
  PORTA=0x01;
26
  PORTB=0x01;
27
  PORTC=0;
28
29
30
31
  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ); // Teiler: 1024
32
  TIMSK = ( 1 << TOIE0 );         // Overflow Interrupt einschalten
33
  sei();                          // Interrupts an
34
35
  while( 1 ){}
36
37
}
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?

von Läubi .. (laeubi) Benutzerseite


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.

von Peter D. (peda)


Lesenswert?

M103 Fuse

Peter

von Daniel S. (ds1982)


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!

von holger (Gast)


Lesenswert?

Watchdog abschalten?

von Daniel S. (ds1982)


Lesenswert?

holger schrieb:
> Watchdog abschalten?

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

von holger (Gast)


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?

von Daniel S. (ds1982)


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....

von holger (Gast)


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;)

von Chris L. (kingkernel)


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!

von Daniel S. (ds1982)


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 ;)

von holger (Gast)


Lesenswert?

>DAS WARS! Optimierung ausgemacht und schon läufts...

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

von Chris L. (kingkernel)


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!

von Läubi .. (laeubi) Benutzerseite


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.
1
int main() {
2
 int a = 1;
3
 while(a) {}
4
 return a;
5
}
Ist nicht äquivalent zu
1
int main() {
2
 int a = 1;
3
 return a;
4
}
 folglich darf es auch nicht "wegoptimiert" werden!

von holger (Gast)


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;)

von Chris L. (kingkernel)


Lesenswert?

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

seltsamer weise wird ein
1
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!

von Peter (Gast)


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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Christian L. schrieb:

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

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

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

*main.lss*
1
Disassembly of section .text:
2
3
00000000 <__vectors>:
4
   0:  0c 94 2a 00   jmp  0x54  ; 0x54 <__ctors_end>
5
   4:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
6
        ... usw ...
7
  50:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
8
9
00000054 <__ctors_end>:
10
  54:  11 24         eor  r1, r1
11
  56:  1f be         out  0x3f, r1  ; 63
12
  58:  cf e5         ldi  r28, 0x5F  ; 95
13
  5a:  d8 e0         ldi  r29, 0x08  ; 8
14
  5c:  de bf         out  0x3e, r29  ; 62
15
  5e:  cd bf         out  0x3d, r28  ; 61
16
  60:  0e 94 36 00   call  0x6c  ; 0x6c <main>
17
  64:  0c 94 37 00   jmp  0x6e  ; 0x6e <_exit>
18
19
00000068 <__bad_interrupt>:
20
  68:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>
21
22
0000006c <main>:
23
int main(void)
24
{
25
  6c:  ff cf         rjmp  .-2        ; 0x6c <main>
26
27
0000006e <_exit>:
28
  6e:  f8 94         cli
29
30
00000070 <__stop_program>:
31
  70:  ff cf         rjmp  .-2        ; 0x70 <__stop_program>

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

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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

Da hat nix damit zu tun ob die Schleife leer ist!
1
while(0) {
2
ganz
3
viele
4
Anweisungen
5
kommen noch
6
hier
7
}
könnte wegoptimiert werden, da der Schleifenrumpf nie erreicht wird.
1
for(i = 0; i < 100; i++) {
2
3
}
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...

von Daniel S. (ds1982)


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!

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.