Hallo!
Ich habe einen Linker-Fehler:
Error 2 R_AVR_13_PCREL against symbol `uart_putc' defined in .text
section in uart.o
Die Tipps mit -lm etc. habe ich durch, aber da das Problem ja mit einer
eigenen Datei auftritt, ist das ja ohnehin sinnfrei.
Das Projekt macht so lange keine Querelen, bis ich z.B. in Zeile 158 der
Datei MC35_Steuerung.c eine Rechenoperation einfüge. (im Code schon
getan)
Langsam verzweifle ich mit diesem avr-gcc... :(
Ich kann das problemlos compilieren, sowohl mit -Os als auch -O0,
für einen ATmega16. Es gibt massig Warnungen "discards qualifier
from pointer target type", die haben zwar nichts mit deinem Problem
jetzt zu tun, aber beseitigen solltest du die trotzdem.
Da du keinerlei Makefile oder sonstwas drin hast: wie sieht deine
Compiler-Kommandozeile aus? Da steht ja nichtmal dabei, für
welchen Controller das sein soll.
Das -lm auch an der richtigen Stelle eingefügt (am Ende)? ;-)
Falls das immer noch nicht hilft ist guter Rat teuer. Evtl. die Objekte
beim Linkaufruf anders sortieren so daß entsprechende Module näher
beieinander lokatiert werden. Ist aber nur ein Workaround, der nicht bis
in alle Ewigkeit funktioniert...
Evtl. über ein eigenes Linkerscript.
Johann L. schrieb:> Das -lm auch an der richtigen Stelle eingefügt (am Ende)? ;-)
Ich habe gar kein -lm gebraucht, hat trotzdem funktioniert.
Johann L. schrieb:> Jörg, ist eigentlich geplant, das in der avr-libc zu beheben für die> nächste Release?
Muss ich mal sehen, wie ich die Zeit finde, das alles durchzugehen.
Sinnvoll wäre es schon, ja.
Jörg Wunsch schrieb:> Johann L. schrieb:>> Jörg, ist eigentlich geplant, das in der avr-libc zu beheben für die>> nächste Release?>> Muss ich mal sehen, wie ich die Zeit finde, das alles durchzugehen.> Sinnvoll wäre es schon, ja.
Die avr-libc legt dir Funktionen ja (über 1000 Makros) in eigene
Sections wie .text.avr-libc oder .text.avr-libc.fplib
Wäre es nicht sinnvoller, .text.* im standard ld-Skript zu sortieren, so
daß gleichnamige Input-Sections dicht beisammen liegen? Oder
widerspricht das irgendeinem ABI?
Zum einen ist das einfacher und zum anderen wird der Code besser, da die
RCALLs bleiben können -- vorausgesetzt, die entsprechenden
input-Sections werden nicht zu groß.
Zudem: die avr-libc verwendet Skip über Call, was wegen des Core-Bugs
keine gute Idee ist.
Übrigens gibts in avr-gcc dafür die Builtin-Defines
__AVR_ERRATA_SKIP__
__AVR_ERRATA_SKIP_JMP_CALL__
Allerdings erst ab 4.7.
Ein Problem ist allerdings, daß ich schon gesehen habe, daß die avr-libc
sich z.B. __addsf3 aus der libgcc zieht anstatt aus der avr-libc, und
zwar auch für C.
Jörg Wunsch schrieb:> Da du keinerlei Makefile oder sonstwas drin hast: wie sieht deine> Compiler-Kommandozeile aus? Da steht ja nichtmal dabei, für> welchen Controller das sein soll.
Indirekt hat er schon :)
Das ist ein AS5-Projekt :(
Da steht der ganze Krempel als XML verschlüsselt in der *.avrgccproj.
Ist wohl für einen ATmega16. Bisher anscheinend nur in Debug-Mode (also
mit -O0 -g2) compiled und da auch gegen libm.a gelinkt:
Johann L. schrieb:> Wäre es nicht sinnvoller, .text.* im standard ld-Skript zu sortieren, so> daß gleichnamige Input-Sections dicht beisammen liegen?
Könnte man machen, aber die Bibliothek sollte unabhängig von der
binutils-Version sein.
> Zum einen ist das einfacher und zum anderen wird der Code besser, da die> RCALLs bleiben können -- vorausgesetzt, die entsprechenden> input-Sections werden nicht zu groß.
Eigentlich wäre es mir lieber, wenn die linker relaxations daraus
RCALLs machen. An dieser Stelle ist dann sicher, dass sie immer
auflösbar sind.
> Zudem: die avr-libc verwendet Skip über Call, was wegen des Core-Bugs> keine gute Idee ist.
Sagt mir gerade nichts. Welcher Core-Bug?
... schrieb:> Indirekt hat er schon :)> Das ist ein AS5-Projekt :(
Ich habe da aber beispielsweise keinen MCU-Typ finden können.
<avrgcc.linker.general.NoStartupOrDefaultLibs>True</avrgcc.linker.genera
l.NoStartupOrDefaultLibs>
> <avrgcc.linker.libraries.Libraries>> <ListValues>> <Value>m</Value>> <Value>c</Value>> <Value>gcc</Value>> <Value>c</Value>> </ListValues>
Ich frag' mich, was das soll. Warum denn keine default libs?
> Im Release-Mode wird die libm.a anscheinend nicht gelinkt, zumindest> fehlen entsprechende Eintträge.
Die wird hier auch überhaupt nicht benötigt. Nicht jede Klage über
ein nicht funktionierendes R_AVR_13_PCREL hat ihren Grund in der
fehlenden libm.a, auch wenn das aufgrund der derzeitigen Architektur
einiger libc-Routinen der häufigste Fall ist.
Jörg Wunsch schrieb:> Johann L. schrieb:>>> Wäre es nicht sinnvoller, .text.* im standard ld-Skript zu sortieren, so>> daß gleichnamige Input-Sections dicht beisammen liegen?>> Könnte man machen, aber die Bibliothek sollte unabhängig von der> binutils-Version sein.
Ja, im Idealfalle. Allerdings hat libgcc das gleiche Problem, und da die
binutils-Version nicht bekannt ist, würde das (noch) nichts bringen.
>> Zum einen ist das einfacher und zum anderen wird der Code besser, da die>> RCALLs bleiben können -- vorausgesetzt, die entsprechenden>> input-Sections werden nicht zu groß.>> Eigentlich wäre es mir lieber, wenn die linker relaxations daraus> RCALLs machen. An dieser Stelle ist dann sicher, dass sie immer> auflösbar sind.
Wenn sichergestellt ist, daß ein RCALL tut, ist dagegen ja nix zu sagen.
>> Zudem: die avr-libc verwendet Skip über Call, was wegen des Core-Bugs>> keine gute Idee ist.>> Sagt mir gerade nichts. Welcher Core-Bug?
Skip (CPSE, SB[IR][CS]) über 32-Bit Instruktion macht Probleme, wenn
während der Sequenz eine IRQ auftritt. Dann wird die Return-Adresse
nicht korrekt hergestellt und eine Teil der Instruktion ausgeführt.
Ist wohl ein Grund, warum avr-gcc keine Skips über 32-Bit erzeugt;
libgcc verwendet es allerdings, z.B hier für Builtin FMULSU:
1
;;; r23:r22 = fmulsu (r24, r25) like in FMULSU instruction
2
;;; Clobbers: r24, r25, __tmp_reg__
3
DEFUN __fmulsu
4
;; A0.7 = negate result?
5
mov A0, A1
6
;; FALLTHRU
7
ENDF __fmulsu
8
9
;; Helper for __fmuls and __fmulsu
10
DEFUN __fmulsu_exit
11
;; A1 = |A1|
12
sbrc A1, 7
13
neg A1
14
#ifdef __AVR_ERRATA_SKIP_JMP_CALL__
15
;; Some cores have problem skipping 2-word instruction
Johann L. schrieb:> Skip (CPSE, SB[IR][CS]) über 32-Bit Instruktion macht Probleme, wenn> während der Sequenz eine IRQ auftritt. Dann wird die Return-Adresse> nicht korrekt hergestellt und eine Teil der Instruktion ausgeführt.
Das betrifft doch aber nur die ganz ganz alten Classic-AVRs (AT90S,
ATmega103), die verwendet doch eh keiner mehr.
Peter
Jörg Wunsch schrieb:> Ich habe gar kein -lm gebraucht, hat trotzdem funktioniert.
Dann wird eben die nicht optimierte float-Lib genommen. Die verbraucht
264Byte SRAM und etwa 4kB Flash mehr.
Peter
Peter Dannegger schrieb:>> Ich habe gar kein -lm gebraucht, hat trotzdem funktioniert.>> Dann wird eben die nicht optimierte float-Lib genommen.
Wie kommst du darauf?
Guckt ihr euch denn das Zeug wenigstens mal an, was die Leute posten?
Da taucht kein einziges Mal das Wort "float" oder "double" drin auf!
Das Problem hier hat mit der libm.a rein gar nichts zu tun.
Jörg Wunsch schrieb:> Guckt ihr euch denn das Zeug wenigstens mal an, was die Leute posten?
Guckst Du Dir immer alles komplett an?
Jörg Wunsch schrieb:> Da taucht kein einziges Mal das Wort "float" oder "double" drin auf!
Da der OP davon sprach, war ich selbstverständlich davon ausgegangen,
daß er float benutzt.
Peter
Peter Dannegger schrieb:> Johann L. schrieb:>> Skip (CPSE, SB[IR][CS]) über 32-Bit Instruktion macht Probleme, wenn>> während der Sequenz eine IRQ auftritt. Dann wird die Return-Adresse>> nicht korrekt hergestellt und eine Teil der Instruktion ausgeführt.>> Das betrifft doch aber nur die ganz ganz alten Classic-AVRs (AT90S,> ATmega103), die verwendet doch eh keiner mehr.>> Peter
Ob die Devices alt sind oder nicht spielt keine Rolle. Die Devices
werden von der Toolchain unterstützt, und das ist das einzige Kriterium,
das zählt.
Johann L. schrieb:> Ob die Devices alt sind oder nicht spielt keine Rolle. Die Devices> werden von der Toolchain unterstützt, und das ist das einzige Kriterium,> das zählt.
Man muß aber deswegen nicht Leute in Angst und Schrecken versetzen, die
MCs einsetzen, die man auch kaufen kann.
Ich sehe auch keinen Grund, solchen Support für die libgcc jetzt noch
nachträglich einzupflegen. Da sollte man eher diese Oldies aus der Liste
streichen.
Peter
Peter Dannegger schrieb:> Johann L. schrieb:>> Ob die Devices alt sind oder nicht spielt keine Rolle. Die Devices>> werden von der Toolchain unterstützt, und das ist das einzige Kriterium,>> das zählt.>> Man muß aber deswegen nicht Leute in Angst und Schrecken versetzen, die> MCs einsetzen, die man auch kaufen kann.
Ich hab lediglich darauf hingewiesen, daß skip über RJMP/RCALL in der
avr-libc an einigen Stellen verwendet wird und daß darauf zu achten ist,
falls RJMP/RCALL durch JMP/CALL ersetzt wird.
> Ich sehe auch keinen Grund, solchen Support für die libgcc jetzt noch> nachträglich einzupflegen. Da sollte man eher diese Oldies aus der Liste> streichen.
Da wurde nichts "nachträglich" eingepflegt. Die libgcc hat jetzt einige
Optimierungen, die sie früher nicht hatte. Und diese verwenden Skip
über RCALL/CALL und daher auch einen Workaround für's Skip-Erratum falls
notwendig. Oder genauer: falls nicht geschlossen werden kann, daß der
Workaround nicht notwendig ist.
Wie gesagt: Ob ein µC "alt" oder "neu" ist, gerade en Vogue oder nicht,
ist für mich da nicht die Messlatte. Ich sehe auch nicht, warum ein
Devices nicht mehr supported werden sollten, nur weil sie "unbequem"
sind.
Johann L. schrieb:> Ich hab lediglich darauf hingewiesen, daß skip über RJMP/RCALL in der> avr-libc an einigen Stellen verwendet wird und daß darauf zu achten ist,> falls RJMP/RCALL durch JMP/CALL ersetzt wird.
Jettz habe ich zumindest verstanden, worum's dir geht.
Das macht leider die Änderung natürlich etwas schwieriger. Wird
wohl darauf hinauslaufen, dass man die avr-libc noch mehr splitten
müsste, um dann separate Builds für die alten AT90-Devices zu
haben. Diese wiederum bleiben bei ihren RCALLs (auch auf die Gefahr
hin, einen Linkerfehler zu generieren), alle anderen können auf
CALL umgestellt werden (mit der Option, dass die linker relaxations
das dann wieder zurückdrehen).
Allerdings hätte wiederum eine solche Änderung zur Folge, dass der
Compiler die Unterscheidung der zu benutzenden Library jenseits des
bisherigen Schemas vornehmen müsste.
Klingt alles nicht danach, als könnte man das schon in der nächsten
avr-libc-Version implementieren, aber wir sollten das dann eher dort
auf der Mailingliste diskutieren.
Jörg Wunsch schrieb:> Johann L. schrieb:>> Ich hab lediglich darauf hingewiesen, daß skip über RJMP/RCALL in der>> avr-libc an einigen Stellen verwendet wird und daß darauf zu achten ist,>> falls RJMP/RCALL durch JMP/CALL ersetzt wird.>> Jettz habe ich zumindest verstanden, worum's dir geht.>> Das macht leider die Änderung natürlich etwas schwieriger. Wird> wohl darauf hinauslaufen, dass man die avr-libc noch mehr splitten> müsste, um dann separate Builds für die alten AT90-Devices zu> haben. Diese wiederum bleiben bei ihren RCALLs (auch auf die Gefahr> hin, einen Linkerfehler zu generieren), alle anderen können auf> CALL umgestellt werden (mit der Option, dass die linker relaxations> das dann wieder zurückdrehen).
Laut Atmel betrifft der Silicon-Bug lediglich AT90S8515 (avr2) und
ATmega103 (avr31). avr2 hat kein CALL und in avr31 ist ausser ATmega103
nur der AT43USB320. Die avr-libc braucht es also nur für avr31 zu
beachten und die Überschätzung ist erträglich. Skip über LDS/STS sind
mir bisher noch keine begegnet in der avr-libc und ich wüsste auch
nicht, wozu man LDS/STS in einer libc bräuchte.
> Allerdings hätte wiederum eine solche Änderung zur Folge, dass der> Compiler die Unterscheidung der zu benutzenden Library jenseits des> bisherigen Schemas vornehmen müsste.
Du meinst eine Auffächerung der Multilibs? Das wollte ich auf jeden
Fall vermeiden. Zum einen scheint mir das nicht angemessen für das
Problem (s.o.) und zum anderen ist avr-libc leider nicht Multilib-fähig,
d.h. sie unterstützt keinen In-Tree-Build wie z.B. newlib.
Oder wird zur Build-Zeit die Multilib-Struktur von avr-gcc abgefragt
mittels -print-multi-directory bzw. -print-multi-lib, so daß sie eine
Änderung der Multilib-Struktur automatisch mit abbildet?
> Klingt alles nicht danach, als könnte man das schon in der nächsten> avr-libc-Version implementieren, aber wir sollten das dann eher dort> auf der Mailingliste diskutieren.
So...nach einem völlig dichten Wochenende habe ich jetzt alles probiert
und auch die Warnings beseitigt. Trotzdem bleibt der Fehler. Hier mal
die Zeile, in der das auftritt:
>"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" >-Wl,-nostdlib -mmcu=atmega16 -Wl,-Map=MC35_Steuerung.map -o MC35_Steuerung.elf>at_steuerung.o hw_setup.o MC35_Steuerung.o uart.o -Wl,-lm -Wl,-lc -Wl,-lgcc>-Wl,-lc> at_steuerung.o: In function `uart_put_kommando':>H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\Debug/.././at_steuerung.c(5 8,1):>R_AVR_13_PCREL against symbol `uart_putc' defined in .text section in uart.o
Ich habe auch einmal eine andere Funktion aus der uart.c
auferufen...gleiche Fehlermeldung.
Kann es sein, dass das ein Problem meiner Installation (AVR Studio 5)
ist?
Johann L. schrieb:> Laut Atmel betrifft der Silicon-Bug lediglich AT90S8515 (avr2) und> ATmega103 (avr31).
Das ist ja überschaubar.
> avr2 hat kein CALL und in avr31 ist ausser ATmega103> nur der AT43USB320.
Die sind beide reichlich obsolet. ATmega103 habe ich noch als
Museumsstück in der Kiste :), AT43USB320 wird man ohnehin kaum kaufen
können. Das letzte Mal, dass ich damit jemanden hantieren sah, war
Keith Gudger (damals bei Atmel) vor 8 Jahren.
> Die avr-libc braucht es also nur für avr31 zu> beachten
Ja, OK, das sollte man da als Ausnahme über einen Makro unterbringen
können.
>> Allerdings hätte wiederum eine solche Änderung zur Folge, dass der>> Compiler die Unterscheidung der zu benutzenden Library jenseits des>> bisherigen Schemas vornehmen müsste.> Du meinst eine Auffächerung der Multilibs?
Ja, gewissermaßen.
> Das wollte ich auf jeden> Fall vermeiden.
Ich auch.
> ... zum anderen ist avr-libc leider nicht Multilib-fähig,> d.h. sie unterstützt keinen In-Tree-Build wie z.B. newlib.> Oder wird zur Build-Zeit die Multilib-Struktur von avr-gcc abgefragt> mittels -print-multi-directory bzw. -print-multi-lib, so daß sie eine> Änderung der Multilib-Struktur automatisch mit abbildet?
Nö, sie macht das auf ihre eigene Weise, wobei auch für alle
Eventualitäten vorgesorgt wird. Manche Devices werden daher doppelt
gebaut, weil sie in einer älteren Compilerversion beispielsweise mal
in avr5 waren und jetzt in avr51 sind. Dadurch muss die für das Bauen
der avr-libc benutzte Compilerversion nicht zwingend die gleiche sein
wie die, mit der dann das Projekt gebaut wird.
Steffen K. schrieb:>>"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe">>-Wl,-nostdlib -mmcu=atmega16 -Wl,-Map=MC35_Steuerung.map -o MC35_Steuerung.elf>>at_steuerung.o hw_setup.o MC35_Steuerung.o uart.o -Wl,-lm -Wl,-lc -Wl,-lgcc>>-Wl,-lc>> at_steuerung.o: In function `uart_put_kommando':>>H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\Debug/.././at_steuerung.c( 58,1):>>R_AVR_13_PCREL against symbol `uart_putc' defined in .text section in uart.o
(Statt die Zeilen so ulkig umzubrechen, pack' sowas lieber in eine
[ pre ] ... [ /pre ] Umgebung, die Leerzeichen in den "pre"-tags
dabei weglassen.)
Da fehlen zwar noch als Vergleich die Zeilen, mit denen die C-Dateien
mal compiliert worden sind, aber macht nichts. Ich habe sie jetzt
einfach mal mit -mmcu=atmega16 -std=c99 compiliert, ohne Optimierung
(damit sie möglichst groß werden). Ich kann das Problem leider in
keiner Weise nachvollziehen, weder mit einem ältlichen GCC 4.3.4
noch einem halbwegs aktuellen 4.5.1.
Hast du dir diesen ganzen Quatsch mit -nostdlib eigentlich selbst da
eingebrockt, oder macht AVR Studio 5 das standardmäßig?
> Kann es sein, dass das ein Problem meiner Installation (AVR Studio 5)> ist?
Irgendwie schon. Ich würde mich an deiner Stelle an den Atmel-
Support wenden.
Okay...das mit dem [ pre ] wusste ich nicht.
>Hast du dir diesen ganzen Quatsch mit -nostdlib eigentlich selbst da>eingebrockt, oder macht AVR Studio 5 das standardmäßig?
Das war noch vom Testen...hab ich wieder weg gemacht, aber natürlich
ohne Änderung.
Ich werde das AVR-Studio mal auf einer virtuellen XP-Umgebung
testen...binn gespannt, ob da der gleiche Fehler auftritt. Aber der
Atmel-Support wird auch "genervt"...Verlauf folgt hier.
Hier das gesamte Statement des Output:
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
5
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.0\Vs\AvrGCC.targets" from project "H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\MC35_Steuerung.avrgccproj" (target "Build" depends on it):
6
Task "RunAvrGCC"
7
C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR ToolChain\bin\make.exe all
H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\Debug/.././at_steuerung.c(59,1): R_AVR_13_PCREL against symbol `uart_putc' defined in .text section in uart.o
13
collect2: ld returned 1 exit status
14
make: *** [MC35_Steuerung.elf] Fehler 1
15
Done executing task "RunAvrGCC" -- FAILED.
16
Done building target "CoreBuild" in project "MC35_Steuerung.avrgccproj" -- FAILED.
17
Done building project "MC35_Steuerung.avrgccproj" -- FAILED.
Da fehlt leider immer noch das Erstellen der .o-Dateien (die sind
nämlich bei dir noch da, deshalb baut make sie nicht neu).
Aber: vielleicht postest du einfach nochmal das (von AVR Studio
generierte) Makefile hier als Anhang, dann kann man das auch mal
außerhalb von AVR Studio neu bauen.
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
5
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.0\Vs\AvrGCC.targets" from project "H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\MC35_Steuerung.avrgccproj" (target "Build" depends on it):
6
Task "RunAvrGCC"
7
C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR ToolChain\bin\make.exe all
H:\AVR\Wasser\MC35_Steuerung\MC35_Steuerung\Debug/.././at_steuerung.c(59,1): R_AVR_13_PCREL against symbol `uart_putc' defined in .text section in uart.o
39
collect2: ld returned 1 exit status
40
make: *** [MC35_Steuerung.elf] Fehler 1
41
Done executing task "RunAvrGCC" -- FAILED.
42
Done building target "CoreBuild" in project "MC35_Steuerung.avrgccproj" -- FAILED.
43
Done building project "MC35_Steuerung.avrgccproj" -- FAILED.
Also...es hat definitv etwas mit dem AVR Studio 5 zu tun. In meiner
virtuellen Umgebung mit neuem Projekt-Verzeichnis etc. kommt der gleiche
Fehler. Mal sehen, was der Atmel-Support sagen wird.
Schade, dass sie das generierte Makefile nun mit so viel Schnulli
drin verschlimmbessert haben. Das muss man nun erstmal umfänglich
editieren, bevor man es außerhalb von AVR Studio benutzen kann. :-(
Anyway, jetzt kann ich dein Problem zumindest nachvollziehen:
/tmp/MC35_Steuerung/MC35_Steuerung/build/.././at_steuerung.c:54: relocation truncated to fit: R_AVR_13_PCREL against symbol `uart_putc' defined in .text section in uart.o
6
collect2: ld returned 1 exit status
7
gmake: *** [MC35_Steuerung.elf] Error 1
Das ist mit einem GCC 4.5.1. Wenn ich den GCC 4.3.4 benutze, dann
läuft es durch.
Ich werde mal zusehen, wie man das analysiert bekommt.
Von wem stammt denn das blöde -mshort-calls da drin?
Das ist der Übeltäter.
Eigentlich sollte man für Otto Normalnutzer sämtliche -f- und -m-
Optionen außer -mmcu verbieten. Die sind "für Äggsberden only".
Auch -fpack-struct -fshort-enums sind potenziell gefährlich; die
entsprechende Funktionalität sollte man lieber im Quelltext durch
attribute an den Deklarationen erreichen.
Was dagegen Sinn hätte, wäre beim Linken noch ein -mrelax anzugeben.
Damit werden alle unnötigen langen Aufrufe nachträglich wieder in
kurze umgewandelt.
Super - ich danke Dir! =]
Ich habe definitv nichts an den Optionen gestellt.
Alles das, was in dem makefile steht, ist direkt vom AVR-Studio erstellt
worden.
Aber mal eine Frage zum Verständnis:
Welche Attribute an den Deklarationen meinst Du? Ich möchte gern
sämtliche vermeidbare Fehlerquellen ausschließen.
Ich habe die Option -mshort-calls rausgenommen und die von Dir
empfohlene -mrelax rein - nun funktioniert es.
Für die, die den Fehler evtl. auch einmal haben:
raus_damit
Project-Properties (Alt+F7) - Toolchain - AVR/GNU C Compiler -
Optimization - use rjmp/rcall (limited range) on >8K devices
(-mshort-calls)
rein_damit
Project-Properties (Alt+F7) - Toolchain - AVR/GNU C Linker -
Optimization - Relax Branches (-mrelax)
Steffen K. schrieb:> Ich habe definitv nichts an den Optionen gestellt.
Dann darfst du Atmel einen Bugreport schicken. Die Option sollte dem
Anwender einfach nicht zur Verfügung gestellt werden. Eigentlich
hätte es dem Atmel-Support gebührt, den Aufwand für deine
Fehlerbehebung zu treiben ... damit sie sehen, warum man das dort
nicht haben sollte.
> Aber mal eine Frage zum Verständnis:> Welche Attribute an den Deklarationen meinst Du?
Man kann das Verkürzen von enums auf 8 Bit (wenn möglich) auf zwei
Wegen erreichen beim GCC: entweder global über die
Kommandozeilenoption -fshort-enums, oder indem man den enum selbst
passend deklariert:
1
enum{
2
A,
3
B,
4
C,
5
}__attribute__((packed))variable;
Die Kommandozeilenoption hat dabei den Nachteil, dass sichergestellt
sein muss, dass alle Übersetzungseinheiten, die am Ende miteinander
gelinkt werden, mit gleichen Optionen compiliert worden sein müssen,
ansonsten belegt die Variable "variable" mal ein oder mal zwei Byte in
verschiedenen Objektmodulen.
Sinngemäß gleiches gilt für -fpack-structs, wobei diese Option bei der
AVR-Architektur praktisch überflüssig ist, da der GCC aufgrund der
8-Bit-Architektur ohnehin kein Padding zwischen den einzelnen struct
members einfügt.
Ähliche Betrachtungen gelten auch für --funsigned-char und
-funsigned-bitfields: die Vorzeichenhaftigkeit oder -losigkeit eines
"char" oder bitfields sollte niemals einer bestimmten Annahme des
Programmierers über das Compilerverhalten unterliegen, sondern sie
sollte stets explizit im Code erfolgen, sofern das nötig ist. Die
Typen "char", "signed char" und "unsigned char" sind dabei strikt
getrennt als drei verschiedene Typen zu handhaben, obwohl natürlich
klar ist, dass ein "char" stets entweder wie ein "signed char" oder
wie ein "unsigned char" implementiert wird. Wenn man sich daran hält,
dann braucht man die blöden -f-Optionen auch hier einfach nicht.
Jörg Wunsch schrieb:> Dadurch muss die für das Bauen> der avr-libc benutzte Compilerversion nicht zwingend die gleiche sein> wie die, mit der dann das Projekt gebaut wird.
Momentan ist das allerdings der Fall: Die Bibliotheken müssen mit der
gleichen avr-gcc Version gebaut worden sein, mit der auch die Anwendung
übersetzt wird.
D.h. eine mit 4.6 generierte avr-libc (ober libgcc) in einen 4.7
kopieren oder umgekehrt und es knirscht gewaltig im Gebälk! Grund ist,
daß Funktionsaufrufe, die durch avr.c erstellt werden (also nicht wie
für "normale" Funktionen via calls.c oder optabs.c) teilweise günstigere
Callinterfaces verwendet werden. ZB gibt es Funktionen, die Parameter
in X übergeben wie
Johann L. schrieb:> Grund ist,> daß Funktionsaufrufe, die durch avr.c erstellt werden (also nicht wie> für "normale" Funktionen via calls.c oder optabs.c) teilweise günstigere> Callinterfaces verwendet werden.
Sofern das "nur" die libgcc-Funktionen betrifft, ist das in Ordnung
(allerdings sollten wir dann schnellstens sehen, dass wir die
Ersatzfunktionen aus der avr-libc raus bekommen). Die libgcc ist
Bestandteil des Compilers und muss daher nicht zwischen den Versionen
portabel sein.
Für "echte" libc-Funktionen jedoch würde es bedeuten, dass dies eine
API-Änderung ist.
Jörg Wunsch schrieb:> Johann L. schrieb:>> Grund ist,>> daß Funktionsaufrufe, die durch avr.c erstellt werden (also nicht wie>> für "normale" Funktionen via calls.c oder optabs.c) teilweise günstigere>> Callinterfaces verwendet werden.>> Sofern das "nur" die libgcc-Funktionen betrifft, ist das in Ordnung> (allerdings sollten wir dann schnellstens sehen, dass wir die> Ersatzfunktionen aus der avr-libc raus bekommen).
Welche "Ersatzfunktionen"?
> Die libgcc ist> Bestandteil des Compilers und muss daher nicht zwischen den Versionen> portabel sein.
So einfach ist's leider nicht: Nehmen wir zB parity oder clz, die in <=
4.6 in C implementiert sind. In 4.7 jedoch in Assembler und von denen
avr-gcc die genaue Registerverwendung kennt (ebenso wie bei den bereits
länger vorhandenen div, mul etc.). Wenn man nun mit altem Compiler
erzeugten Code gegen solchen vom neuen Compiler linkt, geht das idR
schief, weil der neue Code davon ausgeht, daß Werte in bestimmten
call-clobbered Registern erhalten bleiben.
Für alle asm-Funktionen der libgcc das Standard-Interface anzunehmen
führt also zu schlechterem Code, und so gesehen wirk sich dieses
Interface von Funktionen, die nur von avr-gcc zur libgcc aufgerufen
werden, auf jeden Code aus: gegen die libgcc wird ja erst zur gleichen
Zeit gelinkt wie die libc auch.
> Für "echte" libc-Funktionen jedoch würde es bedeuten, dass dies eine> API-Änderung ist.
Hier muss man abwägen, ob das obige Verhalten akzeptablel ist, d.h. ist
die Priorität
A: Codegüte oder
B: Interlinkfähigkeit zwischen verschiedenen avr-gcc Versionen.
B würde bedeuten, Optimierungen wie die obige nie machen zu
können/dürfen.
A wird zum Problem, wenn eine Library unabhängig von avr-gcc
distrubutiert wird. Hier müsste dann eine Versionierung zumindest nach
avr-gcc Version erfolgen.
Zudem gibt es ABI-Änderung durch PR18145:
http://gcc.gnu.org/PR18145
d.h. wenn man alle Daten der Applikation in Sektions hat die weder mit
.data noch mit .rodata noch mit .bss beginnen sucht man wahrscheinlich
ne Zeit lang...
Aber all das sollte in die GCC release notes für die 4.7 rein.
Johann L. schrieb:> Welche "Ersatzfunktionen"?
Die, die eigentlich in die libgcc gehören, aber aus hysterischen
Gründen in der avr-libc reimplementiert worden sind. Ich hätte
die da lieber heute als morgen gern raus, wenn's nur möglich
wäre. Die bereiten doch an dieser Stelle nichts als Ärger.
> Hier muss man abwägen, ob das obige Verhalten akzeptablel ist, d.h. ist> die Priorität> A: Codegüte oder> B: Interlinkfähigkeit zwischen verschiedenen avr-gcc Versionen.
Ganz eindeutig B. Alles andere verhindert es, dass man compilierte
Bibliotheken weitergeben kann.
> B würde bedeuten, Optimierungen wie die obige nie machen zu> können/dürfen.
Richtig, mit einer Ausnahme: die libgcc.a selbst. Diese ist de
facto ein Bestandteil des Compilers, d. h. bei einer korrekten
Installation darf der Compiler zu Recht annehmen, dass die libgcc.a,
gegen die er linkt, zu seiner eigenen Version passt. Das ABI
zwischen Compiler und den Funktionen der libgcc.a ist gewissermaßen
"privat" für den Compiler — im Gegensatz zur Parameterübergabe an
Funktionen, von denen der Compiler nicht mit Sicherheit wissen kann,
dass sie mit der aktuellen Version erzeugt worden sind.
> A wird zum Problem, wenn eine Library unabhängig von avr-gcc> distrubutiert wird. Hier müsste dann eine Versionierung zumindest nach> avr-gcc Version erfolgen.
Ja, außerdem sollten die ABIs in der avr-libc-FAQ (der einzigen
Stelle, an der das ABI derzeit überhaupt dokumentiert ist)
entsprechend erwähnt werden.
Es kann ja schließlich auch mal passieren, dass jemand eigene
Assemblerfunktionen dazu linken will, die müssen ja eine geänderte
Aufrufreihenfolge ebenfalls kennen.
Generell würde ich ABI-Änderungen nur zur Erzeugung geringfügig
besseren Codes ablehnen. Sowas macht man nicht, denn es verursacht
letztlich endlosen Supportaufwand.
> Zudem gibt es ABI-Änderung durch PR18145:> http://gcc.gnu.org/PR18145> d.h. wenn man alle Daten der Applikation in Sektions hat die weder mit> .data noch mit .rodata noch mit .bss beginnen sucht man wahrscheinlich> ne Zeit lang...
Nein, das ist keine Änderung, das ist nur der Zustand, wie er hätte
schon immer sein sollen.
Wer sich nonstandard sections ausdenkt, der muss auch wissen, was er
tut, warum er das tut, und wie er sicherstellt, dass das Ergebnis
dann auch korrekt wird.
> Aber all das sollte in die GCC release notes für die 4.7 rein.
Falls es wirklich ABI-Änderungen gibt, die außerhalb der libgcc.a
zum Tragen kommen, dann bitte ich hier dringend, diese nochmal zu
überdenken.
Wir sollten das aber nicht in diesem gekaperten Thread diskutieren,
sondern auf avr-libc-dev oder avr-gcc-list.
Jörg Wunsch schrieb:> Ich habe da aber beispielsweise keinen MCU-Typ finden können.
Steht ziemlich am Anfang:
1
<avrdevice>ATmega16</avrdevice>
Das mit den short calls steht da übrigens auch, aber nur in der
Debug-Version. Die Release-Variante hätte er also wahrscheinlich
fehlerfrei compilieren können.
Ick. Wenn ich sehe, dass jemand einen solch dubiosen Schalter in
einer IDE "nach außen verdrahtet", dann überlege ich mir, ob ich
nicht schnellstens einen Bugreport beim GCC einereichen sollte, der
diese Option zu entfernen auffordert. Diese Option hat doch weit
weniger praktischen Nährwert als -mint8. Naja, wenigstens erzeugt
sie nicht stillschweigend kaputten Code, sondern nur einen
Linkerfehler.
Sie hätten sie statt "optimization" besser "confusion" nennen sollen.
Jörg Wunsch schrieb:> statt "optimization" besser "confusion"
Wohl wahr :)
Eigentlich mag ich die MSVS und den gcc auch. Was Atmel da allerdings
beim AS5 verzapft hat, kann man im Moment wohl nur in die Tonne treten.
Ich hatte es nur einmal installiert. Nachden ich dann erstmal mein
ebenfalls installiertes VS2005 reparieren durfte, hab ich es wieder
runtergeschmissen. Worauf das VS2005 wieder kaputt war :(
Seitdem fas ich das Ding nichtmal mehr mit der Kneifzange an.