PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fehlermeldung beim Compilieren



ikarus_177
19.06.2009, 22:29
Hallo zusammen,

ich wollte nun auch den Umstieg von Bascom auf C wagen, also hab ich mir die neueste WinAVR Version heruntergeladen und installiert.

Ein gaaaanz kurzes "Programm" geschrieben:


#include <avr/io.h>

int main (void)
{
return(0);

}

mit mFile mir ein kleines Makefile zusammengeklickt:


# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------


# MCU name
MCU = atmega32


# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
# Typical values are:
# F_CPU = 1000000
# F_CPU = 1843200
# F_CPU = 2000000
# F_CPU = 3686400
# F_CPU = 4000000
# F_CPU = 7372800
# F_CPU = 8000000
# F_CPU = 11059200
# F_CPU = 14745600
# F_CPU = 16000000
# F_CPU = 18432000
# F_CPU = 20000000
F_CPU = 8000000


# Output format. (can be srec, ihex, binary)
FORMAT = ihex


# Target file name (without extension).
TARGET = main


# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .


# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c


# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =


# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =


# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s


# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2


# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =


# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99


# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL


# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)


# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS



#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)


#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)


#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100


#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)


# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)


MATH_LIB = -lm


# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =



#---------------- External Memory Options ----------------

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff

# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff

EXTMEMOPTS =



#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x



#---------------- Programming Options (avrdude) ----------------

# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500v2

# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep


# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y

# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V

# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v

AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)



#---------------- Debugging Options ----------------

# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)

# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight

# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr

# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit

# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1

# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242

# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost



#================================================= ===========================


# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd


# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:




# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)

# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)


# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d


# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)





# Default target.
all: begin gccversion sizebefore build sizeafter end

# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib


elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)



# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)

end:
@echo $(MSG_END)
@echo


# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf

sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi

sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi



# Display compiler version information.
gccversion :
@$(CC) --version



# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)


# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)

debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause

else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)




# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000



coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof


extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof



# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@

%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0

# Create extended listing file from ELF output file.
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@

# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@



# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)


# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)


# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@


# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@


# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@


# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@


# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@


# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@


# Target: clean project.
clean: begin clean_list end

clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep


# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)


# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)


# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config


und 'make all' versucht. Leider kommt aber stets folgende Meldung als Ausgabe:
main.c:7: fatal error: opening dependency file .dep/main.o.d: No such file or directory

Ich hab schon alles mögliche versucht, im Forum, im Internet gesucht, aber ich komm einfach nicht auf die Ursache drauf.

Der Dateipfad beeinhaltet weder Sonder- noch Leerzeichen, die Dateien liegen direkt auf C:\, ich verwende Vista x64.

Hat jemand irgendeine Idee, woran's noch liegen könnte?

Viele Grüße
ikarus_177

Tob
20.06.2009, 11:26
Hi,

hast du dein Programm auch unter dem Namen "main.c" abgespeichert?

Ansontsten findet der Compiler das Programm das er verarbeiten soll nicht.

MfG Elko

ikarus_177
20.06.2009, 13:48
Hi,

jup, die Datei heißt "main.c", liegt im selben Verzeichnis wie das Makefile, der Dateipfad beeinhaltet weder Sonder- noch Leerzeichen...

Leider trotzdem noch die selbe Fehlermeldung.

Folgende Meldungen schmeißt er heraus:
Compiling C: main.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./main.lst -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o main.o
main.c:6: fatal error: opening dependency file .dep/main.o.d: No such file or directory
compilation terminated.
make.exe: *** [main.o] Error 1

> Process Exit Code: 2
> Time Taken: 00:01


Das liest sich für mich als GNU-C Neuling so, dass er zwar die Codedatei finden kann, aus irgendeinem Grund aber irgendwas nicht findet bzw. erstellen kann...

Kanns vielleicht ein systemspezifisches Problem sein?

Viele Grüße

SprinterSB
20.06.2009, 16:10
Es ist ein Fehler im makefile, kein Problem des Compilers: Der Compiler wird mit einer Datei aufgerufen (.dep/main.o.d), die offenbar nicht existiert.

Tipp: Für den Anfang solltest du deine Makefiles ebenfalls *einfach* halten, und nicht ein Monster mit über 600 Zeilen hernehmen...

Um ein ELF zu erstellen genügt


avr-gcc -mmcu=atmega32 -gdwarf-2 -DF_CPU=8000000UL -Os -fpack-struct -Wall -W -std=gnu99 main.c -o main.elf


und in deinem Falle sogar



avr-gcc -mmcu=atmega32 -Os main.c -o main.elf


Wenn du schon ne Baustelle offen hast (C), mach nicht noch ne zweite auf mit make, das ist ein jungfrauenverschlingender Moloch ;-)

ikarus_177
20.06.2009, 17:09
Hi Georg!

Eigentlich brauche ich bloß das *.hex - File fürs Flashen.

Wenn ich nun in der Kommandozeile
avr-gcc -mmcu=atmega32 -Os main.c -o main.hex eingebe, erstellt er mir ein schönes hex-File auch ganz, ohne dass ein Makefile im Ordner vorhanden wäre.

Ist die Vorgehensweise denn so in Ordnung? Falls ja, brauch ich die Kompilierungsfunktion im Programmer's Notepad und das Makefile ja gar nicht, da würde doch auch ein kleines Batch-File auch reichen (nur zur Erstellung der hex-Datei)?

Viele Grüße

SprinterSB
20.06.2009, 18:23
Hi Georg!

Eigentlich brauche ich bloß das *.hex - File fürs Flashen.

Wenn ich nun in der Kommandozeile
avr-gcc -mmcu=atmega32 -Os main.c -o main.hex eingebe, erstellt er mir ein schönes hex-File auch ganz, ohne dass ein Makefile im Ordner vorhanden wäre.

Ist die Vorgehensweise denn so in Ordnung? Falls ja, brauch ich die Kompilierungsfunktion im Programmer's Notepad und das Makefile ja gar nicht, da würde doch auch ein kleines Batch-File auch reichen (nur zur Erstellung der hex-Datei)?

Viele Grüße

Nein, das ist so nicht in Ordnung. Mit dem Kommando erstellst du eine ELF-Datei mit einer .hex-Endung. -o legt nur den Ausgabename der Datei fast, sonst nichts.

make wird als Build-Tool verwendet. Es ist nicht notwendig, um C-Projekte zu erzeugen. Dennoch findest du zu fast jedem C-Projekt ein Makefile, weil es den Build-Prozess beschleunigen kann. Das trifft aber natürlich nur dann zu, wenn das Makefile korrekt ist.

make ist keine Programmiersprache; wenn man ein Makefiles als Programm ansieht, liegt man fix auf der Nase.

In großen Projekten sind oft viele verschiedene Aufgaben zu lösen, die mit make automatisiert werden können, etwa: Wenn Datei A gebraucht wird und eine Regel besteht, wie A aus einer Datei B erzeugt werden kann, dann erzeuge A neu falls B jünger ist als das alte A.

Shell-Skripte sind nicht so intelligent, sie machen immer mehr oder weniger stupide das gleiche, ohne Abhängigkeiten und Zeitstempel innerhalb eines Projektes zu berücksichtigen. sh-Skripte sind hier also idR ineffizienter, was aber bei einem kleinen Projekt keine Rolle spielt. Vor allem aber sind sh-Skripte (wenn sie nicht ausufern) besser nachvollziehbar als make, weil es im Gegensatz zu Makefiles eine Abfolge von Kommandos darstellt.

GCC selbst kann keine HEX-Dateien erstellen. Er mach die Ausgabe als Assembler-Datei und ruft darauf andere Programme auf. Was er genau macht, sieht du wenn du die Option -v mit angibst. Die Endausgabe ist wie gesagt ein ELF -- egal wie es auch genannt wird.

Das ELF musst du dann mit einem Tool wie avr-objcopy in ein HEX umwandeln. Du kannst zwar auch ein ELF auf den AVR laden, aber das ist nicht ausführbar (zumindest nicht ohne ELF-Loader, der die Umwandlung in Maschinencode übernimmt). In ELF ist noch viel Zeug drin wie Symbol- und Debug-Informationen, die nicht aufn AVR gehören.

Den Inhalt kannst du aber anschauen mit avr-objdump -d foo.elf

Früher gab es bei WinAVR kleine, überschaubare Beispiel in einem Ordner Examples. Heutzutage gibt's nur noch Zeug mit riesigen, zuperkomplexen Makefiles als eiergelende Wollmilchsau die kein Schwanz mehr nachvollziehen kann. Wenn es funzt, schon, wenn nicht, hat man die Asrchkarte weil es nicht zu durchblicken ist für nen Einsteiger wo es hakt und wie man es behebt...

ikarus_177
20.06.2009, 20:26
Hi,

danke für die Antwort!

Ich hab jetzt also meine Datei "main.c" per
avr-gcc -02 -mmcu=atmega32 main.c -o main.elf
in eine *.elf - Datei gewandelt, die dann weiter mit
avr-objcopy -O ihex -j .text -j .data main.elf main.hex
in eine hex-Datei umgewandelt wird.

Ist das nun die "richtige" Vorgehensweise, also das Endprodukt eine "echte" hex-Datei? Per Kommandozeile kann ich dem Compiler ja den Chiptyp übergeben, die Taktfrequenz kann ja im Code auch angegeben werden.

Es wäre halt praktisch, wenn ich den Compiler mit make all direkt aus dem Programmer's Notepad aufrufen könnte, und nicht immer die ganzen Parameter etc. in die Kommandozeile eingeben müsste. Dafür wäre dann ja aber wieder das Makefile nötig?
Gibt es eigentlich sowas wie eine "Mindestanforderung", was alles im Makefile stehen muss, dass sich der Compiler auskennt? Das, was ich ihm auch so schon über die Kommandozeile sage?

Dass das Makfile unbedingt so lang sein muss, wie von mFile vorgeschlagen, kann ich mir nur schwer vorstellen...

Viele Grüße & Danke!
ikarus_177

SprinterSB
21.06.2009, 11:27
Ich hab jetzt also meine Datei "main.c" per
avr-gcc -02 -mmcu=atmega32 main.c -o main.elf
in eine *.elf - Datei gewandelt, die dann weiter mit
avr-objcopy -O ihex -j .text -j .data main.elf main.hex
in eine hex-Datei umgewandelt wird.

Ist das nun die "richtige" Vorgehensweise, also das Endprodukt eine "echte" hex-Datei? Per Kommandozeile kann ich dem Compiler ja den Chiptyp übergeben, die Taktfrequenz kann ja im Code auch angegeben werden.

Ja, das funktioniert. Die Taktfrequenz kann im Code (oder im Makefile oder wo auch immer) angegeben werden, aber verändert wird sie nur durch Umsetzen der Fuses. Die Angaben haben also nur informativen Character für das Programm, das daraus Zeitwerte berechnen kann.


Es wäre halt praktisch, wenn ich den Compiler mit make all direkt aus dem Programmer's Notepad aufrufen könnte, und nicht immer die ganzen Parameter etc. in die Kommandozeile eingeben müsste. Dafür wäre dann ja aber wieder das Makefile nötig?
Nicht unbedingt. Es geht wie gesagt auch ein Skript aus PN aufzurufen oder andere Build-Tools wie Ant zu verwenden. Aber das nur am Rande...


Gibt es eigentlich sowas wie eine "Mindestanforderung", was alles im Makefile stehen muss, dass sich der Compiler auskennt? Das, was ich ihm auch so schon über die Kommandozeile sage?
Die Mindestanforderung an ein Makefile ist, daß es mindestens eine Regel enthält. Im einfachsten Falle sieht ein Makefile also so aus:


rule:

Die Compiler hat mit Makefiles überhaupt nix zu tun (wenn man mal davon absieht, daß zur Generierung von GCC auch Makefiles verwendet werden). Makefiles sind Steuerdateien, die festlegen, wann warum was wie gemacht werden soll.

Ebenfalls hat make überhaupt nix mit GCC zu tun (wenn man mal davon absieht, daß make mit GCC generiert wurde). Makefiles beinhalten lediglich Regeln, die Strings wie "avr-gcc" enthalten können. Es geht aber auch sowas:

.PHONY: all
all:
(explorer)


Die Erzeugung eines Projekts aus Quelle besteht idR aus mehreren Schritten, die in einem Makefile verwaltet werden können. Aber wie gesagt: make ist keine Sprache im eigentlichen Sinne, und ein Makefile wird nicht von oben nach unten abgearbeitet! (Vielleicht beim Einlesen durch make, aber die Aktionen, die erfolgen, haben mit der Reihenfolge wie sie dastehen nix zu tun!)

Im Falle eines AVR-C-Projekten könnten sie Schritte zB sein

Kompiliere C-Quellen nach Assembler (c -> s)
Assembliere Assembler zu Object (S -> o, s -> o)
Linke Objekte zu elf (o -> elf)
Erstelle ein Map-File (elf -> map)
Erstelle ein Listfile (elf -> lst)
Erstelle Intel-HEX-Datei (elf -> hex)
Flashe das IHEX in den µC
Zeige Resourcenverbrauch
Setze Fuses
...



Dass das Makfile unbedingt so lang sein muss, wie von mFile vorgeschlagen, kann ich mir nur schwer vorstellen...
So ist das mit den eierlegenden Wollmilchborstentieren nun mal...

Je weniger Aufgaben es erledigen muss und je weniger allgemeingültig es ist, je simpler das Projekt ist, desto einfacher kann ein Makefile sein. Da mfile versucht, ein möglichst allumfassendes Makefile zu erstellen, ist es entsprechend komplex.

Ich muss gestehen, daß mir das zuviel des Guten ist. Ich benutze nicht gerne Sachen, die schwer zu durchsteigen sind. Ausserdem würde es viele Aufgaben, die ich in meinen Projekten brauche, nicht lösen. Das müsste dann alles reingefrickelt werden. Die Fehlermeldung von oben liest man öfter in Foren, aber ich hab mich nie damit beschäftigt wie man es behebt, da ich kein mfile verwende. Evtl. ein "make clean" oder das Verzeichnis .dep löschen oder ein leeres anlegen...keine Ahnung.

Ich hab also irgendwann mal nen Tag investiert und make-Manuals gelesen, und seither komm ich mit make ganz gut zurande.

Klar, wenn man ein Projekt machen will, möchte man natürlich Ergebnisse auf dem AVR sehen, und nicht mit Zeugs wie make Zeit verschwenden. Allerdings ist es mit make wie mit vielen anderen Tools aus der Unix-Welt auch: ohne Einarbeitung bringt es Frust. Der Ich-Click-Einfach-Mal-Rum-Und-Guck-Was-Passiert-Und-Versteh-Dann-Schon-Was-Abgeht-Ansatz ist eben zu 95% zum Scheitern verurteilt. Standardbeispiel ist TeX bzw. LaTeX, sed oder awk und auch GCC. Aber wenn man sich damit auseinandersetzt, dann hat mehr sehr mächtige Werkzeuge an der Hand.

Ich hab mal ein kleines, ungetestetes Projekt angehängt, das eine LED blinkt. Es macht nicht viel, aber trotzdem sind es schon einige Zeilen. Du kannst es natürlich noch weiter abspecken. Ich hab ein paar Module reingemacht, damit man sieht, die ein C-Projekt aus mehreren Modulen ausgebaut wird. Wenn du von der Console aus make startest, wiest du sehen, daß es nicht immer das gleiche tut, auch wenn der Aufruf der gleiche ist. Gib einfach mal nacheinander ein


make all
make all
make clean
make clean
make timer2.o
make timer2.o
make

Die Abhängigkeiten der kannst du übrigens nachlesen in .depend

ikarus_177
22.06.2009, 12:25
Hallo,

so ein Beispiel ist natürlich ganz was feines, danke dafür!

Werd mich mal mit der ganzen Sache beschäftigen...
Nur so am Rande: kennst du vielleicht einen guten Editor für Linux? Eclipse?

Viele Grüße
ikarus_177

SprinterSB
22.06.2009, 19:35
Eclipse ist mir zu schwergewichtig, mag ich überhaupt net.

Unter Linux verwende ich emacs.

lowtzow
23.06.2009, 18:07
Hallo zusammen,

ich wollte nun auch den Umstieg von Bascom auf C wagen, also hab ich mir die neueste WinAVR Version heruntergeladen und installiert.



wieso installierst du nicht einfach avr studio dazu
hatte so noch nie probleme mit dem makefile



mfg
low

SprinterSB
23.06.2009, 23:09
wieso installierst du nicht einfach avr studio dazu

Das gibt's für Linux?

ikarus_177
24.06.2009, 15:02
Hi,

nach einem kleinen "Ausflug" nach Ubuntu hab ich auch einen kleinen Test auf einem XP-System gemacht. Ergebnis: da funktionierts auch ganz ohne umständliches Batch-File, sogar mit dem mFile - Makefile ;-)

Viele Grüße

SprinterSB
25.06.2009, 19:11
Du kannst ja auch mal fragen in
http://www.mikrocontroller.net/forum/gcc
unter Linux geht's jedenfalls auch mit Makefile. Vielleicht stimmt was anderes nicht. In dem Forum ist auch Jörg Wunsch unterwegs, AFAIK ist mfile von ihm.