Hallo, als Anfänger versuche ich eine Firmware für eine AtTiny25 auf dem Mac zu compilieren. Dazu habe ich ein Makefile und ein "TurntableStrobe.c" File. Das Makefile habe ich an meinen Programmer (ucbasp) angepasst. Wenn ich nun "make -- F_STROBE=60 F_XTAL=12" im Terminal eingebe, erhalte ich folgende Ausgabe und es wurde kein .Hex file erstellt: brankoto@Brankos-iMac-Pro firmware % make -- F_STROBE=60 F_XTAL=12 strobe = 60 Hz xtal = 12 Building target: build/60/12/TurntableStrobe.elf Invoking: AVR C Linker avr-gcc -Wl,-Map,build/60/12/TurntableStrobe.map -mmcu=attiny25 -o "build/60/12/TurntableStrobe.elf" build/60/12/TurntableStrobe.o -lm -Wl,-gc-sections /usr/local/opt/avr-binutils/bin/avr-ld: build/60/12/TurntableStrobe.o: in function `main': TurntableStrobe.c:(.text.startup.main+0x4): undefined reference to `led' /usr/local/opt/avr-binutils/bin/avr-ld: build/60/12/TurntableStrobe.o: in function `.L6': TurntableStrobe.c:(.text.__vector_4+0x3c): undefined reference to `led' collect2: error: ld returned 1 exit status make: *** [build/60/12/TurntableStrobe.elf] Error 1 brankoto@Brankos-iMac-Pro firmware % Was muss ich ggf. tun? Habe Versucht dazu zu lesen, aber überfordert mich noch. Gruß Branko [Edit: Titel korrigiert - Mod.]
:
Bearbeitet durch Moderator
1 | inline void led(const uint8_t on) { |
->
1 | static inline void led(const uint8_t on) { |
Erstmal empfehle ich dir, zu erkennen, dass deine Frage mit avrdude
überhaupt nichts zu tun hat.
> undefined reference to `led'
bedeutet, dass dem Compiler dieser Name unbekannt ist. Allerdings steht
die Funktion led() direkt darüber im Quelltext.
Deswegen habe ich das Projekt mal versucht zu kompilieren, und es hat
auch auf Anhieb geklappt. Ich benutze den avr-gcc in Version 5.4.0 unter
Linux.
Steve van de Grens schrieb: >> undefined reference to `led' > > bedeutet, dass dem Compiler dieser Name unbekannt ist. Nein, das bedeutet, daß dem Linker der Name unbekannt ist. Und das wird an der Optimierung liegen, die die aus Sicht des Compilers nicht genutzte Funktion rausschmeißt. Ungenutzt erscheint sie, weil sie nicht aus main() bzw. einer davon aufgerufenen Funktion heraus aufgerufen wird, sondern nur aus dem Interrupthandler. Der wird auch nur aufgrund der speziellen "Dekoration" als Interrupthandler nicht rausgeworfen.
Harald K. schrieb: > Ungenutzt erscheint sie, weil sie > nicht aus main() ... heraus aufgerufen wird Du meinst diese Stelle?
Steve van de Grens schrieb: > Du meinst diese Stelle? Oh, die. Ja, dann. Dann ist das was anderes. Tja, warum aber findet der Linker die Funktion dann nicht?
Harald K. schrieb: > Tja, warum aber findet der Linker die Funktion dann nicht? Das wüsste ich auch gerne. Mit dem avr-gcc 12.1.0 bekomme ich die gleiche Fehlermeldung, mit dem avr-gcc 5.4.0 (den ich normalerweise benutze) jedoch nicht, der kann das Projekt compilieren.
Hallo, danke für die rege Hilfe. Tatsächlich konnte ich nach weglassen von "inline" alles problemlos compilieren. Hoffe dass ich demnächst verstehen kann warum :) VG Branko
:
Bearbeitet durch User
Steve van de Grens schrieb: > Das wüsste ich auch gerne. Mit dem avr-gcc 12.1.0 bekomme ich die > gleiche Fehlermeldung, mit dem avr-gcc 5.4.0 (den ich normalerweise > benutze) jedoch nicht, der kann das Projekt compilieren. GCC 12 verhält sich standardkonform hinsichtlich inline (und das tatsächliche Verhalten hängt auch noch von der [hier fehlenden] Optimierung ab). Bei GCC 5 gab es sowas noch nicht im Standard, daher war das Verhalten anders. Die korrekte Auflösung wurde bereits in der ersten Antwort im Thread genannt: deklariere die Funktion nicht einfach nur "inline", sondern "static inline". Wen die Details interessieren: Man möge sich dran erinnern, dass in C (leider) alles, was nicht "static" ist auf oberstem Niveau implizit "extern" ist. Laut C-Standard muss in diesem Falle aber dann eben auch eine externe (globale) Funktion mit diesem Namen existieren, damit sie der Linker ggf. finden kann. Wenn man nun (wie der TE) die Optimierung verhindert hat, dann benutzt der Compiler halt eben keine inline-Erweiterung, sondern gibt den Funktionsaufruf ganz normal extern an den Linker weiter. Der wiederum findet aber keine entsprechende Funktionsdefinition. Der zweite Fehler des TE ist es natürlich, keine Optimierungen zu verwenden.
Danke nochmals für die Ausführungen. Falls „TE“ für Thread-Ersteller o.ä. steht: der TE hat den Code so übernommen und gibt die Infos weiter.
Jörg W. schrieb: > das tatsächliche Verhalten hängt auch noch von der > [hier fehlenden] Optimierung ab > Der zweite Fehler des TE ist es natürlich, keine > Optimierungen zu verwenden. Im Makefile steht -Os
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.