Hallo Liebe Forengemeinde, ich habe ein kleines Problem mit dem µC-programmieren unter Linux. Ich nutze Debian 7 mit gcc 4.7.2. Das Problem klingt recht simpel: Ich habe ein µC Projekt wo ich an einem AtMega8 ein normal 16x2 Display betreiben will. Ich benutze dazu die Anleitung hier aus dem Wiki, also mit den Dateien lcd-routines.c und lcd-routines.h. Das Problem ist nun aber das ich beim kompilieren immer den Fehler bekomme "undefined reference to" bei den "lcd-Befehlen" wie zB lcd_init(); oder lcd_string("");. Ich weiß das es funktioniert wenn ich die beiden Dateien direkt in meine main.c einfüge, doch die feine Art ist das ja wohl nicht. Ich habe trotzdem im Makefile bei "SRC" die lcd-routines.c mit angegeben. Ich habe es mittlerweile Makefiles von verschiedenen Seiten (unteranderem mit der Vorlage und auch mit der Anleitung hier im WIKI) probiert. Ich vermute das trotzdem bei den Makefiles bzw. beim Einbinden der lcd-routines.c der Fehler liegt. Woran kann das liegen? Habe mit Makefiles noch nicht sehr viel Erfahrung bzw. habe nicht sehr oft mit mehreren C-Source-Dateien gearbeite. MfG Hannes
:
Verschoben durch User
Zeig doch mal dein Makefile, alles andere ist wildes Raten ...
Hannes schrieb: > Ich vermute das trotzdem bei den Makefiles bzw. beim Einbinden der > lcd-routines.c der Fehler liegt. dann poste doch mal die Ausgaben von make (vorher make clean machen). eventuell auch das Makefile.
versuch doch erstmal deine sources über die kommandozeile zu kompilieren(ich geh davon aus es sind nicht so viele sources?). Und dann schaust du ob du die Befehle, mit denen du manuell kompiliert hast, so "ähnlich" im makefile findest http://www.ijon.de/comp/tutorials/makefile.html
Das ist die Ausgabe im Terminal
1 | avr-gcc -g -mmcu=atmega8 -Wall -Wstrict-prototypes -Os -mcall-prologues -o launchcontroll.out -Wl,-Map,launchcontroll.map launchcontroll.o |
2 | launchcontroll.o: In function `main': |
3 | /home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:49: undefined reference to `lcd_init' |
4 | /home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:50: undefined reference to `lcd_clear' |
5 | /home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:52: undefined reference to `lcd_setcursor' |
6 | /home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:53: undefined reference to `lcd_string' |
7 | collect2: error: ld returned 1 exit status |
8 | make: *** [launchcontroll.out] Fehler 1 |
Und Das Makefile ist das von hier: http://www.mikrocontroller.net/articles/Beispiel_Makefile
Ich hatte vergessen zusagen: Das Makefile habe ich natürlich an einen atmega8 bei MCU angepasst und den Programmer geändert.
In dem Beispiel-Makefile steht doch drin, dass du alle .c-Dateien auflisten musst. Woher soll "make" denn sonst wissen, welche Dateien es zusammenbauen muss? Irgendwo ist deine main.c aufgelistet. Dahinter trägst du die lcd.c ein und probierst nochmal.
Ja das ist richtig. Hatte aber geschrieben, dass ich das makefile schon angepasst hatte unteranderem auch mit dem eintragen der lcd-routines.c bei "SRC = ..."
1 | # MCU name |
2 | MCU = atmega8 |
3 | |
4 | |
5 | # Processor frequency. |
6 | # This will define a symbol, F_CPU, in all source code files equal to the |
7 | # processor frequency. You can then use this symbol in your source code to |
8 | # calculate timings. Do NOT tack on a 'UL' at the end, this will be done |
9 | # automatically to create a 32-bit value in your source code. |
10 | # Typical values are: |
11 | # F_CPU = 1000000 |
12 | # F_CPU = 1843200 |
13 | # F_CPU = 2000000 |
14 | # F_CPU = 3686400 |
15 | # F_CPU = 4000000 |
16 | # F_CPU = 7372800 |
17 | # F_CPU = 8000000 |
18 | # F_CPU = 11059200 |
19 | # F_CPU = 14745600 |
20 | F_CPU = 16000000 |
21 | # F_CPU = 18432000 |
22 | # F_CPU = 20000000 |
23 | # F_CPU = 8000000 |
24 | |
25 | |
26 | # Output format. (can be srec, ihex, binary) |
27 | FORMAT = ihex |
28 | |
29 | |
30 | # Target file name (without extension). |
31 | TARGET = launchcontroll |
32 | |
33 | |
34 | # Object files directory |
35 | OBJDIR = obj |
36 | |
37 | |
38 | # List C source files here. (C dependencies are automatically generated.) |
39 | SRC = $(TARGET).c lcd.c |
40 | |
41 | |
42 | # List C++ source files here. (C dependencies are automatically generated.) |
43 | CPPSRC = |
44 | |
45 | |
46 | # List Assembler source files here. |
47 | # Make them always end in a capital .S. Files ending in a lowercase .s |
48 | # will not be considered source files but generated files (assembler |
49 | # output from the compiler), and will be deleted upon "make clean"! |
50 | # Even though the DOS/Win* filesystem matches both .s and .S the same, |
51 | # it will preserve the spelling of the filenames, and gcc itself does |
52 | # care about how the name is spelled on its command-line. |
53 | ASRC = |
54 | |
55 | |
56 | # Optimization level, can be [0, 1, 2, 3, s]. |
57 | # 0 = turn off optimization. s = optimize for size. |
58 | # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) |
59 | OPT = s |
60 | |
61 | |
62 | # Debugging format. |
63 | # Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. |
64 | # AVR Studio 4.10 requires dwarf-2. |
65 | # AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. |
66 | DEBUG = dwarf-2 |
wollte das lange ding nicht einfügen aber ok bei mir hab ich die lcd-routines.c als lcd.c gespeichert. Nicht das sich wer wundert das da lcd.c bei SRC steht. Hab alles Unter Debug jetzt für den Beitrag entfernt damit das hier im forum nicht so lang ist.
1 | #include "lcd.h" |
(oder wie die auch immer bei Dir heißt) vergessen in deinem File von wo aus Du die Funktion aufrufst ? Zeig doch bitte das ganze Projekt.
:
Bearbeitet durch User
Marc D. schrieb: > (oder was wie die auch immer heißt) nein, dann kommt ein compiler Fehler und kein Linker Fehler.
1 | //#define F_CPU 8000000UL //the Mega8 runs with the internal Osc.
|
2 | //on 8MHz
|
3 | |
4 | #define F_CPU 16000000UL //external crystal on 16MHz
|
5 | |
6 | #include <avr/io.h> |
7 | #include <util/delay.h> |
8 | #include <avr/interrupt.h> |
9 | #include "lcd-routines.h" |
Hier mal der Kopf von der Hauptdatei ist ja egal wie es heißt habs ja drinnen. Außerdem wenn ich die "lcd.c" in die main einfüge dann klappt es ja ... hab grade ein bißchen gelesen und bin auf die Vermutung Linkerfehler gekommen... könnte da das Problem liegen?
Der Rest des Programms kann es nicht sein dort habe ich zur zeit in der int main(void) nur lcd_init(), lcd_clear(), lcd_setcursor(0,0) und eine ausgabe mit lcd_string("irgendwas") sehen.
Der Linkerfehler kommt daher, dass beim Linken die lcd.o nicht mit der main.o zusammengelinkt wird und daher der Linker die in lcd.o vorhandenen Symbole nicht findet und die Referenzen aus main.o nicht auflösen kann. Das heißt: - obj/lcd.o wird nicht erzeugt ($CC $CFLAGS -c -o lcd.o lcd.c), oder - obj/lcd.o wird nicht eingelinkt ($CC $CFLAGS $LFLAGS -o main main.o lcd.o). Probiere mal "make obj/lcd.o", wenn er dir dann die lcd.o erzeugt, ist es der zweite Fall; andernfalls der erste Fall. In jedem Fall erkennt make die Abhängigkeit zwischen "targetcontroll" und "lcd.o" nicht. (Übrigens schreibt man "control" nicht mit 2 L am Ende.)
Listet man da nicht anstatt der SRC die OBJ-Dateien auf und überläßt es dem make, die entsprechenden Sourcen zu kompilieren? Ich hätte da im Makefile OBJ= .. lcd.o ..
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.