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
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
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.
//#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 ..