ATMega128 stürzt ab nachdem man Interrupts einschaltet.

OP #2027256
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?
OP #2027344
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!
Gast #2027358
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?
#2027366
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!
Persönliche Seite #2027562
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!
#2027598
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!
Persönliche Seite #2027609
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){}
Persönliche Seite #2027772
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...
OP #2027916
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

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