Hallo ich beginne gerade mit einem größeren projekt bei dem ich vorhabe einen ATxmega controller mit C++ zu programmiren. Leider musste ich feststellen dass die aktuelle avr-libc version weder meinen controller unterstützt und auch so gut wie keine unterstütung für c++ besitzt. Deswegen die frage, gibts alternativen zu avr-libc? oder muss ich mir im bedarfsvall alles selber patchen. Details: Der controller mit dem ich arbeite ist ein atxmega128a3u. Der letzte versuch mit c++ typte_traits zu arbeiten hat mich dazu gebracht boost ein zu binden, wass leider auch nicht half da weitere header der standard library fehlten. Entwiklungsumgebung Linux(debian)
Wasle schrieb: > Hallo > > ich beginne gerade mit einem größeren projekt bei dem ich vorhabe einen > ATxmega controller mit C++ zu programmiren. Na dann hau rein. > Leider musste ich feststellen dass die aktuelle avr-libc version weder > meinen controller unterstützt und auch so gut wie keine unterstütung für > c++ besitzt. Deswegen die frage, gibts alternativen zu avr-libc? oder > muss ich mir im bedarfsvall alles selber patchen. Da wirste einiges zu tun kriegen. Und mal ehrlich: brauchste das wirklich? Wenn du 'ne UI mit dem Xmega bauen willst, seh ich das ja die Motivation noch irgendwo ein, glaube aber nicht, dass es das rechtfertigen würde. Vielleicht könntest du einfach objektorientiert mit C programmieren? Also im Stile der WinAPI bzw. GDI wo bestimmte Funktionen an bestimmte Handles gebunden sind? > Details: > Der controller mit dem ich arbeite ist ein atxmega128a3u. > Der letzte versuch mit c++ typte_traits zu arbeiten hat mich dazu > gebracht boost ein zu binden, wass leider auch nicht half da weitere > header der standard library fehlten. Mal stlport probiert?
Wasle schrieb: > Der controller mit dem ich arbeite ist ein atxmega128a3u. Die aktuelle Release-Serie von GCC (4.8) unterstützt auch den ATxmega128A3U, ebenso AVR-Libc 1.8.0. > Der letzte versuch mit c++ typte_traits zu arbeiten hat mich dazu > gebracht boost ein zu binden, wass leider auch nicht half da weitere > header der standard library fehlten. > Entwiklungsumgebung Linux(debian) Hier wirst du wohl einiges an Entwichlungsarbeit in avr-g++ stecken müssen. libsupc++ und libstdc++v3 sind vom gcc Build ausgeschlossen wenn dieser mit --target=avr configuriert wird. Du musst also die entsprechenden configure anpassen, alles neu erzeugen und auftretende Fehler beseitigen. Evtl. fehlen auch Teile im avr-Backend selbst, etwa für Exception-Handling.
Falk Schilling schrieb: > Vielleicht könntest du einfach objektorientiert mit C programmieren? Das will man doch nur wenns gar nicht anders geht, in C++ ist das doch viel eleganter und sicherer...
Johann L. schrieb: > libsupc++ und libstdc++v3 sind vom gcc Build ausgeschlossen wenn dieser > mit --target=avr configuriert wird. Du musst also die entsprechenden > configure anpassen, alles neu erzeugen und auftretende Fehler > beseitigen. Evtl. fehlen auch Teile im avr-Backend selbst, etwa für > Exception-Handling. Wir suchen seit 9 Jahren jemanden, der sich mit der Problematik befasst: https://savannah.nongnu.org/people/viewjob.php?group_id=2140&job_id=378 Steht zwar unter avr-libc, bedeutet aber letztlich, dass sich jemand mit genügend Interesse und Kenntnissen im Bereich C++ darum kümmern müsste, dass beides (AVR-GCC und avr-libc) in dieser Hinsicht sauber miteinander spielt.
Also mal danke für die rückmeldungen @Falk Schilling >Vielleicht könntest du einfach objektorientiert mit C programmieren? >Also im Stile der WinAPI bzw. GDI wo bestimmte Funktionen an bestimmte >Handles gebunden sind? Ist für micht nicht wirklich vergleichbar, da ich weniger die Objektorientierung von C++ verwende, sondern in erster linie operator overloading, namespaces, und besonderen Templates. Auch wenn ich zugebn muss dass der Nutzen dieser funktionen in vielen fällen gering ist. @Johann L. >Die aktuelle Release-Serie von GCC (4.8) unterstützt auch den >ATxmega128A3U, ebenso AVR-Libc 1.8.0. Was gcc betrifft kann ich das nur bestätigen. AVR-Libc 1.8.0 http://download.savannah.gnu.org/releases/avr-libc/ Funktionirt bei mir jedoch nicht. Die unterstützen nur 2 verwante controller ATxmega128A3 bzw. ATxmega128A1U. Ich versuche momentan den Controller mit hielfe des Headers iox128a3u.h (kopiert von Atmel Studio) in die library zu integrieren. Leider scheitere ich noch beim update der Configuration (autotools). @Jörg Wunsch Ich werden mir im laufe der woche mal das zusemmanspiel von libsupc++, libstdc++v3, avr-libc und avr-g++ genauer ansehen. Fileicht läst sich da ja wirklich was machen.
Christoph Wiesmeier schrieb: > Ist für micht nicht wirklich vergleichbar, da ich weniger die > Objektorientierung von C++ verwende, sondern in erster linie operator > overloading, namespaces, und besonderen Templates. All das funktioniert doch. Dafür braucht es ja keine Standard-lib, das macht alles der Compiler. Oliver
Oliver schrieb: > Christoph Wiesmeier schrieb: >> Ist für micht nicht wirklich vergleichbar, da ich weniger die >> Objektorientierung von C++ verwende, sondern in erster linie operator >> overloading, namespaces, und besonderen Templates. > > All das funktioniert doch. Dafür braucht es ja keine Standard-lib, das > macht alles der Compiler. In dem Punkt muss ich dir recht geben. Habe aber auch die Standard-library kennen und lieben gelernt. Ich muss auch zugeben dass ich mir nicht sicher bin wie viel tatsächlich ohne dynamischen Speicher geht. Aber besonders bei den Algorithmen habe ich da Hoffnung.
Christoph Wiesmeier schrieb: > @Johann L. >>Die aktuelle Release-Serie von GCC (4.8) unterstützt auch den >>ATxmega128A3U, ebenso AVR-Libc 1.8.0. > > Was gcc betrifft kann ich das nur bestätigen. > AVR-Libc 1.8.0 http://download.savannah.gnu.org/releases/avr-libc/ > Funktionirt bei mir jedoch nicht. Ok, ich hab bisher immer SVN trunk der 1.8.0 verwendet, weil diese einige Bugfixes genenüber der 1.8.0 Release enthält, ohne die eine Distribution mit avr-gcc 4.7+ nicht sinnvoll ist.
Selbst dynamischer Speicher ist ja nicht wirklich ein Problem. Man muß halt eine eigene new- und delete-Implementierung beistellen, dann klappt das auch. Da gibts hier im Forum und auch ausserhalb in den schon mehrfach geführten Diskussionen zum C++ auf dem AVR Vorschläge. Oliver
Johann L. schrieb: > Christoph Wiesmeier schrieb: >> @Johann L. >>>Die aktuelle Release-Serie von GCC (4.8) unterstützt auch den >>>ATxmega128A3U, ebenso AVR-Libc 1.8.0. >> >> Was gcc betrifft kann ich das nur bestätigen. >> AVR-Libc 1.8.0 http://download.savannah.gnu.org/releases/avr-libc/ >> Funktionirt bei mir jedoch nicht. > > Ok, ich hab bisher immer SVN trunk der 1.8.0 verwendet, weil diese > einige Bugfixes genenüber der 1.8.0 Release enthält, ohne die eine > Distribution mit avr-gcc 4.7+ nicht sinnvoll ist. Bist du dir sicher dass der xmega128a3u unterstützt wird. Hab auch im svn etwas herum gesucht und nichts gefunden. http://svn.savannah.nongnu.org/svn/avr-libc/trunk/avr-libc/ scheint ihn nicht zu enthalten. Oder verwendest du ein anderes repo, wenn ja welches?
Wasle schrieb: > einem größeren projekt bei dem ich vorhabe einen > ATxmega controller Tu es nicht. Nimm einen anderen Controller mit den gleichen Specs.
Wasle schrieb: > Der letzte versuch mit c++ typte_traits zu arbeiten hat mich dazu > gebracht boost ein zu binden, Ich muss das jetzt ganz ernsthaft fragen: Weißt du eigentlich, was du tust? Also, hast du echte Erfahrung mit Mikrocontrollern der Größe des Xmegas in einer Freestanding-Umgebung? Weil, dass klingt alles so wie Großer Hacker will es einem kleinen Microcontroller mal so richtig zeigen und die große Welt erklären. Wenn du type_traits bei einem Microcontroller wie dem XMega brauchst, dann hast du entweder den Überblick über deinen Code verloren (ganz schlecht beim Embedded-Programmieren), oder du willst eine Show abziehen um zu zeigen was für cleveren Code du schreiben kannst (der dann zwar schlecht wartbar ist, aber Hauptsache clever und trickreich geschrieben ...). Oben drauf dann noch Boost? Weil? Ja, warum eigentlich? Weil man zuviel Platz in einem uC hat? Weil da ganz tolle, clevere Funktionen drin sind, die man nie-nicht selber, in einfacher, verständlicher, wartbarer, nachvollziehbarer Weise programmieren kann? So wie Template-Metaprogramming (hust, hust)? Weil semi-nichtdeterministische dynamische Speicherverwaltung in einem uC so viel Spaß macht?
Franz schrieb: > Wasle schrieb: >> einem größeren projekt bei dem ich vorhabe einen >> ATxmega controller > > Tu es nicht. Nimm einen anderen Controller mit den gleichen Specs. Tu es nicht. Nimm einen anderen Controller mit deutlich erweiterten Specs ;) Full-Size C++ in der Variante 11 mit allem, was die Sprache hergibt, wird auf Mikro-Mikros nichts. Nimm dir einen ausgewachsenen ARM, und alles wird gut. Oliver
Oliver schrieb: > Full-Size C++ in der Variante 11 mit allem, was die Sprache hergibt, > wird auf Mikro-Mikros nichts. Nimm dir einen ausgewachsenen ARM, und > alles wird gut. C geht aber auch nicht auf AVR's, denn malloc,free,fopen,system gehen auf denen auch nicht so gut. Malte schrieb: > Wenn > du type_traits bei einem Microcontroller wie dem XMega brauchst Was haben type_traits mit der Zielplattform zu tun? Wenn man generischen, wiederverwendbaren Code schreiben möchte sind diese sehr hilfreich. Da sie ja onehin nur zur Compiletime agieren, sind sie nicht vom Speicher des Targets abhängig. Warum sollte zB so eine Hilfsfunktion auf XMega grunsätzlich schlecht sein?
1 | template <typename T> |
2 | stm32_always_inline T mask (const uint8_t count) { |
3 | return (T { 1 } << count) - 1; |
4 | }
|
5 | |
6 | template <typename T> |
7 | using Plain = typename std::remove_reference<typename std::remove_volatile<T>::type>::type; |
8 | |
9 | template <typename T> |
10 | inline void setBits (T& reg, const uint8_t bit, const uint8_t size, const Plain<T> val) { |
11 | const Plain<T> bmask = mask<Plain<T>> (size); |
12 | const Plain<T> base = reg & ~(bmask << (size * bit)); |
13 | reg = base | (val << (size * bit)); |
14 | }
|
15 | |
16 | int main () { |
17 | // Setze Bits 7-9 vom Register auf 5.
|
18 | setBits (someHardwareRegister, 7, 3, 5); |
19 | }
|
So kann man im User-Code recht praktisch einzelne Bits von Registern setzen, unabhängig von der Registergröße. Dank inline und Compiler-Optimierungen wird das auch schön kurz und effizient. Dabei werden C++11 Features und type_traits verwendet. Warum habe ich jetzt den Überblick über meinen Code verloren? Malte schrieb: > Oben drauf dann noch Boost? Weil? Ja, warum eigentlich? Weil man zuviel > Platz in einem uC hat? Weil da ganz tolle, clevere Funktionen drin sind, > die man nie-nicht selber, in einfacher, verständlicher, wartbarer, > nachvollziehbarer Weise programmieren kann? So wie > Template-Metaprogramming (hust, hust)? Weil semi-nichtdeterministische > dynamische Speicherverwaltung in einem uC so viel Spaß macht? Hier gilt das selbe wie für type_traits; die Boost MPL z.B. verbraucht 0 bytes Flash und 0 Bytes RAM, keine dynamische Speicherverwaltung, und kann einem beim Aufbau von Funktionen wie oben oder anderer Metaprogrammierung sehr helfen. Natürlich kann man das auch selber programmieren, aber wozu, wenn man auch die fertige Implementation der boost verwenden kann? Warum soll die etablierte boost Library nicht wartbar oder wiederverwendbar sein? Malte schrieb: > So wie > Template-Metaprogramming (hust, hust)? Weil semi-nichtdeterministische > dynamische Speicherverwaltung in einem uC so viel Spaß macht? Wieso braucht mein obiges template Metaprogrammierungs-Beispiel semi-nichtdeterministische Speicherverwaltung?
Dr. Sommer schrieb: > C geht aber auch nicht auf AVR's, denn malloc,free,fopen,system gehen > auf denen auch nicht so gut. system ist sowieso nicht portabel. Ansonsten: malloc und free, ausprobiert (welche Bugs sind dir übern Weg gelaufen?), oder plapperst du nur nach?
Jörg Wunsch schrieb: > system ist sowieso nicht portabel. system ist laut C-Standard vorhanden. > Ansonsten: malloc und free, ausprobiert (welche Bugs sind dir übern > Weg gelaufen?), oder plapperst du nur nach? Pingelalarm? Klar funktionieren tun die, nur ob das bei 2 KB RAM wirklich sinnvoll sind ist... kontrovers.
Dr. Sommer schrieb: >> system ist sowieso nicht portabel. > system ist laut C-Standard vorhanden. Das habe ich nicht in Abrede gestellt. Lies das oben nochmal. Das standardisierte system() hilft dir überhaupt nicht, wenn du dann nicht mehr portabel entscheiden kannst, ob du nun system("ls") oder system("dir") ausführen musst, und wenn es gleich gar keinen vom C-Standard gedeckten Weg gibt, das Ergebnis dieses Kommandos (mit Ausnahme eines exit codes) zu nutzen. >> Ansonsten: malloc und free, ausprobiert (welche Bugs sind dir übern >> Weg gelaufen?), oder plapperst du nur nach? > Pingelalarm? Klar funktionieren tun die, nur ob das bei 2 KB RAM > wirklich sinnvoll sind ist... kontrovers. Du hast aber eine Pauschalaussage gemacht, die ganze avr-libc betreffend. Es gibt ja nicht nur AVRs mit 2 KiB SRAM, sondern die gibt es bis zu 32 KiB. Das ist die halbe Menge dessen, was ein Prozess auf einer PDP-11 seinerzeit zur Verfügung hatte, und da wäre keiner auf die Idee gekommen, malloc() als unbrauchbar oder unwichtig einzustufen.
Dr. Sommer schrieb: > Was haben type_traits mit der Zielplattform zu tun? Wenn man > generischen, wiederverwendbaren Code schreiben möchte Die Mär vom wiederverwendbaren Code ... Die Realität sieht anders aus. Selber macht man das dann doch nicht, weil der Code woanders dann nicht ganz passt oder - sehr beliebt - weil man den eigenen cleveren Code später selber nicht mehr versteht. Andere nehmen den Code auch nicht, weil der nicht richtig dokumentiert, getestet und verständlich ist. Und so ist all der schöne Aufwand, den man in die Wiederverwendbarkeit gesteckt hat für die Katz. > sind diese sehr > hilfreich. Da sie ja onehin nur zur Compiletime agieren, sind sie nicht > vom Speicher des Targets abhängig. Warum sollte zB so eine Hilfsfunktion > auf XMega grunsätzlich schlecht sein?template <typename T> > stm32_always_inline T mask (const uint8_t count) { > return (T { 1 } << count) - 1; > } > > template <typename T> > using Plain = typename std::remove_reference<typename > std::remove_volatile<T>::type>::type; > > template <typename T> > inline void setBits (T& reg, const uint8_t bit, const uint8_t size, > const Plain<T> val) { > const Plain<T> bmask = mask<Plain<T>> (size); > const Plain<T> base = reg & ~(bmask << (size * bit)); > reg = base | (val << (size * bit)); > } > > int main () { > // Setze Bits 7-9 vom Register auf 5. > setBits (someHardwareRegister, 7, 3, 5); > }So kann man im User-Code recht praktisch einzelne Bits von Registern > setzen, unabhängig von der Registergröße. Dank inline und > Compiler-Optimierungen wird das auch schön kurz und effizient. > Dabei werden C++11 Features und type_traits verwendet. > Warum habe ich jetzt den Überblick über meinen Code verloren? Das ist genau die Art von Angeber-Code den ich meine. Ja, kann man machen. Bringt einem aber nicht weiter gegenüber einfachem C, nur dass man der Welt mal gezeigt hat, dass man in der Lage ist die weltkomplizierteste setBits()-Funktion zu schreiben. Gratulation.
Malte schrieb: > Und so ist all der schöne Aufwand, den man in die Wiederverwendbarkeit > gesteckt hat für die Katz. Wenn du es nicht hinbekommst, vielleicht. Ich kann meinen Code wunderbar dokumentieren, verstehen und wiederverwenden. > Das ist genau die Art von Angeber-Code den ich meine. Ja, kann man > machen. Bringt einem aber nicht weiter gegenüber einfachem C, nur dass > man der Welt mal gezeigt hat, dass man in der Lage ist die > weltkomplizierteste setBits()-Funktion zu schreiben. Gratulation. Nur weil du sie nicht verstehst? Wie würdest du das denn in einfachem C machen? Mit einem langen hässlichen Makro in einer Zeile, mit all den ekligen bekannten Nebenwirkungen?
Dr. Sommer schrieb: > Wie würdest du das denn in einfachem C machen? Mit einem langen > hässlichen Makro in einer Zeile, mit all den ekligen bekannten > Nebenwirkungen? Es gibt auch inline-Funktionen, wenn dir Makros zu hässlich sind. Ansonsten ist das Bitgewurschtel sowieso immer auf der untersten Abstraktionsebene, und das ist genau die, die man beim Wechsel der Plattform austauschen muss. Da kann man dann (was dein Code nicht kann) auch gleich noch berücksichtigen, ob die Zielplattform zum Setzen eines Bits vielleicht ein eigenständiges "bit-set"-IO-Register hat (ARM, Xmega). Was willst du hier eigentlich? Was haben deine Auslassungen denn noch mit der Frage des TE zu tun? Zuerst willst du uns erzählen, dass man C auf einem Controller nicht benutzen kann, weil es dort kein system() gibt, und dann tust du so, als könnte man sowas nur programmieren, indem man mit den neuesten C++11-Features nur so um sich wirft.
Jörg Wunsch schrieb: > Es gibt auch inline-Funktionen, wenn dir Makros zu hässlich sind. Aber die haben in C feste Parametertypen (C kann keine Templates und kein Overloading). > Ansonsten ist das Bitgewurschtel sowieso immer auf der untersten > Abstraktionsebene, und das ist genau die, die man beim Wechsel der > Plattform austauschen muss. Kommt drauf an, dieser Code ist ziemlich generisch. > Da kann man dann (was dein Code nicht > kann) auch gleich noch berücksichtigen, ob die Zielplattform zum > Setzen eines Bits vielleicht ein eigenständiges "bit-set"-IO-Register > hat (ARM, Xmega). Das würde ich auf noch einer Ebene drunter machen, auf der Hardware-Zugriffs-Ebene, und nicht auf der Bitverarbeitungsebene. Aber auch wenn nicht, dieser Code ist doch dann ein hübsches Interface, unter dem man die Implementierung abändern kann (Wiederverwendbarkeit des darauf aufsetzenden Codes). > Was willst du hier eigentlich? Dem "Malte" erläutern, dass C++(11) und type_traits nicht grundsätzlich schlecht auf Mikrocontrollern ist, auch nicht auf kleinen AVR's. > Zuerst willst du uns erzählen, dass man > C auf einem Controller nicht benutzen kann, weil es dort kein system() > gibt, und dann tust du so, als könnte man sowas nur programmieren, > indem man mit den neuesten C++11-Features nur so um sich wirft. Das mit C war natürlich ein Vergleich, weil ja behauptet wurde, dass man C++ grundsätzlich nicht verwenden kann, weil einige der Features nicht "Mikrocontroller-geeignet" sind; mit der gleichen Logik wäre C dann aber auch ungeeignet. Man kann natürlich auch alles in Assembler oder Brainf*ck programmieren, aber Features von höheren Sprachen wie C und C++ (C++11 erst recht) helfen dabei.
Kindergärtner schrieb: > Das würde ich auf noch einer Ebene drunter machen, auf der > Hardware-Zugriffs-Ebene, und nicht auf der Bitverarbeitungsebene. So'n Quatsch. Wie willst du das eine Ebene drunter machen, wenn es um Dinge wie ein Register zum Setzen von Bits geht (also sowas wie PORTA->OUTSET)?
Jörg Wunsch schrieb: > Kindergärtner schrieb: >> Das würde ich auf noch einer Ebene drunter machen, auf der >> Hardware-Zugriffs-Ebene, und nicht auf der Bitverarbeitungsebene. > > So'n Quatsch. > > Wie willst du das eine Ebene drunter machen, wenn es um Dinge wie ein > Register zum Setzen von Bits geht (also sowas wie PORTA->OUTSET)? Eigentlich kann man auf C-Ebene nicht alles ausdrücken, was man braucht. Etwa wenn die Änerungen an einem Port atomar sein sollen. Für einzelne Bits ist das zwar der Fall, falls SBI / CBI vorhanden sind (AVR) und der Wert des zu schreibenden Bits bekannt ist. Aber garantieren tut das niemand. Bei einem Toggle wird's schon sehr speziell, wenn man das als XOR hinschreibt wird der Compiler es auch als XOR implementieren, nicht als SBI auf PINx wie das bei manchen AVRs möglich ist. Garantieren kann man das nur per (Inline) Assembler oder per entsprechender Builtins, etwa __builtin_avr_atomic_or -- falls es sowas gäbe.
Hallo alle - da will ich hier auch mal meinen Senf zum Besten geben: Christoph Wiesmeier schrieb: > Bist du dir sicher dass der xmega128a3u unterstützt wird. > Hab auch im svn etwas herum gesucht und nichts gefunden. > http://svn.savannah.nongnu.org/svn/avr-libc/trunk/avr-libc/ scheint ihn > nicht zu enthalten. Oder verwendest du ein anderes repo, wenn ja > welches? Ich programmiere derzeit viel fuer ATxmega128a3u - mit den Atmel patches wird dieser auch unterstuetzt. Binaries kannst du dir z.B. hier downloaden: http://matrixstorm.com/avr/tinyusbboard/#asmorc MfG
Jörg Wunsch schrieb: > Wie willst du das eine Ebene drunter machen, wenn es um Dinge wie ein > Register zum Setzen von Bits geht (also sowas wie PORTA->OUTSET)? Es wäre zB. denkbar, sich eine Wrapper-Klasse für Register zu definieren, die die Operatoren |, &, ^, = überlädt, und sich somit (fast) wie eine Register-Variable verhält, aber bei den Operationen entsprechende Bitmasken konstruiert und diese beim zuweisen verwendet, um die Register atomar per Bit-Banding o.ä. zu setzen. Dann würde man Instanzen dieser Klasse anstelle der Register-Definitionen verwenden. Die Berechnungen würde man mit constexpr und inline zur Compile-Zeit durchführen. Die innere Implementation wäre dann Plattform-Spezifisch (bit-banding bei ARM, sbi/cbi bei AVR etc.). Code, der diese Klasse nutzt könnte dann plattformunabhängig effizient atomare Register verwenden mit (fast?) "nativer" Syntax. O.g. setBits-Funktion könnte man vermutlich unverändert auch auf Instanzen davon anwenden ("statische Polymorphie" / "Concept").
Dr. Sommer schrieb: > Es wäre zB. denkbar, sich eine Wrapper-Klasse für Register zu definieren Ja. Langsam stellt sich mir aber wirklich die Frage: warum einfach, wenn's auch umständlich geht? Fast immer muss man auf dieser Ebene beim Wechsel der Plattform ohnehin den Code anpassen. Da kann man das auch alles leicht und überschaubar schreiben. Das Einzige, wo derartige Verrenkungen vielleicht noch irgendwie sinnvoll sind, sind Sourcecode-Bibliotheken wie die für HD44780, bei denen man möglichst flexibel auf die Konfiguration des Benutzers eingehen können möchte und trotzdem auf eine große Zahl von Architekturen portierbar bleiben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.