avr-g++ Klasse, programm zu klein

Gast #1795319
Lesenswert?

Hallo,

ich möchte gerne eine Klasse schreiben, bzw. bereits getan.

Die Klasse (zum Ansteuern einzellner oder mehrerer LCDs) erscheint mir 
sehr korrekt, es gibt keine Fehler beim Kompillieren und der Code hat 
als C Variante (also ohne Klasse) funktioniert.

Das Problem ist: nach Erstellung des Programms ist die .hex Datei für 
den Programmspeicher nur etwa 189 Bytes groß und das ist definitiv zu 
wenig.

Ich hab's probiert und das "Programm" läuft nicht.


Ich benutze idR Makefiles, würde aber auch die Kommandozeile benutzen, 
würde ich denn die korrekten Optionen für meinen Fall wissen.


Hier mal das Makefile (von Avr Studio):
1
###############################################################################
2
# Makefile for the project lcd-class
3
###############################################################################
4

5
## General Flags
6
PROJECT = lcd-class
7
MCU = atmega8
8
TARGET = lcd-class.elf
9
CC = avr-gcc
10

11
CPP = avr-g++
12

13
## Options common to compile, link and assembly rules
14
COMMON = -mmcu=$(MCU)
15

16
## Compile options common for all C compilation units.
17
CFLAGS = $(COMMON)
18
CFLAGS += -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
19
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 
20

21
## Assembly specific flags
22
ASMFLAGS = $(COMMON)
23
ASMFLAGS += $(CFLAGS)
24
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
25

26
## Linker flags
27
LDFLAGS = $(COMMON)
28
LDFLAGS +=  -Wl,-Map=lcd-class.map
29

30

31
## Intel Hex file production flags
32
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
33

34
HEX_EEPROM_FLAGS = -j .eeprom
35
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
36
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
37

38

39
## Objects that must be built in order to link
40
OBJECTS = lcd-class.o 
41

42
## Objects explicitly added by the user
43
LINKONLYOBJECTS = 
44

45
## Build
46
all: $(TARGET) lcd-class.hex lcd-class.eep lcd-class.lss size
47

48
## Compile
49
lcd-class.o: ../lcd-class.cpp
50
  $(CPP) $(INCLUDES) $(CFLAGS) -c  $<
51

52
##Link
53
$(TARGET): $(OBJECTS)
54
   $(CPP) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
55

56
%.hex: $(TARGET)
57
  avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@
58

59
%.eep: $(TARGET)
60
  -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
61

62
%.lss: $(TARGET)
63
  avr-objdump -h -S $< > $@
64

65
size: ${TARGET}
66
  @echo
67
  @avr-size -C --mcu=${MCU} ${TARGET}
68

69
## Clean target
70
.PHONY: clean
71
clean:
72
  -rm -rf $(OBJECTS) lcd-class.elf dep/* lcd-class.hex lcd-class.eep lcd-class.lss lcd-class.map
73

74

75
## Other dependencies
76
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)


Das ist jetzt die Standard kompilliermethode für C Programme, ich weiß 
nicht ob man bei C++ andere Flags braucht.


Vielleicht gibt's ja hier den Ein oder Anderen, der selbst in C++ 
entwickelt und mir weiterhelfen kann. :)


Danke schonmal :)

Gruß Marcel
Moderator Persönliche Seite #1795482
Lesenswert?

Was ist denn genau im Binary angekommen?  Hast du's mal disassembliert
oder dir wenigstens die Symboltabelle angesehen?

Btw., {UNIX|GNU} make benutzt per Konvention CXX für den C++-Compiler
und CXXFLAGS für die Compileroptionen dafür.  CPP ist der
C-Präprozessor, CPPFLAGS sind die Optionen für das Präprozessieren.
Spielt bei explizit geschriebenen Regeln zwar keine große Geige, aber
man tut im Allgemeinen gut daran, sich an Konventionen zu halten, weil
das am wenigsten Verwirrung stiftet auf Dauer.
Gast #1796418
Lesenswert?

so, Problem gelöst.

(ja: ich hatte in dem Programm auch ein Objekt von der Klasse erstellt)

woran es lag, weiß ich nicht genau, aber ich nehme an es lag daran, dass 
ich Klasse und Methoden alles in einer .h Datei hatte.

Nach dem ich Klasse und Methoden in .h und .cpp aufgeteilt hatte lief es 
dann.


Danke trotzdem :)

Marcel
Moderator Persönliche Seite #1796595
Lesenswert?

Marcel schrieb:
> woran es lag, weiß ich nicht genau, aber ich nehme an es lag daran, dass
> ich Klasse und Methoden alles in einer .h Datei hatte.

»ich nehme an...«

Assumptions are the root of all evil.

Eine .h-Datei wird durch den Präprozessor genau an der Stelle
reingezogen, wo das #include steht.  Was da drin steht, ist dem
Präprozessor sche***egal, und der Compiler guckt sich nur an, ob
das gültiger C++-Code ist (der bekommt zwar noch eine Info darüber,
dass das aus einem .h stammte, aber die ist nur dafür da, damit er
den Debugger entsprechend leiten kann, sonst interessiert den das
nicht).

Zwar ist es nicht sinnvoll, die komplette Implementierung der Klasse
in eine .h-Datei zu packen (abgesehen von inline-Implementierungen
natürlich), aber solange die .h-Datei nicht von mehreren .cpp-Dateien
reingezogen wird, sollte das keinen Unterschied für den Compiler
ergeben.  In letzterem Falle würdest du aber nicht zu wenig an
Implementierung "sehen", sondern zu viel, d. h. der Linker müsste
sich dann beklagen, dass er bestimmte Dinge zweimal bekommen hat.
#1796643
Lesenswert?

Jörg Wunsch schrieb:
> Zwar ist es nicht sinnvoll, die komplette Implementierung der Klasse
> in eine .h-Datei zu packen (abgesehen von inline-Implementierungen
> natürlich), aber solange die .h-Datei nicht von mehreren .cpp-Dateien
> reingezogen wird, sollte das keinen Unterschied für den Compiler
> ergeben.

Ausser der Header wurde irgendwann mal als Kopie von einem anderen 
angelegt und dabei vergessen, den Header-Guard anzupassen. Das kann dann 
zu den lustigsten Effekten führen ;-)

Andreas
Gast #1798026
Lesenswert?

Dann war das anscheinend bei mir das Problem.

Ich hatte noch ein anderes Projekt mit der header Datei.
Wenn ich einen Fehler im aktuellen Programm hatte (beim Kompillieren) 
und bin dann zum Problem gesprungen, war ich plötzlich in der 
gleichnamigen header Datei des anderen Projekts.
Habe ich kein Fehler gemacht, wurde die aktuelle header Datei 
verwendet/kompilliert und alles war problemlos.

War schon merkwürdig und ich wusste echt nicht woran es lag.


Gruß
#1798073
Lesenswert?

Marcel schrieb:
> Dann war das anscheinend bei mir das Problem.

Das lässt sich leicht feststellen:
Benutzt du Include Guards?
Wenn ja, ist dir einer untergekommen, der nicht mit dem 
Dateiinhalt/Dateinamen übereingestimmt hat?


Was auch oft fies ist, sind Include-Pfade die man dem Compiler pauschal 
vorgibt. Da werden dann schon mal includes reingezogen, die man so nicht 
oder von einem ganz anderen Verzeichnis haben wollte.

1 oder 2 Include Pfade sind ok. Ich hab aber auch schon Projekte 
gesehen, bei denen mehr als 20 Include Pfade vorhanden waren, weil die 
verschiedenen Basisfunktionalitäten in entsprechend viele 
Subverzeichnisse aufgeteilt wurden. Da dann nachzuvollziehen, welcher 
include von welchem Verzeichnis kommt, ist eine Sysiphusarbeit.

Moral von der Story: Organisation ist gut. Übertreibt man es aber, dann 
wird sie zum alles behindernden Selbstläufer.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren