Forum: Compiler & IDEs Umstieg - weg vom Arduino


von Andreas E. (andreas_e549)


Lesenswert?

Servus Community!

bin in dem Thema uController recht neu und habe bisher lediglich ein 
wenig mit Arduino IDE und Boards herumgespielt.
Beruflich komme ich immer wieder mit dem Thema in Kontakt und ich würde 
mich hier gerne einarbeiten. Zur Verwendung kommen hauptsächlich ATXMega 
und SAMD21 Controller zum Einsatz. Nicht zuletzt durch Lieferengpässe 
wäre ich gern in der Lage, den Code für andere Controller anzupassen 
bzw. neu zu schreiben. Für die verwendeten ATXMega wird aktuell BASCOM 
verwendet. Der Code ist (für mich) einigermaßen gut lesbar und 
verständlich, jedoch habe ich das Gefühl, dass das nicht unbedingt in 
einer professionellen Umgebung Verwendung finden sollte.
Jetzt gleich mit bare metal C anzufangen überfordert mich ehrlichgesagt.

Könnt Ihr mir vielleicht ein paar Ansätze geben, die ich verfolgen kann?

Vielen Dank vorab!
Andi

von Max M. (Gast)


Lesenswert?

Andreas E. schrieb:
> Jetzt gleich mit bare metal C anzufangen überfordert mich ehrlich gesagt.

Naja, da wird Dir nicht viel anderes übrig bleiben wenn Du flexibel auf 
andere MCUs umschwenken können willst.
Sonst hängst Du einfach nur im nächsten Ökosystem fest.

Ist aber kein Hexenwerk.
Les die Registerbeschreibungen und hangel Dich durch.
Besser wird man nur durch Übung und aller Anfang ist schwer.

von Sebastian R. (sebastian_r569)


Lesenswert?

Das Arduino-Gerödel ist von echtem C gar nicht sooo weit weg (auch wenn 
einige mich für diese Aussage vermutlich lynchen wollen würden).

Du kannst sogar mit der Arduino IDE auf einem Arduino-Board mitsamt dem 
Bootloader Bare-Metal-C schreiben/kompilieren.

Der größte Unterschied zum Arduino-C: Register.
Man muss lernen, welche Werte in welche Register man schreiben muss, um 
z.B. einen Pin als Ausgang zu konfigurieren oder einen Eingang zu lesen.

Das gleiche gilt dann auch für Timer, Interrupts,... Das Ganze ist bei 
Arduino ein bisschen versteckt.

Also schau dir zum Beispiel dieses Tutorial an:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Die dortigen Beispiele sollten 1:1 auf dem ATMega328P vom Arduino 
UNO/Nano funktionieren.


Und stark verallgemeinert:
Controller funktionieren alle ähnlich und mit dem gleichen C-Code, 
lediglich die Register heißen anders.

(Es ist stark verallgemeinert und natürlich unterscheiden sich auch 
Funktionen,..., aber das C ansich und die Logik, die man umsetzen 
möchte, bleibt portabel)

von Schlaumaier (Gast)


Lesenswert?

Andreas E. schrieb:
> Könnt Ihr mir vielleicht ein paar Ansätze geben, die ich verfolgen kann?
>
> Vielen Dank vorab!
> Andi

Es gibt 2 Lösungen.

1. B4R www.b4x.com

Der wird auch in Basic programmiert erzeugt aber Arduino-C-Code der an 
die Arduino IDE weitergeben wird.

Und ist eine gute Übergangslösung.

2. lerne C

von Andreas E. (andreas_e549)


Lesenswert?

Zunächst einmal vielen Dank für Eure schnelle Reaktion!

Dass ich mit reinem C sicherlich am flexibelsten bin ist mir bewusst. 
Ich mag auch nicht ausschließen, dass ich mich nicht doch noch mal in 
das Thema einlesen werde.
Für den Moment wäre mir aber etwas mehr "Abstraktion" ganz recht (fürs 
Erfolgserlebnis). Eben ein wenig klicki-bunti wie bei Arduino ;)

Ich habe schon hier und da Nachforschungen angestrebt und komme immer 
wieder auf Begriffe wie:

- Atmel Start / ASF (hier ist mir der Unterschied noch nicht ganz klar)
- PlatformIO mit mbed (das sollte zumindest für den SAM uC 
funktionieren?)

Was haltet Ihr von denen als Zwischenschritt? Oder gibt es noch weitere, 
die ich mir ansehen kann? Oder gar ein komplett falscher Denkansatz?

von Sebastian W. (wangnick)


Lesenswert?

Andreas E. schrieb:
> Oder gar ein komplett falscher Denkansatz?

Jetzt heisst es zurücklehnen und warten bis c-hater aufschlägt ...

LG, Sebastian

von Max M. (Gast)


Lesenswert?

Andreas E. schrieb:
> Was haltet Ihr von denen als Zwischenschritt?

Das ASF ist ein 'Advanced Sofware Framework' das Du auch erst mal lernen 
musst.
Und da ist nichts clicki bunti, sondern das ist ein Framework das Du aus 
Deinem Code heraus ansprichst.
Nachdem Du Dich da durchgeackert hast wie es zu bedienen ist und was es 
alles von Dir an Infos erwartet.
Und dann hast du auch mit 'Advanced' Bullshit Fehlern zu tun und das 
eben nicht alles geht was die MCU könnte.
ASF ist eine sehr praktische Ergänzung und kann ein paar nette Dinge, 
aber es kann ausschliesslich die Atmel MCUs. Nicht mal PIC und schon 
garnicht irgendwas anderes.
Also was hast Du damit gewonnen?

PlatformIO ist eine IDE.
Ja, ist nett, aber was hat das damit zu tun das Dir das abnehmen würde C 
zu lernen und Deine HW zu verstehen?

Du drehst Dich im Kreis.
Du kannst nicht C lernen ohne C zu lernen und Du kannst nicht 
herstellerübergreifend durch die MCU Welt streifen wenn Du Dich auf ein 
propritäres Hersteller Framework einschiesst.

Andreas E. schrieb:
> Jetzt gleich mit bare metal C anzufangen überfordert mich ehrlichgesagt.
Und?
Alles was man neu anfängt überfordert einen, denn sonst würde man ja nur 
noch tun was man eh schon kann.
MAch nicht so ein Drama draus.
Das DB und family referenz Datasheet beissen nicht und da steht alles 
drin was die Gurke kann und wie die regoster gesetzt werden müssen.
Der Rest sind coding skills und die bekommst Du nur durch coden.

von svensson (Gast)


Lesenswert?

> C lernen
Dafür kann man doch gerade gut den Arduino und die IDE benutzen. Eben 
gerade weil die IDE das ganze controllerspezifische Gerödel 
(Portkonfigurationen usw.) vor dem Benutzer verbirgt.
Im Prinzip läßt sich auch innerhalb der Arduino IDE der ganze Umfang vom 
GCC verwenden, auch wenn das in der Arduino-IDE nicht dokumentiert ist.
Den Bootloader kann man verwenden, muß man aber auch nicht.

In einem zweiten Schritt könnte man dann die Portkonfigurationen selbst 
machen und die IDE wechseln.

Und im dritten Schritt könnten dann Spezialfälle in Assembler gelöst 
werden.

Und ich behaupte einfach einmal, daß C auch nicht schwieriger zu lernen 
ist als BASIC.

von dummschwaetzer (Gast)


Lesenswert?

Für Aduino gibt es auch STM32,...

von Wolfgang Höhne (Gast)


Lesenswert?


von Veit D. (devil-elec)


Lesenswert?

Sebastian R. schrieb:
> Das Arduino-Gerödel ist von echtem C gar nicht sooo weit weg (auch wenn
> einige mich für diese Aussage vermutlich lynchen wollen würden).

Ich werde dich nicht lynchen, möchte aber etwas Grundlegendes 
klarstellen. Denn ich werde nie verstehen wie man zu solchen Aussagen 
kommt. Entweder ist es C/C++ oder es ist nichts davon. Es kann nicht 
weit weg oder nah dran sein. Arduino ist auch keine eigene Sprache. Ich 
weiß auch hier nicht wie man darauf kommt. Es gibt vorgefertigte 
Bibliotheken die in C/C++ geschrieben sind. Nicht mehr und nicht 
weniger.

> Du kannst sogar mit der Arduino IDE auf einem Arduino-Board mitsamt dem
> Bootloader Bare-Metal-C schreiben/kompilieren.

Das ist die Einzigste richtige Aussage. Man kann die Arduino 
Bibliotheken nutzen oder eben auch nicht. Niemand zwingt einem dazu. Das 
hat in der Arduino IDE einen Vorteil. Man kann Stück für Stück eigene 
Bibliotheken schreiben und nutzt solange die Arduino Funktionen bis man 
eigene hat. Sofern das Sinn macht. Es macht nicht immer Sinn jedesmal 
das Rad neu zu erfinden. Aber wer möchte kann es machen. Ob nun C, C++ 
oder Assembler ist egal.

von PittyJ (Gast)


Lesenswert?

Andreas E. schrieb:
> Könnt Ihr mir vielleicht ein paar Ansätze geben, die ich verfolgen kann?

Da war letztens ein Beitrag, dass Assembler wieder im kommen ist.
Assembler ist einfach: keine komplizierte Syntax, exakt eine Anweisung 
pro Zeile. Keine Variablen oder Datentypen. Keine Schleifen. Nur 
Sprünge, wie Goto's in Basic.
Assembler könnte da was für die mental einfacheren Leute sein.

von Veit D. (devil-elec)


Lesenswert?

Andreas E. schrieb:
>

Tja was soll man dir raten. Erstmal die Grundlagen von C/C++ lernen. 
Dazu kannste auch die Arduino IDE verwenden. Erstmal darin saubere 
Programme schreiben würde ich meinen. Ob du die fertigen Bibliotheken 
verwendest bleibt dir überlassen. Aber den Code den du selbst schreibst 
entscheidet auch schon ob es lesbar und wartbar ist. Danach wird man 
immer tiefer einsteigen. Ob nun mit oder ohne Arduino.

von Schlaumaier (Gast)


Lesenswert?

Dieser Code .

#Region Project Attributes
  #AutoFlushLogs: True
  #CheckArrayBounds: True
  #StackBufferSize: 600
#End Region

Sub Process_Globals
  Public Serial1 As Serial
  Public lcd As LiquidCrystal_I2C
End Sub

Private Sub AppStart
  Serial1.Initialize(9600)

  Log("AppStart")  ' gibt infos auf den Seriellen Monitor aus

  lcd.Initialize(0x27, 16, 2) 'based on the example from the project.

lcd.Backlight = True
  lcd.Write("System gestartet")

End sub


Das kompiliert die IDE in eine  INO-Datei. Startet die Arduino-IDE die 
diese Datei dann Kompiliert und dann zum Arduino hoch läde.  Der ganze 
Vorgang geht automatisch. ABER, man kann danach die INO-Datei ganz 
normal in der IDE als C Code lesen.

So nebenbei kann man mit der B4R - IDE auch für die Beere programmieren.

von Peter D. (peda)


Lesenswert?

PittyJ schrieb:
> Assembler könnte da was für die mental einfacheren Leute sein.

Assembler ist quasi die Krabbelgruppe im Kindergarten.
Etwas komplexere Anwendungen (Rechnen, formatierte Ein-/Ausgaben, float, 
Structs, Arrays usw.) bleiben einem verwehrt oder werden extrem 
aufwendig und fehlerträchtig.
Assembler kennt keine Datentypen und Pointer und kann daher auch keine 
Fehler oder Warnungen werfen, wenn Du dabei was vermasselst.

Compiler sind heutzutage auch recht gut darin, viele logische Fehler zu 
erkennen (always true, always false, code with no effect, code never 
reached, ...). Assembler führt jedoch gnadenlos den größten Blödsinn 
aus.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Andreas E. schrieb:
> habe bisher lediglich ein wenig mit Arduino IDE und Boards
> herumgespielt.

Immerhin, das ist doch schon mal etwas. Wie bereits mehrfach geschrieben
wurde, verwendet Arduino C++ als Programmiersprache, so dass es eine
Basis für den sanften Übergang zur Arduino-freien C/C++-Programmierung
darstellt.

Ein erster Schritt könnte sein, die setup()- und loop()-Funktion
wegzulassen und stattdessen ganz klassisch ein main() als Hauptprogramm
zu definieren.

Als nächstes könnte man versuchen, die Aufrufe von digtalRead() und
digtalWrite() durch direkte Portzugriffe zu ersetzen. Dazu muss man sich
über das Thema Bitmanipulation informieren und in der Dokumentation des
Arduino-Boards nachschauen, wie die Board-Pins den I/O-Ports des µC
zugeordnet sind. An dieser Stelle lohnt auch schon einmal ein Blick ins
Datenblatt de µC, um zu verstehen, wie die I/O-Ports organisiert sind.

So kann man nach und nach die Arduino-Funktionen für ADC, Timer usw.
durch eigenen Code ersetzen und lernt dabei, das Datenblatt zur
verstehen und auf niedriger Abstraktionsebene in C/C++ zu programmieren.
Dabei kann man am Anfang die (etwas kompliziertere) Initialisierung des
ADCs oder des Timers über Arduino-Funktionen vornehmen und nur das
eigentliche Lesen des aktuellen Zustands selber programmieren.

Je tiefer man in die Materie eintaucht, umso wichtiger werden die
Informationen aus dem Datenblatt. Man lernt also nicht nur, µCs in C/C++
zu programmieren, sondern auch Datenblätter zu verstehen.

Irgendwann ist man dann so weit, dass man die Arduino-Bibliothek
überhaupt nicht mehr benötigt. Wenn man man dieses Ziel für eine
µC-Familie (bspw. AVR) erreicht hat, kann man den obigen Prozess noch
für eine weitere, ebenfalls von Arduino unterstützte Familie (bspw. ARM)
wiederholen. Dabei lernt man, welche Grundprinzipien die verschiedenen
µCs gemeinsam haben und in welchen Details sie sich unterscheiden.

Wenn man auf diese Weise zwei µC-Familien kennengelernt hat, ist es kein
großes Problem mehr, auch weitere µC-Typen einzusetzen, für die es keine
Arduino-Umgebung gibt. Man besorgt sich die jeweilige Tool-Chain
(C-Compiler, Assembler, Linker) und das Datenblatt des µC und legt los.
Ok, ein paar Tage Einarbeitungszeit wird man für einen neuen µC-Typ
schon brauchen. Das ist aber wenig im Vergleich zu der Zeit, die man zum
Lernen einer neuen Programmiersprache benötigt. Zum Glück lassen sich
praktisch alle µC in C programmieren, so dass man keine weiteren
Sprachen lernen muss.

Schlaumaier schrieb:
> Es gibt 2 Lösungen.
>
> 1. B4R www.b4x.com

Warum sollte der TE, nachdem er sich schon etwas mit Arduino und Bascom
angefreundet hat, noch eine weitere Programmiersprache lernen, die
wieder nur für eine begrenzte Zahl von µC-Typen verfügbar ist? Da kann
er doch gleich bei Anduino bleiben, das mehr µC-Typen unterstützt als
B4X.

von Peter D. (peda)


Lesenswert?

Andreas E. schrieb:
> bin in dem Thema uController recht neu und habe bisher lediglich ein
> wenig mit Arduino IDE und Boards herumgespielt.

Arduino ist doch schon C/C++. Damit kann man also einfach weitermachen.

Für plain C/C++ mit AVRs kann man auch das Microchip Studio 
installieren.
https://www.microchip.com/en-us/tools-resources/develop/microchip-studio

von Schlaumaier (Gast)


Lesenswert?

Yalu X. schrieb:
> Warum sollte der TE, nachdem er sich schon etwas mit Arduino und Bascom
> angefreundet hat, noch eine weitere Programmiersprache lernen, die
> wieder nur für eine begrenzte Zahl von µC-Typen verfügbar ist? Da kann
> er doch gleich bei Anduino bleiben, das mehr µC-Typen unterstützt als
> B4X.

Ganz einfach.

Wenn er BASCOM kann, kann er Basic.

Kann er Basic kann er B4X auch in einigen Stunden lernen.

ABER. Das Ergebnis ist das Ziel. ;)  Wie genau beschrieben erzeugt B4X 
eine INO-Datei. Also kann er dann in den Code nachsehen wie die Sachen 
OHNE BASIC in C++ gemacht werden.

Und da sehe ich ein klaren Vorteil als wenn man ihn ins kalte Wasser 
wirft.


Davon abgesehen ist deine Aussage FALSCH.

B4X unterstützt überhaupt keine Micro-Controller. !!! Man muss sich nur 
Entscheiden ob man ESP32 (weil optimierter Sub-Code) benutzt oder nicht.

Man stellt dort unter Einstellungen nur ein, was in der ARDUINO-IDE zur 
Verfügung steht damit der Code gleich sauber hochgeladen werden kann.

Diese Infos braucht aber NICHT der Vor-Compiler sondern die AVRDUDE ;)

Und GENAU DAS ist der Unterschied zwischen B4R und Bascom. Da brauche 
ich / bin ich auf die Mirco-Code (oder wir man das Nennt) des MC 
angewiesen.
BASCOM kostet viel Geld (B4R war immer für lau) und ich bin auf die 
Entwickler angewiesen.  Bei B4R bin ich das NICHT. Da lade ich die 
MC-"Treiber" einfach nach. Und die Arduino-IDE-Community ist 1000 x 
stärker.

Ich habe mir nämlich damals das selbe überlegt wie jetzt mehr o. weniger 
der TO.

Bloß wollte ich auch keine neue Sprache lernen. Besonders nicht C mit 
seinen Drecks-Klammern. Und seiner ; Verteilung

von Ralph S. (jjflash)


Lesenswert?

Yalu X. schrieb:
> Man besorgt sich die jeweilige Tool-Chain
> (C-Compiler, Assembler, Linker) und das Datenblatt des µC und legt los.
> Ok, ein paar Tage Einarbeitungszeit wird man für einen neuen µC-Typ
> schon brauchen.

Erstmal eine komplette Zustimmung zu Yalu, wobei zu obigem Text dann zu 
sagen ist, dass das bspw. im Falle von ARM nicht sooooo ganz so einfach 
ist. Ich erinnere mich noch daran, wie ich um die Erstellung eines 
korrekten Linkerscriptes gekämpft habe. Hier kommt dann die Einarbeitung 
im Falle von STM32 Controllern (zumindest in aller Regel) in die HAL 
hinzu. Für mich sind die "Einstellmöglichkeiten" bisweilen eine 
Herausforderung. Oder man wählt die Alternative "libopencm3", auch nicht 
so ganz schlecht.

In erster Linie muß man, wie die Vorredner schon geschrieben, schlicht 
unterscheiden zwischen der Programmierung (in C / C++) und der Hardware. 
Das sind dann eben besagte Register.

Wer Arduino kann (und wenn es nur ein bisschen ist), hat somit schon mit 
C/C++ Kontakt gehabt (wie oben eben richtig festgestellt wurde, wird in 
der Arduino IDE C++ verwendet). Hierauf sollte aufgebaut werden und 
nicht schlicht die Sprache gewechselt werden. Wenn dann die Sprache so 
halbwegs sicher sitzt, kann man sich mit der Hardware der 
unterschiedlichen MCU's auseinandersetzen.

Ein fertiges Setup der Toolchain (inkl. Linkerscripts) und evtl. 
Bibliotheken kann hier sehr helfen.

Wenn man keine eigene Toolchain aufsetzen will, kann auch die 
Arduino-IDE verwenden und läßt dann im Sourcecode des Hauptprogrammes 
die Funktionen setup und loop weg und fügt eine

int main(void)
{
}

hinzu. Fortan kann hier mit C programmiert werden. Eventuelle 
Sourcebibliotheken in Form von .h / .c landen dann in dem Ordner in dem 
auch das Hauptprogramm ist, das Arduino-Framework linkt die Sourcen aus 
dem Ordner dann automatisch mit hinzu.

Wenn das funktioniert, kann man sich einmal Gedanken darüber machen, das 
Arduino-Framework komplett wegzulassen.

von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

> Assembler ist quasi die Krabbelgruppe im Kindergarten.
> Etwas komplexere Anwendungen (Rechnen, formatierte Ein-/Ausgaben, float,
> Structs, Arrays usw.) bleiben einem verwehrt

Tja, die bleiben nur solchen Idioten verwehrt, die halt Asm nicht 
können.

> oder werden extrem
> aufwendig und fehlerträchtig.

Nicht fehlerträchtiger als in C. Oder höchstens unwesentlich 
fehlerträchtiger.

> Assembler kennt keine Datentypen

Naja, irgendwie schon. Datentypen sind in Asm praktisch wie in C. Eine 
Konvention. Gegen die man leicht verstoßen kann. Man muß in Asm bloß 
weniger Syntax-Geschwalle aufbieten, wenn man (aus gutem Grund 
absichtlich) dagegen verstoßen möchte.

> und Pointer

Na das ist ja mal was ganz neues. Assembler kennen keine Pointer... Nee, 
natürlich kennen sie die, heißen hier nur Indirektion, ist aber absolut 
dieselbe Soße. Und übrigens: auch genauso "sicher" wie in C...

> und kann daher auch keine
> Fehler oder Warnungen werfen, wenn Du dabei was vermasselst.

Quatsch mit Soße. Man kann in reinem Asm dem ganzen Quatsch diese 
minimalen Sicherheitsvorteil von C per Makros genauso überhelfen. 
Tatsächlich sind das ja auch in C nur Makros. Aber man verliert die 
Freiheit, es einfach optimal zu machen. Da könnte man dann auch gleich C 
verwenden.

> Compiler sind heutzutage auch recht gut darin, viele logische Fehler zu
> erkennen (always true, always false, code with no effect, code never
> reached, ...). Assembler führt jedoch gnadenlos den größten Blödsinn
> aus.

Eins zumindest ist sicher: nicht erreichbarer Code wird auch in Asm ganz 
sicher nicht ausgeführt. Und der ganze andere Quatsch sind oft keine 
logischen Fehler, sondern schlicht Sachen, die INTENDIERT sind, bloß 
vom Programmierer nicht hinreichend gut ausgedrückt, damit der hirnlose 
Compiler die Intention erkennen kann. Der Klassiker:

while (true) {
 //tue was
}

Normalerweise müßte es hier eine Warnung der Klasse "allways true" 
geben. An jeder anderen Stelle als in der Hauptschleife kommt die auch. 
Also: schon hier wird aus praktischen Erfordernissen sogar in C selber 
getrickst. Abartig unlogischer Dreck.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

c-hater schrieb:
> Abartig unlogischer Dreck

Deine Sprache/Argumente erscheinen mir zunehmend unterkomplex, weil Hass 
ist kein Argument sonders eine Emotion, um die ich dich wirklich nicht 
beneide!

von Gerhard O. (gerhard_)


Lesenswert?

c-hater schrieb:
> Naja, irgendwie schon. Datentypen sind in Asm praktisch wie in C.

Moin,

Ich vermute fast, Du bist kein wirklicher "C-hater" und programmierst in 
der Stille Deines Kämmerlein/Labor Sachen in C oder C++. Ich denke der 
c-hater "Stuff" ist eher nur Show und ein Trademark, dass Du nicht 
aufgeben willst;-)

Komm endlich aus Deinem "Closet" und geb es zu, dass Programmieren in C 
oder C++ doch auch Spass macht und viel Zeit spart. Ich weiß doch, dass 
bei Dir im Labor unzählige Arduino Bords rumliegen die in C/C++ 
programmiert werden...

Ich kenne doch meine Pappenheimer und Du machst mir nichts vor. Als gebe 
es endlich einmal zu und gut ist!

Gruß,
Gerhard

von Peter D. (peda)


Lesenswert?

c-hater schrieb:
> Na das ist ja mal was ganz neues. Assembler kennen keine Pointer... Nee,
> natürlich kennen sie die, heißen hier nur Indirektion, ist aber absolut
> dieselbe Soße.

Weit entfernt.
Assembler kennt nicht die Größe der Struct im Array und auch nicht die 
Größe und den Offset der Member. Du must also alles händisch ausrechnen 
und in die Pointeradditionen eintragen.
Und sobald Du die Member änderst (Anzahl, Order, Typ), ist alles für die 
Katz und es passiert Mumpitz.
Und Pointer auf Pointer sind in C einfach nur eine weiteres Klammernpaar 
[], aber in Assembler mag ich mir das nicht antun müssen.

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.