Forum: Mikrocontroller und Digitale Elektronik C++ mit AVR-Dude


von Thomas F. (tfreal10)


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?

von Klaus W. (mfgkw)


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

von Klaus W. (mfgkw)


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.

von Klaus W. (mfgkw)


Lesenswert?

Andersrum vielleicht einfacher: gleich das
komplette Makefile zum Abändern:
http://mfgkw.dyndns.org/AVR_LCD/Makefile

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Warum aktualisierst du nicht einfach das im Tutorial dann?

von Klaus W. (mfgkw)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Das spricht nicht gegen eine Änderung, aber gegen eine
> relativ unwichtige Änderung.

Da der jetzige Zustand einem ungewollt und unerwartet das Ergebnis
seiner Arbeit zerstören kann, finde ich die Änderung keineswegs
unwichtig.

von Thomas F. (tfreal10)


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?

von Klaus W. (mfgkw)


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.

von Klaus W. (mfgkw)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Klaus W. (mfgkw)


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.

von Thomas F. (tfreal10)


Angehängte Dateien:

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

von Klaus W. (mfgkw)


Lesenswert?

Nachtrag: ich habe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Exkurs_Makefiles#Einleitung
entsprechend ergänzt.
Unter Windows ist das Makefile nach wie vor nicht getestet.
Bei Problemen bitte Hinweis an mich.

von Klaus W. (mfgkw)


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

von Thomas F. (tfreal10)


Lesenswert?

Super Kompilieren hat funktioniert. Auf dem Controller selbst habe ich 
es noch nicht probiert. Also ich habe jetzt, dass Makefile vom Tutorial 
genommen.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Sehe ich jetzt erst.

Thomas Frosch schrieb:
> Kann man mit AVRDUDE überhaupt C++ programmieren? Welche Einstellungen
> muss ich noch vornehmen?

AVRDUDE ist die Programmiersprache egal. Du kannst damit auch die 
Abschrift eines Buches (ASCII) programmieren. Nur wird der Prosessor 
damit nicht klarkommen.

von Klaus W. (mfgkw)


Lesenswert?

Thomas Frosch schrieb:
> Also ich habe jetzt, dass Makefile vom Tutorial
> genommen.

Fein, aber:
Welches hast du jetzt? Das neue, das seit gestern für C++ angepriesen 
wird?

von Thomas F. (tfreal10)


Lesenswert?

Ehh also habs mir heute früh von der Seite runtergeladen. Keine Ahnung 
welches.

In meinem alten Makefile wurde mir am ende auch angezeigt mit wieviel 
Prozent die Speicher belegt sind. Wo muss ich dementsprechende Zeilen 
hinzufügen und wie lauten diese Zeilen?

von Klaus W. (mfgkw)


Lesenswert?

Dann schau doch mal in deinem alten Makefile nach, wo die Ausgabe 
herkommt.

Ich habe bei meiner Änderung diesbezüglich nichts hinzugefügt und
nichts hinweggenommen, soweit ich weiß. Ich bin mir also keiner
Schuld bewusst.

von Thomas F. (tfreal10)


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.

von Thomas F. (tfreal10)


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.

von Klaus W. (mfgkw)


Lesenswert?

hm, ich hatte auch schon mal ein Programm mit C und C++ verglichen
und keinen Unterschied gesehen.

Wenn du es nicht weg bekommst, schaue ich es mir morgen mal an.

Deine Bytes sind Flash, oder was?

von Thomas F. (tfreal10)


Lesenswert?

Jo im Flash. im SRam sind ja keine da ich keine statischen oder globalen 
Variablen habe.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas Frosch schrieb:
> und im C++ Fall benötige ich 2300 bytes,
> im C Fall nur 104 bytes.

Dann schalt mal die Optimierung ein, dann bleibt von beiden Programmen
nichts mehr übrig, weil sie nichts machen.

Wenn du die Optimierung nicht einschaltest/einschalten willst, dann
beschwer dich bitte nicht über Ressourcenverbrauch.

von Thomas F. (tfreal10)


Lesenswert?

die Optimierung ist in beiden Fällen im Makefile auf s.
Und natürlich will ich Optimierung.

Oder muss ich die Optimierung noch irgendwo anders 
"anschalten"/auswählen ???

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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).

von Thomas F. (tfreal10)


Angehängte Dateien:

Lesenswert?

Hab hier mal meine beiden kleinen Testprogramme mit Makefiles und 
avrdude ausgabe im Anhang.

Wie gesagt es sind nicht einmal noch irgendwelche includes drin...


... Gut ich mache was falsch!!! Find ich super, dann ist ja noch 
hoffnung auf weniger Speicher!. Aber was mache ich falsch??

von Klaus W. (mfgkw)


Lesenswert?

Thomas Frosch schrieb:
> Aber was mache ich falsch??

du nimmst rar :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas F. (tfreal10)


Angehängte Dateien:

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?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas Frosch schrieb:
> aber hast du es auch mit dem gleichen
> Makefile kompiliert?

Ich habe die Kommandozeilen mit zitiert, die ich benutzt habe.  Die
solltest du gegen die vergleichen können, die dein Makefile benutzt.

von Thomas F. (tfreal10)


Lesenswert?

Wo und wie soll ich den die zeilen vergleichen? Bzw eingeben???

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
Noch kein Account? Hier anmelden.