Forum: Compiler & IDEs warning: internal error: out of range error


von Steffen Graap (Gast)


Lesenswert?

Hallo

Ich benutze eclipse mit Winavr. Mittlerer Weile ist mein Programm so 
groß geworden das ich die Warnung "warning: internal error: out of range 
error" vom Linker bekomme. Im einzelnen handelt es sich um folgende 
Meldungen:

c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/avr6\libgcc.a(_addsub_sf.o) 
:  In function `_fpadd_parts':
(.text+0x6): warning: internal error: out of range error
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/avr6\libgcc.a(_addsub_sf.o) 
:  In function `__subsf3':
(.text+0x29c): warning: internal error: out of range error
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/avr6\libgcc.a(_addsub_sf.o) 
:  In function `__subsf3':
(.text+0x29e): warning: internal error: out of range error
Finished building: TRENDvent_Bedien.lss
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/avr6\libgcc.a(_addsub_sf.o) 
:  In function `__addsf3':
(.text+0x2fe): warning: internal error: out of range error

und noch einige mehr.

Als letzes habe ich weitere FLASH-Konstanten zum Code hinzugefügt, sodas 
jetzt gut 32k mit Flashkonstanten (Bilder, Texte, Configurationen, ect.) 
voll sind. Alle wurden mit dem PROGMEM-Atrribut angelegt und landetetn 
in der .text-Section.

Der eigentliche Programmcode beginnt bei 0000815a <vBoot>: (aus 
.lss-File)

Ich habe schon im Forum gesucht, aber noch nichts zu spezillen Problem 
gefunden, da die Fehler ja beim vom Compiler generiertem Code entstehen.

Was kann ich machen um das Problem zu lösen?

Gruß Steffen

von klaus (Gast)


Lesenswert?

Weiß nicht was mit Winavr möglich ist, aber vielleicht gibts nen Weg 
größere Konstanten in .rodata zu bekommen...

von Stefan E. (sternst)


Lesenswert?

Du solltest die Library libm.a benutzen (-lm).

von Steffen Graap (Gast)


Lesenswert?

Hab das -lm dem Linker hinnzugefügt, hat aber leider nichts genutzt.

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Steffen Graap schrieb:
> Hab das -lm dem Linker hinnzugefügt, hat aber leider nichts genutzt.

Was soll das heißen? Dass der Output immer noch genau so aussieht?
Wie sieht der Linker-Aufruf denn konkret aus?

von Steffen Graap (Gast)


Angehängte Dateien:

Lesenswert?

Der Output sieht zwar nicht genau so aus, aber die warnings sind immer 
noch da. Da die Ausgaben hier den Rahmen sprengen würden habe, ich sie 
als Anhang beigefügt. Jeweils einemal mit, und ein mal ohne den 
Linkerzusatz -lm.
Auch ist dort jeweils der Linkeraufruf enthalten. Das Linkerscript 
"TRENDvent.x" ist das Standartscript für den Mega2560 (avr6.x) erweitert 
um die Zusätze für die .xram-Section. Auch das habe ich im Anhang 
beigefügt.

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Falsche Position. Das -lm muss hinter die Objekt-Dateien.

von Steffen Graap (Gast)


Lesenswert?

Oh, Danke das wusste ich bis eben nicht, man lernt ständig dazu. Da ich 
über eclipse arbeite, habe ich einfach den Zusatz mit ins Argumentenfeld 
eingetragen, um die ganzen Objektdateien kümmert sich eclipse selbst.
Nun hab ichs einfach als zu benutzende bibliothek übergeben.

Das Resultat siehst du unten. Die Warnings sind schon weniger geworden, 
aber immer noch vorhanden.

Gruß Steffen

Invoking: AVR C Linker
avr-gcc -Wl,-Map,TRENDvent_Bedien.map -T 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x -mmcu=atmega2560 
-o"TRENDvent_Bedien.elf"  ./Code/boot.o ./Code/dateisystem.o 
./Code/doxygen.o ./Code/key.o ./Code/lcd_graph.o ./Code/lcd_text.o 
./Code/main.o ./Code/memory.o ./Code/menue.o ./Code/spi.o 
./Code/sprache.o ./Code/steuerung.o ./Code/task.o ./Code/tim.o 
./Code/usart.o ./Code/usart_1.o ./Code/usart_2.o ./Code/usart_3.o   -lm
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(dtoa_prf.o):  In function `dtoa_prf':
(.text+0x4): warning: internal error: out of range error
Finished building target: TRENDvent_Bedien.elf
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(dtoa_prf.o):  In function `dtoa_prf':
(.text+0x6): warning: internal error: out of range error
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x4): warning: internal error: out of range error

Invoking: AVR Create Extended Listing
avr-objdump -h -S TRENDvent_Bedien.elf  >"TRENDvent_Bedien.lss"
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x6): warning: internal error: out of range error
Finished building: TRENDvent_Bedien.lss

Create Flash image (ihex format)
avr-objcopy -R .eeprom -O ihex TRENDvent_Bedien.elf 
"TRENDvent_Bedien.hex"
Finished building: TRENDvent_Bedien.hex

Invoking: Print Size
avr-size --format=avr --mcu=atmega2560 TRENDvent_Bedien.elf
AVR Memory Usage
----------------
Device: atmega2560

Program:  137006 bytes (52.3% Full)
(.text + .data + .bootloader)

Data:       3634 bytes (44.4% Full)
(.data + .bss + .noinit)


Finished building: sizedummy

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wenn du mal -g einschaltest (Debug-Information), dann kann der
Linker dir statt nur einer Adresse die Quellcodezeile mit sagen,
auf die sich das bezieht.  Vielleicht hast du ja dann eher eine
Idee, was die Ursache sein könnte.

von Steffen Graap (Gast)


Lesenswert?

Leider hat das hinzufügen von -g zum Linkeraufruf nicht mehr 
Informationen gebracht. sieh unten

Was sind trampolines ? Im Listfile gibt es zwei Sprünge in diesem Teil. 
Die beiden Sprünge sind genau die beiden Dateien, die der Linker 
bemängelt

000080e8 <__trampolines_start>:
    80e8:  0d 94 2b 06   jmp  0x20c56  ; 0x20c56 <strtod+0x250>
    80ec:  0d 94 c9 04   jmp  0x20992  ; 0x20992 <dtoa_prf+0x250>

Gruß Steffen

make all
Building target: TRENDvent_Bedien.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,TRENDvent_Bedien.map -g -T 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x -mmcu=atmega2560 
-o"TRENDvent_Bedien.elf"  ./Code/boot.o ./Code/dateisystem.o 
./Code/doxygen.o ./Code/key.o ./Code/lcd_graph.o ./Code/lcd_text.o 
./Code/main.o ./Code/memory.o ./Code/menue.o ./Code/spi.o 
./Code/sprache.o ./Code/steuerung.o ./Code/task.o ./Code/tim.o 
./Code/usart.o ./Code/usart_1.o ./Code/usart_2.o ./Code/usart_3.o   -lm
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(dtoa_prf.o):  In function `dtoa_prf':
(.text+0x4): warning: internal error: out of range error
Finished building target: TRENDvent_Bedien.elf
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(dtoa_prf.o):  In function `dtoa_prf':
(.text+0x6): warning: internal error: out of range error

c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x4): warning: internal error: out of range error
Invoking: AVR Create Extended Listing
avr-objdump -h -S TRENDvent_Bedien.elf  >"TRENDvent_Bedien.lss"
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x6): warning: internal error: out of range error
Finished building: TRENDvent_Bedien.lss

von (prx) A. K. (prx)


Lesenswert?

Steffen Graap schrieb:

> Was sind trampolines ? Im Listfile gibt es zwei Sprünge in diesem Teil.
> Die beiden Sprünge sind genau die beiden Dateien, die der Linker
> bemängelt

Pointer sind beim GCC für AVR nur 16 Bits breit, auch wenn sie auf 
Funktionen zeigen und der AVR mehr als 64KW/128KB Flash hat. Folglich 
müssen alle Funktionen, oder mindestens alle die irgendwo indirekt 
genutzt werden, eine Adresse innerhalb des davon adressierbaren Bereichs 
haben.

Diese beiden Funktionen liegen ausserhalb und daher gibt es 
Hilfsadressen innerhalb. Weshalb der Linker damit ein Problem hat ist 
aber für mich unklar. Es fällt zwar auf, dass die Tramplines knapp 
jenseits von 32KB liegen, ich kann aber nicht erkennen weshalb das ein 
Problem sein sollte.

Versuch mal, die ROM-Daten soweit zu reduzieren, dass die Trampolines 
unter 0x8000 rutschen. Nur testhalber, ob da ein Zusammenhang besteht.

von Steffen Graap (Gast)


Lesenswert?

A. K. schrieb:
> Versuch mal, die ROM-Daten soweit zu reduzieren, dass die Trampolines
> unter 0x8000 rutschen. Nur testhalber, ob da ein Zusammenhang besteht.

das hab ich mal gemacht, die Trampolines rutschen jetzt unter 0x8000

00007988 <__trampolines_start>:
    7988:  0d 94 70 02   jmp  0x204e0  ; 0x204e0 <strtod+0x250>
    798c:  0d 94 0e 01   jmp  0x2021c  ; 0x2021c <dtoa_prf+0x250>

Ein Fehler ist dadurch beseitigt worden, der andere bleibt aber.

Steffen

make all
Building file: ../Code/lcd_graph.c
Invoking: AVR Compiler
avr-gcc -Wall -g3 -gstabs -Os -fpack-struct -fshort-enums 
-fno-strict-aliasing -funsigned-char -funsigned-bitfields -c -save-temps 
-mmcu=atmega2560 -DF_CPU=14745600UL -MMD -MP -MF"Code/lcd_graph.d" 
-MT"Code/lcd_graph.d" -c -o"Code/lcd_graph.o" "../Code/lcd_graph.c"
Finished building: ../Code/lcd_graph.c

Building target: TRENDvent_Bedien.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,TRENDvent_Bedien.map -g -T 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x -mmcu=atmega2560 
-o"TRENDvent_Bedien.elf"  ./Code/boot.o ./Code/dateisystem.o 
./Code/doxygen.o ./Code/key.o ./Code/lcd_graph.o ./Code/lcd_text.o 
./Code/main.o ./Code/memory.o ./Code/menue.o ./Code/spi.o 
./Code/sprache.o ./Code/steuerung.o ./Code/task.o ./Code/tim.o 
./Code/usart.o ./Code/usart_1.o ./Code/usart_2.o ./Code/usart_3.o   -lm
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x4): warning: internal error: out of range error
Finished building target: TRENDvent_Bedien.elf
c:/programme/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr6\li 
bc.a(strtod.o):  In function `strtod':
(.text+0x6): warning: internal error: out of range error

Invoking: AVR Create Extended Listing
avr-objdump -h -S TRENDvent_Bedien.elf  >"TRENDvent_Bedien.lss"
Finished building: TRENDvent_Bedien.lss

von (prx) A. K. (prx)


Lesenswert?

Ich fürchte jetzt muss jemand ran, der gcc-avr für >128KB und die 
binutils von innen kennt.

von (prx) A. K. (prx)


Lesenswert?

Ach ja: Ist das die aktuelle Version von WinAVR (20100110)?

von Steffen Graap (Gast)


Lesenswert?

Es ist noch nicht die aktuelle Version, sonder 20090313. Da werd ich 
wohl erst mal die aktuelle Version installieren.

Was mir noch eingfallen ist, ich benutze Funktionspointer
wie z.B. in dieser Funktion
1
UINT8 u8Add_Time_Task (funcp pFunktion , TIMER_RESOLUTION tDelay)
der Pointer ist folgend definiert
1
typedef void (* funcp)(void);

Den oben genannten Aufruf benutze ich 433 mal im Program.

Könnte der Fehler damit was zu tun haben?

Steffen

von (prx) A. K. (prx)


Lesenswert?

Eher nicht, denn dass du strtod indirekt nutzt scheint unwahrscheinlich. 
Aber warte mal bis Jörg Wunsch aufgewacht ist, er scheint auch schon 
über sowas gestoplert zu sein.

von Steffen Graap (Gast)


Lesenswert?

Für mich hat sich das erst mal erledigt. Nach der Installation des 
neusten WinAVR sind die Fehler erst mal weg. Ob alles läuft kann ich 
erst am Montag auf Arbeit testen, da ich hier keine Testhardware habe.

Für mich als Erkenntnis nehme ich erst mal mit, das wenn unerklärliche 
Probleme auftauchen, ich erst mal nach der neusten Version schaue.

Nochmals Danke euch allen für die Hilfe.

Gruß Steffen

PS: nach entfernen des Linkerzusatzes -lm traten die Fehler wieder auf.

von (prx) A. K. (prx)


Lesenswert?

Steffen Graap schrieb:

> Für mich hat sich das erst mal erledigt. Nach der Installation des
> neusten WinAVR sind die Fehler erst mal weg.

Weil das Problem weg ist oder weil nun alles unter 128KB liegt?

von Steffen Graap (Gast)


Lesenswert?

@ A. K.
Du hattest recht. Ich hatte etwas voreilig gehandelt. Das Problem war 
erst mal so wie oben beschrieben nicht mehr vorhande. Da du aber die 
Frage nach den 128kb gestellt hast, hab ich einen Versuche gemacht, und 
alle Debugausgaben (Stringausgaben für erfolgreiche Programmabschnitte 
über eine COM) eingeschaltet. Dabei trat dann der Out off Range error 
wieder auf. Diesmal aber nicht in ein vom Compiler erstellten/benutzten 
Funktion, sondern in der schon weiter oben erwähnten Funktion mit 
Funktionspointerübergabe.

Invoking: AVR C Linker
avr-gcc -Wl,-Map,TRENDvent_Bedien.map -g -T 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x -mmcu=atmega2560 
-o"TRENDvent_Bedien.elf"  ./Code/boot.o ./Code/dateisystem.o 
./Code/doxygen.o ./Code/key.o ./Code/lcd_graph.o ./Code/lcd_text.o 
./Code/main.o ./Code/memory.o ./Code/menue.o ./Code/spi.o 
./Code/sprache.o ./Code/steuerung.o ./Code/task.o ./Code/tim.o 
./Code/usart.o ./Code/usart_1.o ./Code/usart_2.o ./Code/usart_3.o   -lm
./Code/usart_2.o: In function `vSend_Debug_Data':
../Code/usart_2.c:684: warning: internal error: out of range error
../Code/usart_2.c:684: warning: internal error: out of range error
Finished building target: TRENDvent_Bedien.elf

hier die entsprechende Zeile
1
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);

das Listfile zeigt auch den Grund für den out of range error
1
00020440 <vSend_Debug_Data>:
2
 */
3
 //*****************************************************************************
4
void vSend_Debug_Data (void)
5
{
6
//UINT8 u8Counter;
7
u8Putchar_3 (0xAF);
8
   20440:  8f ea         ldi  r24, 0xAF  ; 175
9
   20442:  0f 94 f9 06   call  0x20df2  ; 0x20df2 <u8Putchar_3>
10
u8Putchar_3 (0xFE);
11
   20446:  8e ef         ldi  r24, 0xFE  ; 254
12
   20448:  0f 94 f9 06   call  0x20df2  ; 0x20df2 <u8Putchar_3>

Gibt es eine Art konvertierung von einem 16bit auf einen 32bit 
Funktionspointer? Oder wie löse ich dises Problem?

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Steffen Graap schrieb:

> das Listfile zeigt auch den Grund für den out of range error

Welchen Grund siehst du denn da?
Die beiden "call" sind es jedenfalls nicht, falls du die meintest.

Hast du es schon mit "-Wl,--relax" für den Linker versucht?

von Steffen Graap (Gast)


Lesenswert?

Die Funktion vSend_Debug_Data liegt im Speicher auf Adresse 0x20440 = 
132160. Das ist oberhalb der 16bit-Adressierung. Der Funktionspointer 
aus
1
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);
kann aber nur 16bit.
Da scheint der Hund begraben zu sein.

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Steffen Graap schrieb:
> Die Funktion vSend_Debug_Data liegt im Speicher auf Adresse 0x20440 =
> 132160. Das ist oberhalb der 16bit-Adressierung. Der Funktionspointer
> aus
1
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);
2
>
> kann aber nur 16bit.

Deshalb sollte es für die Funktion ein Trampoline geben, und dessen 
Adresse an die Funktion übergeben werden. Ich habe ein solches Szenario 
(und ein paar Variationen) nachgestellt, und hatte keinerlei Probleme 
damit (mit WinAVR-20090313).

von Steffen Graap (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Deshalb sollte es für die Funktion ein Trampoline geben, und dessen
> Adresse an die Funktion übergeben werden. Ich habe ein solches Szenario
> (und ein paar Variationen) nachgestellt, und hatte keinerlei Probleme
> damit (mit WinAVR-20090313).

die gibt es aber nicht, sondern nur eine für die vCheckCom_2
1
000088f6 <__trampolines_start>:
2
    88f6:  0d 94 4c 03   jmp  0x20698  ; 0x20698 <vCheckCom_2+0xca>

wenn ich dem Linker noch --relax übergeben, dann erscheinen noch 
zusätzliche Warnungen:

make all
Building target: TRENDvent_Bedien.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,TRENDvent_Bedien.map -g-T 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x --relax 
-mmcu=atmega2560 -o"TRENDvent_Bedien.elf"  ./Code/boot.o 
./Code/dateisystem.o ./Code/doxygen.o ./Code/key.o ./Code/lcd_graph.o 
./Code/lcd_text.o ./Code/main.o ./Code/memory.o ./Code/menue.o 
./Code/spi.o ./Code/sprache.o ./Code/steuerung.o ./Code/task.o 
./Code/tim.o ./Code/usart.o ./Code/usart_1.o ./Code/usart_2.o 
./Code/usart_3.o   -lm
c:/programme/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x:6:  warning: 
redeclaration of memory region 'text'
Finished building target: TRENDvent_Bedien.elf

Invoking: AVR Create Extended Listing
avr-objdump -h -S TRENDvent_Bedien.elf  >"TRENDvent_Bedien.lss"
c:/programme/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x:7:  warning: 
redeclaration of memory region 'data'
c:/programme/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x:9:  warning: 
redeclaration of memory region 'eeprom'
Finished building: TRENDvent_Bedien.lss

Create Flash image (ihex format)
avr-objcopy -R .eeprom -O ihex TRENDvent_Bedien.elf 
"TRENDvent_Bedien.hex"
c:/programme/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x:10:  warning: 
redeclaration of memory region 'fuse'
c:/programme/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: 
c:/programme/winavr/avr/lib/ldscripts/TRENDvent.x:11:  warning: 
redeclaration of memory region 'lock'
Finished building: TRENDvent_Bedien.hex

Steffen

von (prx) A. K. (prx)


Lesenswert?

Irgendwo steht, dass man mit --relax auch --gc-sections angeben muss.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich kenne derzeit leider keine einfache Methode, Funktionszeiger für
Code > 128 KiB zu benutzen.  Man müsste die Dinger intern als uint32_t
führen, aber wie dereferenziert man sie dann?

von Steffen Graap (Gast)


Lesenswert?

Die Linkerzusätze bringen leider nichts.

Ich hab mir mal die Funktion, in der der Fehler auftritt, mal näher 
angeschaut. Zu erst der C-Code, auf das wesentliche reduziert (der Rest 
sind nur COM-Ausgaben)
1
void vSend_Debug_Data (void)
2
{
3
...
4
...
5
...
6
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);
7
}

im Listfile sieht das dann wie folgend aus, auch wieder auf das 
wesentliche reduziert.
1
00020440 <vSend_Debug_Data>:
2
 */
3
 //*****************************************************************************
4
void vSend_Debug_Data (void)
5
{
6
...
7
...
8
...
9
u8Add_Time_Task (vSend_Debug_Data, TIME_DEBUG_DATA);
10
   204c0:  80 e0         ldi  r24, 0x00  ; 0
11
   204c2:  90 e0         ldi  r25, 0x00  ; 0
12
   204c4:  6a ef         ldi  r22, 0xFA  ; 250
13
   204c6:  70 e0         ldi  r23, 0x00  ; 0
14
   204c8:  0e 94 6e ec   call  0x1d8dc  ; 0x1d8dc <u8Add_Time_Task>
15
}
die Konstante TIME_DEBUG_DATA ist mit 250 angegeben.
Wie man schön sehen kann wird hier nicht die Adresse von 
vSend_Debug_Data (20440) übergeben und auch keine trampoline-Adresse, 
sondern 0,
Die Frage bleibt weiter im Raum stehen wie kann ich den Linker überreden 
hier ein trampoline zu benutzen?

Steffen

von Steffen Graap (Gast)


Lesenswert?

Ich weiß, das heut Sonntag ist, aber hat niemand eine Idee, warum der 
Linker keine Trampolines benutzt, und wie man ihn dazu überreden kann?

Als Plan B könnte ich die ganzen FLASH-Konstanten (~30kb) ja in den 
hinteren Teil des FLASH legen, dann hätte ich erst mal Ruhe bis der Code 
entsprechend groß ist.
Gibt es dafür ne Standartlösung?
Ansonsten würde ich eine neue Section anlegen, diese in den hinteren 
Berecih des Flash ansiedeln und die Daten mit prm_read_byte_far 
inclusive dem far()-konvertierungsmacro laden.

Gruß Steffen

von (prx) A. K. (prx)


Lesenswert?

Steffen Graap schrieb:

> Gibt es dafür ne Standartlösung?

Sowas ist ein bischen jenseits dessen, was ich einem AVR zumuten würde. 
Oder jedenfalls dem avr-gcc, vielleicht tun sich kommerzielle Compiler 
damit leicher.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap schrieb:
> Ich weiß, das heut Sonntag ist, aber hat niemand eine Idee, warum der
> Linker keine Trampolines benutzt, und wie man ihn dazu überreden kann?

Die AVR-GCC-Hacker findest du immer noch am ehesten auf der
avr-gcc-list (at nongnu.org), nicht hier im Forum.  Allerdings
habe ich von Björn Haase lange nichts mehr gelesen.  Er hat
seinerzeit die Trampoline für den AVR-Port implementiert.

von Steffen Graap (Gast)


Lesenswert?

Ich habe mir die Problematik nochmals genauer angeschaut. Der Fehler 
tritt nur dann auf, wenn ich Funktionen über einen Pointer aufrufe. Bei 
allen anderen Aufrufen funktioniert es mit den Trampolines oder mit 
direkten CALL-Aufrufen. Dabei ist mir eine Idee aufgeblitzt.
Den Aufruf einer Funktion über einen Pointer mache ich nur in einer 
Funktion, die den Pointer aus einer Liste übernimmt. Wenn ich jetzt 
anstelle eines Pointers ein UINT32 ablege, und diesen dann per Assembler 
CALL aufrufe sollte das ganze doch funktionieren? Was meint ihr dazu?

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap schrieb:
> Wenn ich jetzt
> anstelle eines Pointers ein UINT32 ablege, und diesen dann per Assembler
> CALL aufrufe sollte das ganze doch funktionieren?

Ja, das meinte ich weiter oben schon.  Es ist übrigens ein EICALL,
und du musst dich ggf. noch drum kümmern, dass RAMPZ danach wieder
zurück gedreht wird (bin ich mir gerade nicht im Klaren).

Die Frage ist allerdings dennoch, warum die Trampoline hier nicht
greifen.

von Steffen Graap (Gast)


Lesenswert?

@ Jörg

Ja klar, ein EICALL ist der richtige Befehl. Ich werde das mal 
ausprobieren. Ich werde allerdings erst zum Ende der Woche dazu kommen, 
da vorher noch was anderes erledigt werden muss, und mit reduzierten 
Dabugausgaben läuftdas ganze noch.
Ich melde mich dann wieder wenn ich so weit bin um euch auf dem 
Laufenden zu halten.

Muss ich den Bug noch melden oder hat das schon jemand erledigt?

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap schrieb:
> Muss ich den Bug noch melden oder hat das schon jemand erledigt?

Bin ich mir gerade nicht sicher...  Hier:

http://www.nongnu.org/avr-libc/bugs.html

sammelt Eric Weddington alle bekannten Toolchain-Bugs.  Ich finde
auf Anhieb nichts dergleichen, kannst ja auch nochmal drüber schauen
und ggf. einen Bug bei GCC einkippen.

von Steffen Graap (Gast)


Lesenswert?

Ich bin mir auch nicht ganz sicher. Es gibt einen Bug-Report, der sich 
aber mit dem EICALL-Befehl befasst.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38549
Ich denke ich werd da mal einen Bug einfügen.

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Bei diesem Bug bin ich mir nicht sicher, da auch der WinAVR-Bug, auf
den er sich bezieht, nicht mehr zugänglich ist.

Du kannst ja einen Verweis darauf anbringen.  Da die Erwartungshaltung
aber ist, dass das Problem eigentlich durch die Trampoline gelöst
werden sollte, muss man den Bugreport wohl nicht bei GCC, sondern bei
den binutils einkippen.  Bitte setz Eric.Weddington (at atmel.com)
mit auf Cc.

von Steffen Graap (Gast)


Lesenswert?

Ich hab den Bug unter folgendem Link angemeldet. Ich hoffe es war die 
richtige Stelle.

https://savannah.nongnu.org/bugs/index.php?28921

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hab's schon gesehen.  Naja, nicht ganz die richtige Stelle, die
avr-libc kann da nicht viel dafür tun.  Ich werde aber mal sehen,
ob ich damit dort erst einmal eine Diskussion lostreten kann, ob
das nun ein Bug in den linker trampolines ist oder nicht (also
ob die trampolines das eigentlich abfangen sollten oder ob das
gar nicht gehen kann).

von Steffen Graap (Gast)


Lesenswert?

Ja, sorry. Ich hab mich schon schwer getan den Bug in englisch da 
reinzuhacken. Die ganze Compiler/Linker ect. Geschichte sind für mich 
böhmische Wälder. Da ich ein Quereinsteiger in die C-Programmierung bin, 
beschäftige ich mich mit den entsprechenden Thematiken erst wenn ich ein 
Problem habe, so wie jetzt.

Der Compiler ist für mich ein Werkzeug, solange er funktioniert, ist es 
mir egal wie er das macht. Erst wenn er seinen Dinst verweigert, muss 
ich in die Innerein. Leider fehlt mir die Zeit, mich damit umfassender 
zu befassen.


Ich denk mal der richtigere Weg wären nicht die Trampolines, sondern 
Funktionspointer entsprechend des benutzten Device 16 oder 22(24)bit 
breit zu machen, analog dem verwendeten Programmcounter.
Welche Variante nun weniger Arbeit bedeutet kann ich nicht sagen.


Betreffs des Workaround mit dem EICALL, werd ich mich wohl ab morgen 
beschäftigen, da mein Programm jetzt nur noch läuft wenn ich alle 
Debugausgaben abschalte. (Codegröße >140k)

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Jörg Wunsch schrieb:
> Ich werde aber mal sehen,
> ob ich damit dort erst einmal eine Diskussion lostreten kann, ob
> das nun ein Bug in den linker trampolines ist oder nicht (also
> ob die trampolines das eigentlich abfangen sollten oder ob das
> gar nicht gehen kann).

Wie ich schon schrieb, ich hatte versucht das nachzustellen(*), und 
hatte keinerlei Probleme mit Funktionszeigern auf Funktionen jenseits 
von 128k. Es wurde brav ein Trampoline angelegt, und der Zeiger verwies 
dann auf dieses. "oder ob das gar nicht gehen kann" fällt also schon mal 
raus. ;-)

(*): Ich habe alles ausprobiert, was mir an Kombinationen einfiel (z.B. 
auch die Zuweisung des Funktionspointer jenseits von 128k gelegt), 
keinerlei Fehler. Ohne kompletten compilierbaren Beispiel-Code wird aus 
dem Bug-Report wohl nichts werden.

von Steffen Graap (Gast)


Angehängte Dateien:

Lesenswert?

Moin

Den kompletten Code kann ich leider nicht zur Verfügung stellen 
(Firmengeheimnis). Ich kann aber ein Versuchsprojekt anlegen, welches 
ich Online stellen kann. Das dauert aber noch.

Vorab erst mal das Modul des Taskmanagers in der die Funktionspointer 
erstellt und benutzt werden.

Gruß Steffen

von Steffen Graap (Gast)


Angehängte Dateien:

Lesenswert?

So, ich habe das Testprojekt feritg, ging schneller als ich gedacht 
habe. Ich habe mal das ganze eclips-Projektverzeichnis gezipt. Dazu noch 
die Compiler/linkerausgabe als Bild.

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Sorry, aber dieses Beispielprojekt ist wertlos.
1
0001f4e4 <u32Fill_Flash_5>:
2
   1f4e4:  78 56 34 12 78 56 34 12 78 56 34 12 78 56 34 12
3
   1f4f4:  78 56 34 12 78 56 34 12 78 56 34 12 78 56 34 12
4
   1f504:  78 56 34 12 78 56 34 12 00 00 00 00 00 00 00 00
5
   ...
6
7
000271e4 <__trampolines_start>:
8
   271e4:  0d 94 24 39   jmp  0x27248  ; 0x27248 <vTestFunktion>
Du hast hier einfach per PROGMEM so viele Daten in das Flash gepumpt, 
dass der Trampoline selber auch jenseits der 128k liegt. Das ist ein 
anderes Szenario, als das im ursprünglichen Code, wo die Trampolines 
deutlich unterhalb liegen:
Beitrag "Re: warning: internal error: out of range error"

von Steffen Graap (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Du hast hier einfach per PROGMEM so viele Daten in das Flash gepumpt,
> dass der Trampoline selber auch jenseits der 128k liegt.

Jup, das hab ich nicht beachtet, ich werd das morgen mal nachbessern.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Kleiner Tipp: um viel Code zu erzeugen, nimmst du dir am besten
eine als "volatile" deklarierte (oder zwei :) Variablen eines
32-Bit-Datentyps, und die summierst du dann (mittels automatisch
generiertem C-Code) kräftig auf.

von Steffen Graap (Gast)


Lesenswert?

Ich hab das Versuchsprojekt mal angepasst, und siehe da, alles läuft 
ohne Probleme wie bei Stefan.

In meinem richtigen Projekt hab ich mal 32k FLASH-Müll eingefügt, und 
nun hab ich 49 out of range error. Warum es im Testprojekt funktioniert, 
und im richtigen Projekt nicht, ist mir ein Rätsel.

Was mir aufgefallen ist, es werden zwar Trampolines für eine Funktion 
angelegt (warscheinlich für einen Aufruf ohne Pointer)
1
1072a:  0d 94 74 23   jmp  0x246e8  ; 0x246e8 <vSetAlarm_LED+0x8c>
hierbei wird aber nicht die absolute Funktionsadresse angesprungen wird. 
Hat bestimmt was mit Optimierung zu tun. Die selbe Funktion 
(vSetAlarm_LED) wird aber auch über die Taskfunktionen (u8Add_Time_Task, 
u8Check_Time_Task und u8Remove_Time_Task) benutzt, und hierfür wird kein 
Trampoline (hier würde die absolute Adreesse benötigt) angelegt.

von Stefan E. (sternst)


Lesenswert?

Steffen Graap schrieb:

> In meinem richtigen Projekt hab ich mal 32k FLASH-Müll eingefügt, und
> nun hab ich 49 out of range error. Warum es im Testprojekt funktioniert,
> und im richtigen Projekt nicht, ist mir ein Rätsel.

Nun, ein wichtiger Unterschied ist das eigene Linkerscript. Lass das 
doch mal auf das Testprojekt los.

von Steffen Graap (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Nun, ein wichtiger Unterschied ist das eigene Linkerscript. Lass das
> doch mal auf das Testprojekt los.

Da hast du zwar recht, aber da der Unterschied in den Linkerscripten nur 
magrinal ist (nämlich nur das einfügen des externen Speichers) hab ich 
es gar nicht erst benutzt. Zum Beweis hab ich im Testprojekt auch das 
Linkerscript benutzt, aber es gibt kein Unterschied.

An Unterschieden zwischen den Projekten fallen mir folgendes ein.
- Anzahl der benutzten Funktionen ~5 gegenüber ~100
- Anzahl der Aufrufe mit Funktionspointerübergaben 6 gegnüber 286
- Anzahl der übergebenen Funktionen 1 gegenüber ~30

von Steffen Graap (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab des Testprojekt mal erweitert. Und der error tritt jetzt auf. 
Ich hoffe ich habe nicht wieder irgendetwas nicht beachtet, denn so 
langsam Platzt mir der Kopf.

Anbei wieder das gezipte eclipse Projekt und die Ausgaben als Bild.

Ich denke das jetzt genügend Informationen zur Verfügung stehen um den 
Bug oder meine Unzulänglichkeit ;-) zu finden.

Gruß Steffen

von Stefan E. (sternst)


Lesenswert?

Tja, dann muss ich mal auf einen meiner ersten Tipps zurückkommen. Mit 
einem "-Wl,--relax" verschwinden die Probleme in deinem Testprojekt. Und 
wenn ich mir den Output weiter oben nochmal genau ansehe, dann hast du 
dort das --relax auch gar nicht an den Linker übergeben ("-Wl," fehlt).

von Steffen Graap (Gast)


Lesenswert?

das -Wl fügt eclipse wohl automatisch mit dazu. Das --relax hatte ich 
drin da es nichts gebracht hat hab ich es wieder entfernt.

Hier das ganze mit b eiden Zusätzem zum Linker.
Muss der Compiler die Zusätze auch bekommen?

Building target: Pointertest.elf
Invoking: AVR C Linker
avr-gcc -Wl,-Map,Pointertest.map -g --relax -mmcu=atmega2560 
-o"Pointertest.elf"  ./Code/funktionen.o ./Code/main.o ./Code/task.o 
./Code/tim.o   -lm
./Code/funktionen.o: In function `vTestFunktion6':
../Code/funktionen.c:63: warning: internal error: out of range error
../Code/funktionen.c:63: warning: internal error: out of range error
./Code/funktionen.o: In function `vTestFunktion7':
../Code/funktionen.c:72: warning: internal error: out of range error
../Code/funktionen.c:72: warning: internal error: out of range error
./Code/funktionen.o: In function `vTestFunktion8':
../Code/funktionen.c:81: warning: internal error: out of range error
../Code/funktionen.c:81: warning: internal error: out of range error
./Code/funktionen.o: In function `vTestFunktion9':
../Code/funktionen.c:90: warning: internal error: out of range error
../Code/funktionen.c:90: warning: internal error: out of range error
Finished building target: Pointertest.elf

von Stefan E. (sternst)


Lesenswert?

Steffen Graap schrieb:
> das -Wl fügt eclipse wohl automatisch mit dazu.

Na, offensichtlich wohl nicht, ...

> Invoking: AVR C Linker
> avr-gcc -Wl,-Map,Pointertest.map -g --relax -mmcu=atmega2560

... oder siehst du hier etwa ein "-Wl," vor dem "--relax"?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

-mrelax sollte auf der Compiler-Kommandozeile auch gehen, der Compiler
übersetzt das dann beim Linken in ein --relax an den Linker.

Allerdings sollte man mittels --relax zwar ggf. kürzeren Code erhalten,
aber eigentlich ist die Option nicht dafür gedacht, Fehler beseitigen
zu helfen.

von Stefan E. (sternst)


Lesenswert?

Jörg Wunsch schrieb:

> Allerdings sollte man mittels --relax zwar ggf. kürzeren Code erhalten,
> aber eigentlich ist die Option nicht dafür gedacht, Fehler beseitigen
> zu helfen.

Gibt es eine Doku zur "Linker Relaxation" bei AVRs?

Wenn ich mir den in der ld-Doku enthaltenen diesbezüglichen Part zu 
68HC11/68HC12 anschaue, gibt es z.B. dort einen Einfluss von --relax auf 
den Themenbereich Adressen/Sprünge/Aufrufe.
Und dass die Tampolines auf der gleichen Seite genannt werden, ist doch 
auch irgendwie "verdächtig". ;-)

http://sourceware.org/binutils/docs/ld/M68HC11_002f68HC12.html#M68HC11_002f68HC12

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan Ernst schrieb:
> Gibt es eine Doku zur "Linker Relaxation" bei AVRs?

Nö.

Du kannst allerdings Recht haben.  Soweit ich mich erinnere, hat
Björn Haase die linker relaxations in der Tat vor den trampolines
implementiert.

von Steffen Graap (Gast)


Lesenswert?

Sorry, das ich mich nich früher gemeldet habe. Der Admin hat den Proxy 
runtergefahren und ich war vom Netz getrennt. Musste also erst mal nach 
Hause, und nach dem Schneeschippen bin ich nu soweit.

Stefan Ernst schrieb:
> Na, offensichtlich wohl nicht, ...
>
>> Invoking: AVR C Linker
>> avr-gcc -Wl,-Map,Pointertest.map -g --relax -mmcu=atmega2560
>
> ... oder siehst du hier etwa ein "-Wl," vor dem "--relax"?

Das löst das Problem, und nicht nur im Testprojekt. Ich dachte das sind 
zwei Zusätze, die nicht zusammen gehören und das Komma sei das 
Trennzeichen.
War also doch meine Unzulänglichkeit.
Ich muss mich wohl doch mehr mit den Innerein des "Werkzeuges" Compiler 
beschäftigen.

Trotzdem nochmals einen herzlichen Dank an alle Beteiligten.

Gruß Steffen

Was passiert jetzt mit dem Bugeintrag?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap schrieb:
> Was passiert jetzt mit dem Bugeintrag?

Den kann ich ja mit Verweis auf -mrelax bzw. -Wl,--relax beruhigt
schließen.  Möglicherweise mach' ich noch einen FAQ-Eintrag draus.

von Steffen Graap (Gast)


Lesenswert?

Moin

Ich bin gerade dabei einen Bootloader zu schreiben. Wenn ich hier den 
Taskmanager nutzen wollte, der ja die Funktionspointer benutzt, hätte 
ich wohl ein Problem. Die "Trampoline-Krügge" funktioniert ja Aufgrund 
der Verschiebung der text.-Section nicht.
Gibt es, oder wird es für diesen Fall eine Lösung geben?

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Verstehe ich nicht ganz, welcher "task manager"?

Ein Bootloader braucht doch normalerweise nur RJMP/RCALL, und einen
einzigen langen EIJMP, mit dem er die Applikation anspringt.  Den
kann man allemal mit der Hand codieren, wenn's sein muss.

von Steffen Graap (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Verstehe ich nicht ganz, welcher "task manager"?

Da muss ich ein wenig weiter ausholen.

Das System besteht aus mehreren Controllern (4 Stück). Einer diese 
Controller hate einen FLASH, der auch vom PC als Massenspeicher benutzt 
werden kann. Auf diesen FLASH wird vom PC eine Datei abgelegt, in der 
die Updatedaten aller Controller enthalten sind. Der Controller hat 
jetzt die Aufgabe den Inhalt der Datei an die anderen Bootloader zu 
verteilen, damit diese das Update durchführten können.
Da hierbei etwas mehr zu tun ist als nur Daten von einem 
Kommunikationsport in den FLASH zu schreiben. Ich wollte mein weiter 
oben erwähnten Taskmanager / Sceduler benutzen um Aufgabe (Task) wie 
z.B. Kommunikationstimeouts, Pollingintervalle ect. zu setzen.
Dieser Taskmanager benutzt Funktionspointer um sich die auszuführende 
Aufgabe zu merken.

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm, kann ich mir gerade zu wenig vorstellen, welche Implikationen
das nun auf die Zeiger hat.  Schlimmstenfalls musst du das halt
wirklich mit inline asm machen.

von Stefan E. (sternst)


Lesenswert?

Die Funktionspointer werden im Bootloader ganz sicher nicht 
funktionieren, da ja auch die Trampolines dann über 128k liegen. Sattle 
doch im Bootloader auf eine Lösung um, die keine Funktionspointer 
benötigt (*). Du könntest z.B. statt dem Pointer eine ID speichern. Und 
statt den Pointer zu dereferenzieren (um die Funktion aufzurufen), rufst 
du eine Dispatcher-Funktion mit dieser ID auf, die dann die eigentliche 
Funktion aufruft.

(*) Ich denke das wird einfacher sein, als zu versuchen, mit Inline-ASM 
im Bootloader die Funktionspointer zum funktionieren zu bringen.

von Steffen Graap (Gast)


Lesenswert?

@ Stefan
so in etwa habe ich mir das auch schon überlegt.

Es Besteht bei mir nicht wirklich ein Problem. Ich habe das Thema hier 
nur nochmals angesprochen, weil die "Trampoline-Krügge" (nicht böse 
gemeint) hier versagt. Wie weiter oben schon angesprochen wäre eine 
Erweiterung der Funktionspionter auf >=22Bit die sichere Lösung die auch 
im Bootloader funktioniert.
Vieleicht kann man ja mal über eine Änderung in entsprechenden Kreisen 
nachdenken.

Gruß Steffen

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steffen Graap schrieb:
> Vieleicht kann man ja mal über eine Änderung in entsprechenden Kreisen
> nachdenken.

"nachdenken" hilft da nicht. ;-)  Wenn sich keiner findet, der die
Zeit (geschätzt Mannmonate bis Mannjahre) investiert, GCC eine
Harvard-Architektur näher zu bringen, die dann innerhalb einer
Architektur verschieden große Zeiger verkraftet, dann kannst du
darüber nachdenken, bis der Arzt kommt.  Ist ein typischer Fall von
Opensource: diejenigen, die das Feature so sehr benötigen, dass sie
ohne dieses nicht mehr weiterarbeiten möchten, müssen letztlich auch
daher kommen und es implementieren.  Die Mainstream-GCC-Entwickler,
die einen i386 oder amd64 ihr eigen nennen, haben doch keinerlei
Motivation, in ein derartiges Feature Aufwand zu stecken.

(Alternative: solche Aktionen wie Google summer of code.)

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.