Forum: Mikrocontroller und Digitale Elektronik ATmel Atmega48 IVT und AVR-GCC


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich habe momentan das Problem, dass in C Implementierte ISR nicht 
richtig in die IVT eingetragen werden.

Für den Atmel Atmega48 möchte ich die USART-Interrupts "USART Rx 
complete" und "USART Tx complete" Interrupts verwenden. In meiner 
Implementierung laufe ich jedoch immer nur in die Default ISR. Bei der 
Fehlersuche ist mir aufgefallen, dass im .lss-file die ISRs nicht 
eingetragen wurden. Bei der Verwendung der Defines "USART_RXC_vect" bzw. 
"USART_TX_vect" kommt es zu einer Fehlermeldung:

1
...
2
ISR(USART_RXC_vect)
3
{
4
   asm volatile("nop");
5
}
6
7
ISR(USART_TXC_vect)
8
{
9
   asm volatile("nop");
10
}
11
...
1
 
2
make all 
3
Building file: ../main.c
4
Invoking: AVR Compiler
5
avr-gcc -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega48 -DF_CPU=8000000UL -MMD -MP -MF"main.d" -MT"main.o" -c -o "main.o" "../main.c"
6
../main.c:11: warning: 'USART_RXC_vect' appears to be a misspelled signal handler
7
../main.c:16: warning: 'USART_TXC_vect' appears to be a misspelled signal handler
8
Finished building: ../main.c


Auszug aus der lss Datei:
1
00000000 <__vectors>:
2
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
3
   2:  20 c0         rjmp  .+64       ; 0x44 <__bad_interrupt>
4
   4:  1f c0         rjmp  .+62       ; 0x44 <__bad_interrupt>
5
   6:  1e c0         rjmp  .+60       ; 0x44 <__bad_interrupt>
6
   8:  1d c0         rjmp  .+58       ; 0x44 <__bad_interrupt>
7
   a:  1c c0         rjmp  .+56       ; 0x44 <__bad_interrupt>
8
   c:  1b c0         rjmp  .+54       ; 0x44 <__bad_interrupt>
9
   e:  1a c0         rjmp  .+52       ; 0x44 <__bad_interrupt>
10
  10:  19 c0         rjmp  .+50       ; 0x44 <__bad_interrupt>
11
  12:  18 c0         rjmp  .+48       ; 0x44 <__bad_interrupt>
12
  14:  17 c0         rjmp  .+46       ; 0x44 <__bad_interrupt>
13
  16:  16 c0         rjmp  .+44       ; 0x44 <__bad_interrupt>
14
  18:  15 c0         rjmp  .+42       ; 0x44 <__bad_interrupt>
15
  1a:  14 c0         rjmp  .+40       ; 0x44 <__bad_interrupt>
16
  1c:  13 c0         rjmp  .+38       ; 0x44 <__bad_interrupt>
17
  1e:  12 c0         rjmp  .+36       ; 0x44 <__bad_interrupt>
18
  20:  11 c0         rjmp  .+34       ; 0x44 <__bad_interrupt>
19
  22:  10 c0         rjmp  .+32       ; 0x44 <__bad_interrupt>
20
  24:  0f c0         rjmp  .+30       ; 0x44 <__bad_interrupt>
21
  26:  0e c0         rjmp  .+28       ; 0x44 <__bad_interrupt>
22
  28:  0d c0         rjmp  .+26       ; 0x44 <__bad_interrupt>
23
  2a:  0c c0         rjmp  .+24       ; 0x44 <__bad_interrupt>
24
  2c:  0b c0         rjmp  .+22       ; 0x44 <__bad_interrupt>
25
  2e:  0a c0         rjmp  .+20       ; 0x44 <__bad_interrupt>
26
  30:  09 c0         rjmp  .+18       ; 0x44 <__bad_interrupt>
27
  32:  08 c0         rjmp  .+16       ; 0x44 <__bad_interrupt>



Es sind keine Einträge in der IVT.
Werden direkt die Interrupt Vector Nummern verwendet, kommt es nicht zu 
den Warnungen und die ISR werden an der falschen Stelle in die IVT 
eingetragen:
1
...
2
ISR(_VECTOR(19))
3
{
4
   asm volatile("nop");
5
}
6
7
ISR(_VECTOR(21))
8
{
9
   asm volatile("nop");
10
}
11
...
1
00000000 <__vectors>:
2
   0:  19 c0         rjmp  .+50       ; 0x34 <__ctors_end>
3
 ...
4
  24:  0f c0         rjmp  .+30       ; 0x44 <__bad_interrupt>
5
  26:  0f c0         rjmp  .+30       ; 0x46 <__vector_19>
6
  28:  0d c0         rjmp  .+26       ; 0x44 <__bad_interrupt>
7
  2a:  18 c0         rjmp  .+48       ; 0x5c <__vector_21>
8
  2c:  0b c0         rjmp  .+22       ; 0x44 <__bad_interrupt>
9
...

Laut Datenblatt sollten die Einträge an Adresse 0x0012 und 0x0014 
liegen.
Im Datenblatt steht auch, dass für die Atmega48/88 Derivate ein 
instruction word und für die Atmega168 Derivate zwei instruction word 
benötigt werden.
In der Include-Hierarchie bzw. bei der Nachverfolgung der 
USART_RXC/TXC_vect Defines habe ich auch festgestellt, dass die Datei 
<iom16.h> durch <avr/io.h> inkludiert wird. Scheinbar ist an irgendeiner 
mir nicht bekannten Stelle das Symbol
1
__AVR_ATmega16__
 definiert.

Zur IDE / Build Umgebung:

Ich verwende Eclipse IDE for C/C++ Developers (Version: Oxygen.3a 
Release (4.7.3a)) mit dem AVR Eclipse Plugin 2.4.1 und WinAVR-20100110.


Liegt es vielleicht an diesem ominösen Define
1
__AVR_ATmega16__
?
Hat jemand schon einmal ein ähnliches Problem gehabt?

Viele Grüße

Matthias

von Matthias (Gast)


Lesenswert?

P.S.
Ich habe noch einmal explizit das define AVR_ATmega16 undefined gesetzt 
und das define AVR_ATmega48 gesetzt.
1
 avr-gcc -D__AVR_ATmega48__ -U__AVR_ATmega16__ ...
Es wird dann das file <iomx8.h> includiert und es kommt nicht zur 
Warining beim bauen.
Mir ist auch noch aufgefallen, das im Datenblatt die Vektor Nummer mit 1 
beginnt, jedoch bei der Definition der ISR bzw. hinter den Defines die 
Vektoren mit 0 beginnen (INT0 hat den Vektor 1 und im Datenblatt die 
Vektor Nummer 2). Also ist 19 und 21 in dem obigen Beispiel falsch und 
müste 18 und 20 implementieren.

Die von der Tool-Chain erzeugte IVT hat weiterhin den Faktor 2 in den 
Adressen der Einträge:
1
ISR(USART_RX_vect)
2
{
3
   asm volatile("nop");
4
}
5
6
ISR(USART_TX_vect)
7
{
8
   asm volatile("nop");
9
}
1
  22: 10 c0 rjmp .+32 ; 0x44 <__bad_interrupt>
2
  24: 10 c0 rjmp .+32 ; 0x46 <__vector_18> <<<< USART RX Soll Adresse 12
3
  26: 0e c0 rjmp .+28 ; 0x44 <__bad_interrupt>
4
  28: 19 c0 rjmp .+50 ; 0x5c <__vector_20> <<<< USART TX Soll Adresse 14
5
  2a: 0c c0 rjmp .+24 ; 0x44 <__bad_interrupt>

von m.n. (Gast)


Lesenswert?

Matthias schrieb:
> ../main.c:11: warning: 'USART_RXC_vect' appears to be a misspelled
> signal handler
> ../main.c:16: warning: 'USART_TXC_vect' appears to be a misspelled
> signal handler

Dann schreibe doch einfach einmal
USART_RX_vect und USART_TX_vect bzw. USART_UDRE_vect.

von S. Landolt (Gast)


Lesenswert?


von Matthias (Gast)


Lesenswert?

m.n. schrieb:
> Dann schreibe doch einfach einmal
> USART_RX_vect und USART_TX_vect bzw. USART_UDRE_vect.


Das war es wohl gewesen. Da hat mir die Auto-Verfollständigung und ein 
Problem in der Eclipse-Config ein Strich durch die Rechnung gemacht...

Was ich noch nicht ganz vestehe:
Aus dem Datenblatt ATmega48/88/168:
1
...
2
;SPI Transfer Complete Handler
3
0x012                                              rjmpUSART_RXC; 
4
USART, RX Complete Handler
5
0x013                                              rjmpUSART_UDRE
6
; USART, UDR Empty Handler
7
0x014                                              rjmpUSART_TXC; 
8
USART, TX Complete Handler
9
0x015                                              rjmpADC 
10
; ADC Conversion Complete Handler
11
0x016                                              rjmpEE_RDY; 
12
...

Aus meinem .lss-File:
1
...
2
  24:  18 c0         rjmp  .+48       ; 0x56 <__vector_18>
3
  26:  16 c0         rjmp  .+44       ; 0x54 <__bad_interrupt>
4
  28:  36 c0         rjmp  .+108      ; 0x96 <__vector_20>
5
  2a:  14 c0         rjmp  .+40       ; 0x54 <__bad_interrupt>
6
...

Warum unterscheiden sich die Adressen um den Faktor 2?
Wird hier einmal Byte-Adressiert und einmal Word-Adressiert gerechnet?

Zu dem Problem mit dem Define:
1
__AVR_ATmega16__

Wird wohl identisch zu diesem Problem sein: 
https://www.avrfreaks.net/comment/2264901#comment-2264901

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.