Forum: Mikrocontroller und Digitale Elektronik Compile Error AVR MAc


von Branko T. (branko_t)


Angehängte Dateien:

Lesenswert?

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
von MaWin O. (mawin_original)


Lesenswert?

1
inline void led(const uint8_t on) {

->
1
static inline void led(const uint8_t on) {

von Steve van de Grens (roehrmond)


Lesenswert?

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.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

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.

von Steve van de Grens (roehrmond)


Angehängte Dateien:

Lesenswert?

Harald K. schrieb:
> Ungenutzt erscheint sie, weil sie
> nicht aus main() ... heraus aufgerufen wird

Du meinst diese Stelle?

von Harald K. (kirnbichler)


Lesenswert?

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?

von Steve van de Grens (roehrmond)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

Hast Du mal ausprobiert, "inline" wegzulassen?

von Branko T. (branko_t)


Lesenswert?

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
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Branko T. (branko_t)


Lesenswert?

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.

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


Lesenswert?

Branko T. schrieb:
> Falls „TE“ für Thread-Ersteller o.ä. steht

Yup, macht es. :-)

von Steve van de Grens (roehrmond)


Lesenswert?

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

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Steve van de Grens schrieb:
> Im Makefile steht -Os

Im Log-Text allerdings nicht.

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.