Forum: Compiler & IDEs GCC erzeugt zu kurze Interrupttabelle auf ATTiny24


von Daniel G. (Gast)


Lesenswert?

Ich versuche seit Stunden verzweifelt folgenden, kleinen 
Programmabschnitt mit avr-gcc unter Windows auf einem ATtiny24V zum 
laufen zu kriegen:
1
#include <avr/interrupt.h>
2
#include <avr/io.h>
3
#include "Tools.h"
4
5
///<summary>ADC Interrupt</summary>
6
ISR(ADC_vect)
7
{
8
  volatile unsigned char ucDummy;
9
  BIT_SET(PINB, PB0);
10
11
  //-- ADCH immer auslesen, damit der AD-Wandler wieder bereit ist
12
  ucDummy=ADCH;      
13
}
14
15
///<summary>Hauptprogramm</summary>
16
__attribute__((noreturn)) void main ()
17
{
18
  //! DEBUG
19
  BIT_SET(DDRB, PB0);
20
  BIT_CLEAR(PORTB, PB0);
21
22
  //-- ADC konfigurieren
23
  ADMUX=0;                        //Eingangskanal 0  
24
  BIT_SET(ADMUX, REFS1);          //1,1V
25
  BIT_SET2(ADCSRA, ADPS1, ADPS2); //Prescaler /64
26
  BIT_SET2(ADCSRA, ADIE, ADEN);   //Interrupt Enable und ADC Enable
27
  
28
  //-- Interrupts freigeben
29
  sei();
30
31
  //-- AD-Wandler anwerfen
32
  BIT_SET(ADCSRA, ADSC);
33
}

Das Problem ist, das der Interrupt nie aufgerufen wird (die LED an PB0 
bleibt aus). Nun habe ich mir die disassembly des Compileroutputs 
angesehen und bin etwas stutzig geworden:
1
Disassembly of section .text:
2
3
00000000 <__vectors>:
4
   0:  0c c0         rjmp  .+24       ; 0x1a <__ctors_end>
5
   2:  27 c0         rjmp  .+78       ; 0x52 <__bad_interrupt>
6
   4:  26 c0         rjmp  .+76       ; 0x52 <__bad_interrupt>
7
   6:  25 c0         rjmp  .+74       ; 0x52 <__bad_interrupt>
8
   8:  24 c0         rjmp  .+72       ; 0x52 <__bad_interrupt>
9
   a:  23 c0         rjmp  .+70       ; 0x52 <__bad_interrupt>
10
   c:  22 c0         rjmp  .+68       ; 0x52 <__bad_interrupt>
11
   e:  21 c0         rjmp  .+66       ; 0x52 <__bad_interrupt>
12
  10:  20 c0         rjmp  .+64       ; 0x52 <__bad_interrupt>
13
  12:  1f c0         rjmp  .+62       ; 0x52 <__bad_interrupt>
14
  14:  1e c0         rjmp  .+60       ; 0x52 <__bad_interrupt>
15
  16:  1d c0         rjmp  .+58       ; 0x52 <__bad_interrupt>
16
  18:  1c c0         rjmp  .+56       ; 0x52 <__bad_interrupt>
17
18
0000001a <__ctors_end>:
19
  1a:  11 24         eor  r1, r1
20
  1c:  1f be         out  0x3f, r1  ; 63
21
  1e:  cf e5         ldi  r28, 0x5F  ; 95
22
  20:  d2 e0         ldi  r29, 0x02  ; 2
23
  22:  de bf         out  0x3e, r29  ; 62
24
  24:  cd bf         out  0x3d, r28  ; 61

Kann es sein, dass hier für meine ISR kein rjmp eingetragen ist. 
Ausserdem sind es viel zu wenig Interruptvektoren da der ATtiny24 17 
Interrupts hat und hier nur 13 vorhanden sind. Dafür fängt der Abschnitt 
__ctors_end zu früh an und belegt einen teil der Interrupttabelle.

Kann jemand das Problem nachvollziehen? Woran könnte das liegen? Mir 
fällt echt nichts mehr ein und ich bin für jeden Tip dankbar...

von Daniel G. (Gast)


Angehängte Dateien:

Lesenswert?

Hier die Datei Tools.h zum Nachvollziehen. Irgendwie kann ich beim 
Bearbeiten eines Postings keine Datei anhängen.

(Scheint heute irgendwie nicht mein Tag zu sein)

von yalu (Gast)


Lesenswert?

Falschen Controllertyp angegeben? Mit -mmcu=attiny24 sieht bei mir die
Tabelle so aus:
1
00000000 <__vectors>:
2
   0:  10 c0         rjmp  .+32       ; 0x22 <__ctors_end>
3
   2:  28 c0         rjmp  .+80       ; 0x54 <__bad_interrupt>
4
   4:  27 c0         rjmp  .+78       ; 0x54 <__bad_interrupt>
5
   6:  26 c0         rjmp  .+76       ; 0x54 <__bad_interrupt>
6
   8:  25 c0         rjmp  .+74       ; 0x54 <__bad_interrupt>
7
   a:  24 c0         rjmp  .+72       ; 0x54 <__bad_interrupt>
8
   c:  23 c0         rjmp  .+70       ; 0x54 <__bad_interrupt>
9
   e:  22 c0         rjmp  .+68       ; 0x54 <__bad_interrupt>
10
  10:  21 c0         rjmp  .+66       ; 0x54 <__bad_interrupt>
11
  12:  20 c0         rjmp  .+64       ; 0x54 <__bad_interrupt>
12
  14:  1f c0         rjmp  .+62       ; 0x54 <__bad_interrupt>
13
  16:  1e c0         rjmp  .+60       ; 0x54 <__bad_interrupt>
14
  18:  1d c0         rjmp  .+58       ; 0x54 <__bad_interrupt>
15
  1a:  1d c0         rjmp  .+58       ; 0x56 <__vector_13>
16
  1c:  1b c0         rjmp  .+54       ; 0x54 <__bad_interrupt>
17
  1e:  1a c0         rjmp  .+52       ; 0x54 <__bad_interrupt>
18
  20:  19 c0         rjmp  .+50       ; 0x54 <__bad_interrupt>

von Hmm... (Gast)


Lesenswert?

Hab mal eben deinen Code durch den GCC gejagt (da du weder die 
verwendete GCC-Version noch dein Makefile beigelegt hast hab ich die 
Defaults von Code::Blocks+GCC V4.2.2 im debug-Build benutzt).
1
00000000 <__vectors>:
2
   0:  10 c0         rjmp  .+32       ; 0x22 <__ctors_end>
3
   2:  28 c0         rjmp  .+80       ; 0x54 <__bad_interrupt>
4
   4:  27 c0         rjmp  .+78       ; 0x54 <__bad_interrupt>
5
   6:  26 c0         rjmp  .+76       ; 0x54 <__bad_interrupt>
6
   8:  25 c0         rjmp  .+74       ; 0x54 <__bad_interrupt>
7
   a:  24 c0         rjmp  .+72       ; 0x54 <__bad_interrupt>
8
   c:  23 c0         rjmp  .+70       ; 0x54 <__bad_interrupt>
9
   e:  22 c0         rjmp  .+68       ; 0x54 <__bad_interrupt>
10
  10:  21 c0         rjmp  .+66       ; 0x54 <__bad_interrupt>
11
  12:  20 c0         rjmp  .+64       ; 0x54 <__bad_interrupt>
12
  14:  1f c0         rjmp  .+62       ; 0x54 <__bad_interrupt>
13
  16:  1e c0         rjmp  .+60       ; 0x54 <__bad_interrupt>
14
  18:  1d c0         rjmp  .+58       ; 0x54 <__bad_interrupt>
15
  1a:  1d c0         rjmp  .+58       ; 0x56 <__vector_13>
16
  1c:  1b c0         rjmp  .+54       ; 0x54 <__bad_interrupt>
17
  1e:  1a c0         rjmp  .+52       ; 0x54 <__bad_interrupt>
18
  20:  19 c0         rjmp  .+50       ; 0x54 <__bad_interrupt>

Hier sind alle 17 Vektoren drin. Und der Vektor für den ADC-Interrupt 
scheint auch an der richtigen Stelle zu sein.

Wie rufst du den GCC den auf?

von Hmm... (Gast)


Lesenswert?

@yalu:

Mist, zu langsam gewesen ;)

von Daniel G. (Gast)


Lesenswert?

Zuerst einmal vielen Dank für eure Mühe.

Jetzt weiß ich wenigstens, dass es an den Paramtern (also an mir) und 
nicht am GCC liegt.

Die GCC Version ist gcc version 4.3.2 (WinAVR 20081205). Also der 
aktuellste WinAVR.

Nachfolgend mal die einzelnen Aufrufe, so wie sie das Makefile absetzt:
1
avr-gcc -c -mmcu=attiny24 -I. -gstabs -Os -DF_CPU=8000000UL -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=./BUILD/test.lst  -std=gnu99 -MMD -MP -MF ./BUILD/test.o.d test.c -o BUILD/test.o 
2
test.c:28: warning: function declaration isn't a prototype
3
test.c:27: warning: return type of 'main' is not 'int'
4
avr-gcc -Wl,-Map=./BUILD/main.map,--cref      ./BUILD/test.o      -o ./BUILD/main.elf
5
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock BUILD/main.elf BUILD/main.hex
6
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex BUILD/main.elf BUILD/main.eep || exit 0
7
avr-objdump -h -S -z BUILD/main.elf > BUILD/main.lss
8
avr-nm -n BUILD/main.elf > BUILD/main.sym

von yalu (Gast)


Lesenswert?

Beim Linken, nämlich in dieser Zeile
1
avr-gcc -Wl,-Map=./BUILD/main.map,--cref      ./BUILD/test.o      -o ./BUILD/main.elf

fehlt -mmcu=attiny24

Wahrscheinlich hat dein Makefile einen Fehler.

von Daniel G. (Gast)


Lesenswert?

Hallo yalu,

danke für den Tip. Manchmal sieht man den Wald vor lauter Bäumen nicht. 
Ich hab immer die Compilerparameter überprüft und den Linker ganz 
übersehen. Werd gleich mal das Makefile anpassen und nochmal Bescheid 
geben.

von Daniel G. (Gast)


Lesenswert?

Hallo zusammen,

kaum macht mann's richtig, schon geht's. Es lag tatsächlich am Fehlenden 
mmcu-Parameter beim Linken.

Vielen Dank fürs Weiterhelfen.

Schönes Restwochenende.

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.