C++ mit AVR-Dude

OP #1688104
Lesenswert?

Hi

ich möchte gerne von C auf C++ umsteigen. Hierzu habe ich eine main.cpp 
und eine ctest.h erstellt und diese natürlich im Makefile eingetragen. 
Sonst habe ich keine Änderung am Makefile gemacht. Nun mein Problem: Ich 
kann das Programm ohne Fehler compilieren, überspielt hab ich es noch 
nicht auf einen Controller. Ich benutze Programmer´s Notepad und 
AVRDUDE. Nun wird aber jedes mal beim compilieren die Datei main.cpp 
überschrieben und es steht dann plötzlich soetwas drin:

 1                   .file  "ctest.cpp"
   2                 _SREG_ = 0x3f
   3                 _SP_H_ = 0x3e
   4                 _SP_L_ = 0x3d
   5                 _CCP_  = 0x34
   6                 _tmp_reg_ = 0
   7                 _zero_reg_ = 1
   8                   .global __do_copy_data
   9                   .global __do_clear_bss
  17                 .Ltext0:
  18                 .Letext0:
DEFINED SYMBOLS
                            *ABS*:00000000 ctest.cpp
C:\DOKUME~1\.......und so weiter.......

Kann man mit AVRDUDE überhaupt C++ programmieren? Welche Einstellungen 
muss ich noch vornehmen?
#1688160
Lesenswert?

Das Problem liegt am Makefile aus dem Tutorial.

Da steht so etwas drin:
1
CFLAGS += ...
2
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
3
CFLAGS += ...

Das bewirkt, daß mit $(<:.c=.lst) aus dem jeweils aktuellen
C-Quelltext ein Name für das Listing gebildet wird, indem
das ".c" am Ende des Namens abgeschnitten wird und durch
".lst" ersetzt wird.
Zu einem "blabla.c" wird also das Listing "blabla.lst" erzeugt.

Bei einem C++-Quelltext hat man jetzt kein ".c" am Ende, also
wird nichts abgeschnitten und nichts ersetzt und das Listingfile
heißt jetzt genauso wie der Quelltext.
Mit jedem Compilieren überschreibt der Compiler den Quelltext.

Meine Lösung ist, auf das Ersetzen zu verzichten und das
".lst" einfach anzuhängen.
Zu einem "blabla.c" wird also das Listing "blabla.c.lst"
erzeugt, zu "blabla.cpp" entsprechend "blabla.cpp.lst".

Das Makefile müsste also so geändert werden:
1
CFLAGS += ...
2
CFLAGS += -Wa,-adhlns=$<.lst
3
CFLAGS += ...

mfgkw
#1688161
Lesenswert?

Der Vollständigkeit halber vielleicht noch die
weiteren Änderungen, die ich am Makefile vorgenommen habe.

Alt (aus Tutorial):
1
# List C source files here. (C dependencies are automatically generated.)
2
SRC = $(TARGET).c
3

4
...
5

6
CFLAGS += -DF_CPU=$(F_OSC)
7

8
...
9

10
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
11

12
...
13

14
# List any extra directories to look for include files here.
15
#     Each directory must be seperated by a space.
16
EXTRAINCDIRS =
17

18
...
19

20
# Define all object files.
21
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
22

23
...
24

25
# Compile: create object files from C source files.
26
%.o : %.c
27
  @echo
28
  @echo $(MSG_COMPILING) $<
29
  $(CC) -c $(ALL_CFLAGS) $< -o $@ 
30

31

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

36
...
37

38
  $(REMOVE) $(OBJ)
39
  $(REMOVE) $(LST)
40
  $(REMOVE) $(SRC:.c=.s)
41
  $(REMOVE) $(SRC:.c=.d)
42
..

geändert zu:
1
PROJECTNAME=AVR_LCD44780
2

3
...
4

5
# Target file name (without extension).
6
TARGET = $(PROJECTNAME)
7

8
# List C source files here. (C dependencies are automatically generated.)
9
# List C source files here. (C dependencies are automatically generated.)
10
CSRC =  
11
# List C++ files here
12
CPPSRC = $(PROJECTNAME).cpp
13

14
...
15

16
CFLAGS += -DF_CPU=$(F_OSC)
17
CFLAGS += -DNO_STDSTRING -DNO_STDIOSTREAM
18

19
...
20

21
ASFLAGS = -Wa,-adhlns=$<.lst,-gstabs 
22

23
...
24

25
# List any extra directories to look for include files here.
26
#     Each directory must be seperated by a space.
27
EXTRAINCDIRS = .
28

29
...
30

31

32
# Define all object files.
33
OBJ = $(CPPSRC:.cpp=.o) $(SRC:.c=.o) $(ASRC:.S=.o) 
34

35
...
36

37
# Compile: create object files from C source files.
38
%.o : %.c
39
  @echo
40
  @echo $(MSG_COMPILING) $<
41
  $(CC) -c $(ALL_CFLAGS) $< -o $@ 
42

43

44
# Compile: create object files from C++ source files.
45
%.o : %.cpp
46
  @echo
47
  @echo $(MSG_COMPILING) $<
48
  $(CC) -c $(ALL_CFLAGS) $< -o $@ 
49

50

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

55

56
# Compile: create assembler files from C++ source files.
57
%.s : %.cpp
58
  $(CC) -S $(ALL_CFLAGS) $< -o $@
59

60
...
61

62
  $(REMOVE) *~ *.o *.s *.lst

(Die Zeile mit CFLAGS += -DNO_STDSTRING -DNO_STDIOSTREAM macht
Sinn, wenn man meine lcd-Routinen für C++ nimmt.)


Damit wird auch die Zeile:
1
# Define all listing files.
2
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
überflüssig (sie müsste korrekterweise ja auch noch
die SRCPP enthalten) und kann gelöscht werden.
#1688863
Lesenswert?

Habe ich durchaus schon ins Auge gefasst.

Situation: Es geht hier um einen echten Klassiker, der in Tausend
Kopien in Verwendung ist und auf den sich viele beziehen. Dann
erzeugt eine Änderung natürlich auch Reibung, weil irgendwann
jeder sich auf eine andere Version bezieht.
Das spricht nicht gegen eine Änderung, aber gegen eine
relativ unwichtige Änderung.
Mit C funktioniert das Makefile ja hervorragend, und ich gehe
davon aus, daß es nur wenige Leute gibt, die C++ ernsthaft
verwenden. Ich natürlich, aber ich schwatze das niemandem auf.

Zudem denke pfusche ich ungern anderen ins Handwerk, und solange
sich der Ersteller dafür zuständig fühlt, überlasse ich ihm
gern die Entscheidung, was wie zu ändern ist.
Dann mache ich eher mal einen unverbindlichen Vorschlag,
und warte entspannt die Reaktion ab (ähnlich wie gestern
die LCD-Geschichte: einen eindeutigen Fehler bei der
Adressberechnung korrigiere ich kurzerhand; wenn eine
Änderung aber die Benutzung gegenüber früher ändert,
bin ich vorsichtiger).

Vielleicht bin ich auch etwas zu zart besaitet, was
Änderungen angeht, aber es kommt ja nicht auf einen Tag an.

Also auch hier: wenn keiner Bedenken äussert, ändere ich es
nach etwas Vorwarnzeit.


Ich warte...
OP #1689245
Lesenswert?

Seh ich dass richtig... Würde das Makefile dann für C und C++ 
funktionieren? Oder muss ich jedes mal ein anderes Makefile nehmen?

@Klaus Wachter könntest du mir eventuell einfach dein Makefile zur 
verfügung stellen bevor ich da jetzt alles durchgeh und zig Copy-Paste 
Fehler mache?
#1689356
Lesenswert?

Na gut, ich habe mich mal heute abend drüber hergemacht (oder war es 
gestern?).

Zum Einen habe ich meine oben beschriebenen Änderungen drin
(C und C++).
Zum Anderen gleich bei der Gelegenheit die Kommentare etwas
aufgepeppt.
Insbesondere sind alle Stellen, die man zwecks Anpassung
betrachten sollte, mit # ==> und # <== eingerahmt und etwas
ausführlicher kommentiert.

Dieser Stand ist zu finden unter http://mfgkw.dyndns.org/Makefile_kw_cpp

Leider habe ich den ganzen AVR-Kram nur unter Linux installiert,
und selbst da ist die Datei eher knapp getestet (ich muß morgen
früh raus und mal langsam schlafen gehen).

Deshalb die Bitte um Tests, sei es unter Windows, mit C oder
C++ oder einfach nur Lesen der Kommentare, ob sie so verständlich
und sinnvoll sind.
Wenn keine groben Schnitzer mehr drin sind, können wir sie ja
in die freie Wildbahn entlassen.
Morgen werde ich abends auch nochmal damit spielen.

---

Mittelfristig wäre es vielleicht auch sinnvoll, dem gcc-Tutorial
einen Anhang zu spendieren, was bei C++ zu beachten ist und ggf.
mit ein paar Beispielen zu garnieren?

---

Klaus Wachtler schrieb:
> (Die Zeile mit CFLAGS += -DNO_STDSTRING -DNO_STDIOSTREAM macht
> Sinn, wenn man meine lcd-Routinen für C++ nimmt.)

Das soll nicht lcd-Routinen heißen, sondern fixpoint-Bibliothek.
#1689369
Lesenswert?

Thomas Frosch schrieb:
> Seh ich dass richtig... Würde das Makefile dann für C und C++
> funktionieren? Oder muss ich jedes mal ein anderes Makefile nehmen?

Das Makefile muß von Fall zu Fall angepasst werden.
In dieser Form ist die Anpassung für C++ aber ebenso leicht,
wie man bisher einfach die eine oder andere C-Datei in das Projekt
einfügt, nämlich durch Auflisten in einer make-Variablen:
1
# ==> If you have more than one source file then list them here.
2
#
3
# The source file named like the project may be given as $(PROJECTNAME).c
4
# or $(PROJECTNAME).cpp; list the remaining files with their full names
5
# either in the CSRC!
6
# C and C++  dependencies are automatically generated.
7
#
8
# example with one C file:
9
# CSRC = $(PROJECTNAME).c
10
#
11
# example with C file and lcd-routines (cut and paste it together with
12
# lcd-routines.h from mikrocontroller.net):
13
# CSRC = $(PROJECTNAME).c lcd-routines.c
14
#
15
# example with one C++ file:
16
# CSRC = $(PROJECTNAME).cpp
17
#
18
# example with some C++ files (including the main file of the project) and some C files:
19
# CSRC = $(PROJECTNAME).cpp second.cpp third.cpp a.c another.c
20

21
# List C and C++ files here
22
CSRC = $(PROJECTNAME).c
23
# <==

Man schreibt also hinter CSRC = ... einfach alle Dateien, die
als C oder C++ kompiliert werden sollen.
Moderator Persönliche Seite #1689458
Lesenswert?

Klaus Wachtler schrieb:
> Mittelfristig wäre es vielleicht auch sinnvoll, dem gcc-Tutorial
> einen Anhang zu spendieren, was bei C++ zu beachten ist und ggf.
> mit ein paar Beispielen zu garnieren?

Ja, mach mal. ;-)  Es gibt nicht so viele Leute, die aktiv C++ auf
Controllern machen.  Folglich sind für derartige Ergänzungen natürlich
genau diejenigen gefragt, die es auch wirklich in der Praxis benutzen.
#1689535
Lesenswert?

War mir klar :-)

Soviel Praxis habe ich zwar nicht, aber ich fange demnächst mal
damit an (wenn die makefile-Geschichte und lcd-routines vom Tisch
sind und das Wetter nicht zu schön ist, also kommende Woche frühestens).

Trotzdem wäre es nett, wenn jemand mal das obige Makefile unter
Windows probieren würde; ich habe ehrlich gesagt keine Lust
deswegen alles zu installieren.
OP #1690086
Lesenswert?

Hab mein Makefile welches ich oft benutze mal angepasst. Allerdings 
funktioniert es nicht :-(


Schaut so aus.....

Ich kann zwar aus den Fehlermeldungen entnehmen, dass noch einstellungen 
für C drin sind aber weiss nicht in was ich die parameter ändern kann.



> "make.exe" all

-------- begin --------
avr-gcc (WinAVR 20080610) 4.3.0
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is 
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.


Linking: main.elf

avr-gcc -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=16000000UL -Os 
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall 
-Wstrict-prototypes -Wa,-adhlns=main.o  -std=gnu99 -DF_CPU= 
-DNO_STDSTRING -DNO_STDIOSTREAM -Wundef -MMD -MP -MF .dep/main.elf.d 
main.o ctest.o ctest.cpp --output main.elf -Wl,-Map=main.map,--cref 
-lm

cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid 
for Ada/C/ObjC but not for C++

cc1plus.exe: warning: command line option "-std=gnu99" is valid for 
C/ObjC but not for C++

<command-line>: warning: "F_CPU" redefined

<command-line>: warning: this is the location of the previous definition

c:/programme/winavr/bin/../lib/gcc/avr/4.3.0/../../../../avr/bin/ld.exe: 
main.o:  file format not recognized; treating as linker script

c:/programme/winavr/bin/../lib/gcc/avr/4.3.0/../../../../avr/bin/ld.exe: 
main.o:1:  syntax error
make.exe: *** [main.elf] Error 1

> Process Exit Code: 2
> Time Taken: 00:01
Angehängte Dateien:
#1695745
Lesenswert?

Thomas Frosch schrieb:
> cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid
> for Ada/C/ObjC but not for C++
>
> cc1plus.exe: warning: command line option "-std=gnu99" is valid for
> C/ObjC but not for C++

Das habe ich in meiner Vorlage jetzt so geändert, daß es
für C und C++ jeweils getrennte Zusatzflags geben kann.
Diese beiden kommen dann nur bei C zum Zuge.
Siehe http://mfgkw.dyndns.org/AVR/Makefile
OP #1696898
Lesenswert?

Ja richtig. Ich habe davor auch nicht das Makefile von der Tutorial 
Seite verwendet.

Es ist aber in der Zeile...

1
ELFSIZE = $(SIZE) -A $(TARGET).elf

verankert. Ändert man die Zeile in...

1
ELFSIZE = $(SIZE) -A $(TARGET).elf --mcu=$(MCU) --format=avr $(TARGET).elf

dann werden die Prozente angezeigt. Beide Formate gehen aber anscheinend 
nicht.

1
ELFSIZE = $(SIZE) -A $(TARGET).elf --mcu=$(MCU) --format=sysv $(TARGET).elf
ist gleichbedeutend mit
1
ELFSIZE = $(SIZE) -A $(TARGET).elf

es gibt auch noch das Format
1
ELFSIZE = $(SIZE) -A $(TARGET).elf --mcu=$(MCU) --format=berklay $(TARGET).elf

hier wird nur die größe von 'text' ausgegeben. Dafür aber in 
verschiedenen Stellenwertsystemen.

Also danke für die Hilfe!! Habe es aber leider immer noch nicht 
geschafft den Controller selber mal zu testen.
OP #1696922
Lesenswert?

Als ich jetzt mit der Prozentanzeige etwas herumgespielt habe ist mir 
aufgefallen, dass durch das C++ Makefile erheblich mehr speicher 
benötigt wird. Habe folgendes Programm mal genau so und ohne sonstige 
includes etc. für beide Makefiles übersetzen lassen....
1
int main(void)
2
{
3

4
  char fuchs[4] = {0};
5
  fuchs[3] = 77;
6
  
7
  if (fuchs[3] == 5)
8
  {
9
    fuchs[3] = 5;
10
  }
11

12
  return 0;
13
}

und im C++ Fall benötige ich 2300 bytes,
im C Fall nur 104 bytes.

Woran liegt das? Sollte das der Preis für C++ sein überleg ich mir noch 
einmal ob ich wirklich darauf umsteigen will.
Moderator Persönliche Seite #1697710
Lesenswert?

Thomas Frosch schrieb:
> die Optimierung ist in beiden Fällen im Makefile auf s.

Dann machst du noch irgendwas anderes falsch.  Ich bekomme für dein
Beispiel:
1
$ cat > foo.c
2
int main(void)
3
{
4

5
  char fuchs[4] = {0};
6
  fuchs[3] = 77;
7
  
8
  if (fuchs[3] == 5)
9
  {
10
    fuchs[3] = 5;
11
  }
12

13
  return 0;
14
}
15
^D
16
$ avr-gcc -Os -xc -mmcu=atmega1281 -o foo.elf foo.c
17
$ avr-size foo.elf
18
   text    data     bss     dec     hex filename
19
    264       0       0     264     108 foo.elf
20
$ avr-gcc -Os -xc++ -mmcu=atmega1281 -o foo.elf foo.c
21
$ avr-size foo.elf
22
   text    data     bss     dec     hex filename
23
    264       0       0     264     108 foo.elf

Diese 264 Byte sind praktisch nur Interruptvektortabelle und
C-Startup-Code (der ATmega1281 hat ziemlich viele Vektoren).
Moderator Persönliche Seite #1697993
Lesenswert?

...wobei es Zip oder tar+gzip nicht besser machen würden.  Ich habe
dir doch ein minimales Beispiel gezeigt, wenn du nun versuchst, deinen
Klumpen (der ja offenbar so groß ist, dass du dafür extra komplette
Archive anhängen musst) mal auf das notwendige Minimum runterzubrechen,
entweder merkst du dann schon selbst, wo's klemmt, oder du kannst uns
anschließend eine Datei und ein, zwei Kommandozeilen liefern, um das
Problem nachzuvollziehen.
OP #1698468
Lesenswert?

Welchen Klumpen soll ich runterbrechen??? Ich sehe nirgend wo einen 
Klumpen! Ich wollte die Daten nur etwas strukturiert hochladen. Deshalb 
die Archive. Welches Beispiel? Das aus dem 4rt letzten Beitrag? Da sehe 
ich leider nur was du rausbekommst aber hast du es auch mit dem gleichen 
Makefile kompiliert? Woran könnte es dann noch liegen?


Ich habe jetzt für meine main.c und meine main.cpp (jeweils gleicher 
Inhalt) das gleiche Makefile benutzt also das von der Tutorial Seite. 
Hier kommt auch für main.c 104bytes raus und für main.cpp wieder 
2300bytes.

Also der einzige Unterschied ist nur noch .c und .cpp

Wie kann das sein?
Angehängte Dateien:

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