Forum: Mikrocontroller und Digitale Elektronik Geschwindigkeit Arduino > C


von Hans L. (holzwurm56)


Lesenswert?

Hallo,
ich experimentiere ein bißchen mit Arduinos. Ich lese oft das ein in C 
programmiertes Aduinoboard ein Programm viel schneller ausführt wie ein 
mit der Arduinoprogrammiersprache. Hat das jemand mit dem entsprechendem 
Meßequipment mal probiert, z.B. ein Programm:
                 Loop
                      PinX = 1
                      PinX = 0
Welche Taktfrequenz hat ein Signal an PinX mit Arduino programmiert, 
welche mit C programmiert?

Ich hoffe die Frage war nicht zu blöd.

MfG

Hans

von Peter II (Gast)


Lesenswert?

Hans L. schrieb:
> Ich hoffe die Frage war nicht zu blöd.
doch ist sie.

Arduino ist C


Es wird kein unterschied geben. Bei Arduino ist das Problem viel mehr, 
das viele Versteckt wird und man nicht weis was im Hintergrund passiert.

von Korrektor (Gast)


Lesenswert?

Peter II schrieb:
> Arduino ist C++

von Oliver S. (oliverso)


Lesenswert?

Hans L. schrieb:
> Ich lese oft das ein in C
> programmiertes Aduinoboard ein Programm viel schneller ausführt wie ein
> mit der Arduinoprogrammiersprache.

Hast du mal einen Link? Oder mehrer, wenn du das oft gelesen hast?

Oliver

von Ulrich F. (Gast)


Lesenswert?

digitalWrite() und digitalRead() sind keine Geschwindigkeitswunder, aber 
ansonsten, ist die Aussage:

Hans L. schrieb:
> Ich lese oft das ein in C
> programmiertes Aduinoboard ein Programm viel schneller ausführt wie ein
> mit der Arduinoprogrammiersprache

Wohl ein Märchen.

von Stefan F. (Gast)


Lesenswert?

> Wohl ein Märchen.

Sicher?

Ich erinnere mich an eine Diskussion hier im Forum, wo jemand 
digitalWrite() mit direkten Portzugriffen der Art PORTB |= (1<<PB3) 
verglich und ganz erstaunt war, dass die Arduino Library in diesem Punkt 
100x mal langsamer war.

Damals wurde hier der generierte Assembler Code verrissen und viele 
Telnehmer meinten, dass sie genau deswegen niemals etwas mit Arduino 
Software zu tun haben wollen.

von Peter II (Gast)


Lesenswert?

Stefan U. schrieb:
> Ich erinnere mich an eine Diskussion hier im Forum, wo jemand
> digitalWrite() mit direkten Portzugriffen der Art PORTB |= (1<<PB3)
> verglich und ganz erstaunt war, dass die Arduino Library in diesem Punkt
> 100x mal langsamer war.

aber es zwingt doch niemand digitalWrite zu verwenden. Ich kann auch in 
C mir eine langsame Variante von digitalWrite einfallen lassen.

Es hängt also nicht direkt am Arduino wenn etwas langsam ist, sondern 
daran wie man ein Problem umsetzt.

eine Uhr wird (hoffentlich) mit C auch nicht schneller sein.

von Ulrich F. (Gast)


Lesenswert?

Stefan U. schrieb:
> dass die Arduino Library in diesem Punkt
> 100x mal langsamer war.
Nichts anderes habe ich doch gesagt.....
Vielleicht nicht so deutlich.....


Siehe:
Ulrich F. schrieb:
> digitalWrite() und digitalRead() sind keine Geschwindigkeitswunder

Stefan U. schrieb:
> Sicher?
Ja!

von avr (Gast)


Lesenswert?

Peter II schrieb:
> Es hängt also nicht direkt am Arduino wenn etwas langsam ist, sondern
> daran wie man ein Problem umsetzt.

Natürlich hängt es genau daran. Wenn du auf die Arduino Seite gehst, 
wirst du in der Doku nämlich genau diese Funktionen finden. Beim 
direkten Portzugriff benutzt man die Bibliothek gar nicht mehr.

von Peter II (Gast)


Lesenswert?

avr schrieb:
> Natürlich hängt es genau daran. Wenn du auf die Arduino Seite gehst,
> wirst du in der Doku nämlich genau diese Funktionen finden.

https://www.arduino.cc/en/Reference/PortManipulation

also ich finde dort beides. Und dort steht auch das der direkte Zugriff 
schneller ist und man ihn verwenden sollte wenn es sehr schnell gehen 
soll.

von Loddaar (Gast)


Lesenswert?

Hans L. schrieb:
> Loop
>                       PinX = 1
>                       PinX = 0

die Zuweisungen sind nicht von Arduino

da verwendet man DigitalWrite, das kostet zum einen Zeit,
zum anderen braucht das Loop auch länger als wenn du eine
Schleife direkt in C++ programmierst.
Die Taktfrequenz mit der das ganze abgearbeitet wird habe ich
auch schon Mal gesucht, war unter den ersten Treffern bei google ...

von avr (Gast)


Lesenswert?

Peter II schrieb:
> also ich finde dort beides. Und dort steht auch das der direkte Zugriff
> schneller ist und man ihn verwenden sollte wenn es sehr schnell gehen
> soll.

hm, tatsächlich. Das widerspricht eigentlich der 
Plattformunabhänigigkeit. Besser wäre es über Templates... Da frage mich 
eigentlich, wo der Vorteil von Arduino liegen soll wenn es nicht mehr 
plattformunabhängig ist? Dann kann man es eigentlich gleich lassen.

von Simon (Gast)


Lesenswert?

avr schrieb:
> Peter II schrieb:
> also ich finde dort beides. Und dort steht auch das der direkte Zugriff
> schneller ist und man ihn verwenden sollte wenn es sehr schnell gehen
> soll.
>
> hm, tatsächlich. Das widerspricht eigentlich der
> Plattformunabhänigigkeit. Besser wäre es über Templates... Da frage mich
> eigentlich, wo der Vorteil von Arduino liegen soll wenn es nicht mehr
> plattformunabhängig ist? Dann kann man es eigentlich gleich lassen.

Das steht dort als Nachteil.

von Peter II (Gast)


Lesenswert?

>    Loop
>                      PinX = 1
>                      PinX = 0

kann es sein das du nicht Arduino sondern BASCOM meinst?

von Christian K. (the_kirsch)


Lesenswert?

Die "Arduino Programmiersprache" ist C/C++ mit einer HAL (hardware 
abstraction layer, deutsch Hardwareabstraktionsschicht)


Durch die HAL sind die ganzen Hardwarezugriffe versteckt, das 
vereinfacht zwar die Programmierung aber ist sehr viel langsamer, da 
viele Sachen zusätzlich abgefragt oder berücksichtig werden, auch wenn 
sie an der Stelle gar nicht relevant sind.


Ein PortX |= 0x01; dauert nur einen Takt

Ein Aufruf über digitalWrite() dauert im vergleich dazu ewig.
Erstmal muss nachgeschaut werden welcher Pin das überhaupt ist, dann 
werden alternative Funktionen des Pins (z. B. PWM) deaktiviert, 
Direktion Register gesetzt und dann wird  endlich der Pin gesetzt.

: Bearbeitet durch User
von Hans L. (holzwurm56)


Lesenswert?

Vielen Dank für alle Beiträge. Ich habe geschrieben das ich mit den 
Arduinos jetzt etwas experimentiere, d. h. ich bin ein Anfänger. Wenn 
ich ein entsprechendes Frequenzmeßgerät hätte würde ich es selbst 
probieren. Hat es jemand schon mal selbst ausprobiert wie die 
Ausgabefrequenz bei den verschiedenen Programmiersprachen ist, oder habt 
alle ihr alle es auch nur irgendwo gelesen? Das hätte ich mit Google 
auch hinbekommen. PinX soll natürlich nur stellvertretend für die 
entsprechende Anweisung stehen.

MfG

Hans

von c-hater (Gast)


Lesenswert?

Christian K. schrieb:
> Erstmal muss nachgeschaut werden welcher Pin das überhaupt ist, dann
> werden alternative Funktionen des Pins (z. B. PWM) deaktiviert,
> Direktion Register gesetzt

wenn Digitalwrite das Direktion Reg setzt, dann braucht man die Funktion 
Pinmode ja gar nicht???

von c-hater (Gast)


Lesenswert?

Hans L. schrieb:
> Das hätte ich mit Google
> auch hinbekommen.
und warum machst du es dann nicht?

>PinX soll natürlich nur stellvertretend für die
> entsprechende Anweisung stehen.

und wie lautet die entsprechende Anweisung,
DigitalWrite
oder
PORTB |= 1

von Lurchi (Gast)


Lesenswert?

Die libraries sind nicht überall so viel langsamer. Das setzen einzelner 
Bits ist schon so etwas wie ein worst case Beispiel. Bei vielen 
einfachen Rechenfragen gibt es gar keinen Unteschied zu normalem C Code.

Bei so etwas wie UART / I2C kann man es von Hand auch schlechter 
impementieren als in den Libs.

von Langer Atem (Gast)


Lesenswert?

Das hatten wir hier:
Beitrag "Ist Arduino verpönt?"

wenn ich mich recht erinnere, brauchte der Arduino-code 150 takte, wo 
hardwarenahes C 2 brauchte.

von Hans L. (holzwurm56)


Lesenswert?

Fazit,
keiner hat die Taktfrequenz bei den verschiedenen Programmiersprachen 
selbst gemessen.
Ich kaufe mir ein Frequenzmeßgerät und probiere es selbst.

MfG

Hans

von Loddar (Gast)


Lesenswert?

Hans L. schrieb:
> Hat das jemand mit dem entsprechendem
> Meßequipment mal probiert

dazu brauchst du kein Equipment.

einfach dein Programm z.B. 10000x laufen lassen und die vor und nachher 
die Zeilt per millis geben lassen.
Wenn du die Differenzzeit durch 10000 teilst, hast du die Zeit für einen 
Durchlauf

von Hans L. (holzwurm56)


Lesenswert?

Hallo Loddar,
dieser praktische Tip hat mir geholfen.

MfG

Hans

von Rudolph R. (rudolph)


Lesenswert?

Christian K. schrieb:
> Ein PortX |= 0x01; dauert nur einen Takt

Check das noch mal, das ist ein Read-Modify-Write.
Dicht dran, sehr dicht dran, aber auch nicht richtig. :-)

Sowas finde ich lästig:

val = analogRead(analogPin);    // read the input pin
Serial.println(string);
lcd.print("hello, world!");

Das ist komplett blockierend, die Funktionen kommen erst zurück wenn das 
Ergebnis da ist.
Im Falle vom analogRead() werden also mal eben um 100µs sinnlos 
verbrannt.

Und da wundern sich unsere Azubis, warum der Arduino nur eher sporadisch 
auf Eingaben reagiert...

von Dr. Sommer (Gast)


Lesenswert?

Rudolph R. schrieb:
> Das ist komplett blockierend, die Funktionen kommen erst zurück wenn das
> Ergebnis da ist.
> Im Falle vom analogRead() werden also mal eben um 100µs sinnlos
> verbrannt.
Tja, das ist halt das Grundmerkmal von 98% der Mikrocontroller-Libraries 
wie eben auch Arduino, dass jede Funktion blockiert. Das ist ja so 
allgegenwärtig, dass sich da kein Mensch mehr Gedanken drüber macht. 
Asynchrone Programmierung auf Interrupt-Basis versteht ja keiner...

von Rudolph R. (rudolph)


Lesenswert?

Rudolph R. schrieb:
>> Ein PortX |= 0x01; dauert nur einen Takt
>
> Check das noch mal, das ist ein Read-Modify-Write.
> Dicht dran, sehr dicht dran, aber auch nicht richtig. :-)

---
PORTB |= 0x01;
 80:  28 9a         sbi  0x05, 0  ; 5
---

Na okay, der Compiler ist noch schlauer.

von Ulrich F. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Asynchrone Programmierung auf Interrupt-Basis versteht ja keiner...
Das kann man so auch nicht sagen...

Dr. Sommer schrieb:
> dass jede Funktion blockiert
Das gilt für Serial.println(string); nicht unbedingt. Das blockiert 
erst, wenn der Buffer voll ist.

Dr. Sommer schrieb:
> dass sich da kein Mensch mehr Gedanken drüber macht
Außerdem ist das in vielen Fällen vollkommen egal, ob eine Funktion ein 
paar mS blockiert.

von Bauteiltöter (Gast)


Lesenswert?

Rudolph R. schrieb:
>> Ein PortX |= 0x01; dauert nur einen Takt
>
> Check das noch mal, das ist ein Read-Modify-Write.
> Dicht dran, sehr dicht dran, aber auch nicht richtig. :-)


Ein PORTA |= (1<<0);

wirt zu zur kürzest möglichen ASM-Anweisung sbi kompiliert, die braucht 
auf normalen AVRs 2 Takte, auf den tinyAVRs ("Number of clock cycles for 
Reduced Core tinyAVR") einen Takt.

von Michael U. (amiga)


Lesenswert?

Hallo,

Dr. Sommer schrieb:
> Tja, das ist halt das Grundmerkmal von 98% der Mikrocontroller-Libraries
> wie eben auch Arduino, dass jede Funktion blockiert. Das ist ja so
> allgegenwärtig, dass sich da kein Mensch mehr Gedanken drüber macht.
> Asynchrone Programmierung auf Interrupt-Basis versteht ja keiner...

Prinzipiell hast Du recht und das ist auch das Problem "Arduino".

Es wird aber auch niemand gehindert, es selbst zu machen. Dann ist es 
eben nicht mehr so leicht portabel, aber schneller und nicht 
blockierend.

Ja, digitalWrite() und seine Abkömmlinge sind lahm. Für einen sauberen 
Multiplex meiner Anzeige z.B. zu lahm. Na und? Wird eben ein freier 
Timer initialisiert und der Kram selbst erledigt.

Andererseits speiel ich mit den ESP8266 rum, da bin ich dankbar für 
digitalWrite(), die Doku des Espressif ist nämlich umfangreich, manchmal 
fragwürdig oder unvollständig.

Abhängig vom Vorhaben ist es mir auch egal, wielange digitalWrite() 
braucht, ich gewinne nichts wenn es schnell ist ohne daß es eine Rolle 
spielt. Der AVR wartet dann eben länger oder die loop() wird 30x statt 
10x nutzlos durchlaufen bis wieder was passiert.

Es wird bei Arduino-Displays gern die u8g-Lib empfohlen. Vorteil ist, 
sie kennt fast jeden Displaycontroller mit fast jeder Ansteuerung. Sie 
hat fast jede Funktion, die man irgendwie brauchen kann.

Gut, der Mega328 ist fast voll, wenn man die einbindet, nimmt man eben 
den Mega2560. Gereicht hätte für die komplette Aufgabe allerdings auch 
ein Mega88.

Wie schreibt hier jemand gern: einen Tod muß man sterben...

Gruß aus Berlin
Michael

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Rudolph R. (rudolph)

>> Ein PortX |= 0x01; dauert nur einen Takt

2, da wird ein sbi draus.

>Check das noch mal, das ist ein Read-Modify-Write.

Meistens nicht.


>val = analogRead(analogPin);    // read the input pin
>Serial.println(string);
>lcd.print("hello, world!");

Vollkommen OK.

>Das ist komplett blockierend, die Funktionen kommen erst zurück wenn das
>Ergebnis da ist.

Was sollen sie sonst tun? Anfänger mit Call back Funktionen un RTOS 
verwirren?

>Im Falle vom analogRead() werden also mal eben um 100µs sinnlos
>verbrannt.

Was in 90% aller Arduino-Anwendung kein Problem ist.

>Und da wundern sich unsere Azubis, warum der Arduino nur eher sporadisch
>auf Eingaben reagiert...

Ach so, weil sie 100us waren müssen? Soso!

Nicht immer nur rumjammern, wenn schon Kritik, dann substantiell!

von Rudolph R. (rudolph)


Lesenswert?

Falk B. schrieb:
>>Im Falle vom analogRead() werden also mal eben um 100µs sinnlos
>>verbrannt.
>
> Was in 90% aller Arduino-Anwendung kein Problem ist.

Ich gehe eher von 69% aus, die Zahl ist genau so willkürlich gewählt. 
:-)

>>Und da wundern sich unsere Azubis, warum der Arduino nur eher sporadisch
>>auf Eingaben reagiert...
>
> Ach so, weil sie 100us waren müssen? Soso!

Nein, durch die Kombination von allem was denen so einfällt.
Zum Beispiel in jedem Schleifen-Durchlauf die Strings erneut an das 
Display schicken, am Besten noch mehrere übereinander.

Natürlich gespickt mit delay() das Ganze.

> Nicht immer nur rumjammern, wenn schon Kritik, dann substantiell!

War doch konstruktiv, was denn noch?
Fakt ist, das ist alles blockierend mit mehr oder weniger starken 
Auswirkungen.
Mein Kommentar dazu war jetzt nicht, dass das Scheisse ist, sondern 
lediglich, dass ich das lästig finde.

von Falk B. (falk)


Lesenswert?

@ Rudolph R. (rudolph)

>> Ach so, weil sie 100us waren müssen? Soso!

>Nein, durch die Kombination von allem was denen so einfällt.
>Zum Beispiel in jedem Schleifen-Durchlauf die Strings erneut an das
>Display schicken, am Besten noch mehrere übereinander.

>Natürlich gespickt mit delay() das Ganze.

AHA! Da kommen wir der Sache schon näher!

>> Nicht immer nur rumjammern, wenn schon Kritik, dann substantiell!

>War doch konstruktiv, was denn noch?

Nö, nur Gejammer über eine normale Sequenz, also ob man nur mit 
Interrupts und asynchronen Schikanen programmieren könnte. Das stimmt 
nicht!

>Fakt ist, das ist alles blockierend mit mehr oder weniger starken
>Auswirkungen.

Ich behaupte mal, auch mit den meist blockierenden Arduino-Funktionen 
kann man gute, flüssige Programme schreiben. Auch wenn es mit "richtigem 
C" sicher noch besser geht und man noch ne ganze Ecke mehr rausholen 
kann.

>Mein Kommentar dazu war jetzt nicht, dass das Scheisse ist, sondern
>lediglich, dass ich das lästig finde.

Der entscheidende Punkt ist, dass man den Lehrlingen die richtigen 
Konzepte vermitteln muss und nicht rumjammern, daß sie es bis jetzt noch 
nicht kapiert haben. Alle können und wollen es so oder so nicht 
verstehen.

von Wolfgang A. (Gast)


Lesenswert?

Hans L. schrieb:
> Wenn ich ein entsprechendes Frequenzmeßgerät hätte würde ich es selbst
> probieren.

Ein Frequenzmeßgerät ist für Messungen an einem µC nun wirklich fast die 
ungünstigste Lösung. Kauf dir besser einen kleinen Logikanalysator für 
weniger als 8€. Da hast du wesentlich mehr von.

von Lurchi (Gast)


Lesenswert?

Die Laufzeit so kurzer Dinge kann man ggf. auch noch gut im Simulator 
ablesen. Einfach beak points setzen und den Simulator Takte Zählen 
lassen.

Der Faktor 100 (durch die nun doch 2 Zyklen für ein SBI nur noch 50) 
sieht groß aus, aber in der Regel kommt da noch viel anderer Code dazu, 
so dass der Unterschied in der kompletten routine gar nicht mehr so 
auffällt.
Wenn man wirklich Zeitkritische Teile hat, wie etwa Bitbanging - kann 
man auch beim Arduino direkt auf die Register zugreifen - das ist aber 
eher die Ausnahme.

von JoJoBa (Gast)


Lesenswert?

Falk B. schrieb:
> Der entscheidende Punkt ist, dass man den Lehrlingen die richtigen
> Konzepte vermitteln muss und nicht rumjammern, daß sie es bis jetzt noch
> nicht kapiert haben. Alle können und wollen es so oder so nicht
> verstehen.

Gannz genau sehe ich es auch so!

Wenn wir also über Arduino und Codgeschwindigkeiten reden, sollten wir
ganau diese Dinge ausdrücklich vor Augen halten  :-)
...Arduino wurde ja gerade für Künstler und nichtprogrammierer
entwickelt!

Dem Entwickler sei Dank... erfreuen sich viele User darüber,dass
es diesen Plattform gibt.
Gerade weil es hier nicht um ein,bis in die Perfektion hochgeputschtes
Spezies handelt, eignet sich diese Familie bestens für Lernzwecke.

Und Lernen gehört nunmal dazu, neues Wissen anzuegnen.

In diesem Sinne freue ich mich persönlich sehr darüber, dass es
eine preiswerte "universelle" Möglichkeit gibt, C, C++ Arduino-C
oder wie auch es heißen mag Sprache kennenzulernen und
paralell dazu darüber,die Theorie sofort in die Praxis umsetzen zu 
können.

Ob die Code-geschwindigkeiten zufriedenstellend sind, hängt hier
im Größtenteil doch davon ab, wie weit ich mit meinem Wissen
gekommen bin ?!

Die Fortgeschrittenen setzen Assembler ein, die Anfänger eher die
Arduino-C, das eine schließt aber das Andere nur in einer Richtung
aus :-)

MfG

von Michael U. (amiga)


Lesenswert?

Hallo,

warum sollte man rumhacken?

Die Meinungen werden da ohnehin beliebig weit auseinandergehen.
Ich kann nur für mich reden. Es ist bei mir reines Hobby, das heißt, daß 
Ergebnis soll ohne wenn und aber funktionieren, es spielt aber keine 
wirkliche Rolle, wenn ein Projekt scheitert und ich es beerdige.

Ich quäle auch keine µC, allerdings ist Multitasking z.B. auch keine 
µC-Domäne, zumindest nicht in der 8Bit-Klasse.

Keis meiner Projekte in den etlichen Jahren verfolgte die Absicht in 
Serie zu gehen, nichtmal direkt nachbaubar mußte es sein. Trotzdem 
wurden einge Sachen erfolgreich nachgebaut, die vor Jahren mal hier ins 
Forum gestellt hatte.

Selbstverständlich löse ich Probleme durch Nutzung von Interrupts wenn 
es das Mittel der Wahl ist. Bin ja mit Z80 und 6502 groß geworden und 
habe nach Jahren Pause die kleinen AVR für mich entdeckt.

Natürlich ist es auch privat immer ein Entscheidungsfaktor, ob man den 
AVR wechselt oder die Plattform oder ob man seinem Ehrgeit folt "das muß 
gehen".
Ich trau mir allerdings die Erfahrung zu, zeitig zu merken, wenn Grenzen 
auftauchen.

Wenn da die Frage kommt: ich will wav-Dateien mit meinem Arduino 
abspielen (wurde woanders gefragt), könnte ich fragen welche. 8Bit 22kHz 
Mono ist machbar ohne sich die Ohren zu brechen von SD-Karte oder 
externem Flash.
44,1kHz 16Bit Mono mit externem SPI-Flsdh und externem 12Bit-SPI-DAC 
kein Problem, selbst schon gemacht.
Allerdings würde ich fürchten, daß das mit den fertigen Arduino-ich kann 
alles aber nichts sonderlich schnell-Libs nicht klappt.

Ist es nun µC quälen, wenn ich sowas dann lieber "zu Fuß" in C schreibe?
Oder in ASM weil mir das Spaß macht und ich es kann?
Ist es quälrn, wenn ich da dann bei einer bestimmten Routine die Takte 
zähle damit es klappt? Wenn ich dabei merke daß es nicht gehen kann, 
dann wechsle ich eben die Plattform. Ich werde nicht fragen, ob es einen 
Geheimbefehl im AVR gibt, der ein PortBit in einem halben CPU-Takt 
setzt.

Ich bastle gerade eine kleine Kiste, die letztlich die Daten meiner 
Sensoren auf einer Webseite anzeigt. Habe ich schon seit Jahren erst mit 
einem AVR-NetIO, dann auf einem RasPi bis es dessen SD-Card zerlegt hat.
Jetzt eben mit ESP8266. Natürlich darf der jetzt im Interrupt den RFM12 
bedienen (ist nur als Empfänger). Macht er auch. Mit meinen 5 Jahre 
alten C-Sourcen von Mega8 in der ArduinoIDE. Da stört auch digitalWrite 
nicht, der 80MHz ESP ist auch mit (hier eher trotz) WLAN schnell genug 
dafür.

Die Firmware-Entwicklungszeit ist zweitrangig, es ist Hobby und muß 
nicht morgen fertig sein.

Natürlich gint es Probleme, wenn jemadn gerade auf dem neuen Arduino-UNO 
eine LED zum Blinken gebracht hat und als nächtes Projekt eine 
Quadcopter plant oder einen selbstfahrenden Roboter mit Home-Funktion.
Der schnelle Erfolg mit dem Blinken verführt zu der Meinung "Hurra, ich 
kann programmieren".

Allerdings war das wor Jahrzehnten auch nicht anders. Wenn ich jemanden 
soviel Basi auf dem C64 beigebracht hatte, daß er eine Uhr programmeiren 
konnte, war di nächte Frag auch "und jetzt zeig mir mal schnell, wie man 
ein schönes Ballerspiel mit Scrolling in beiden Achsen programmiert".

Damals gab es nur noch kein Internet. :-)

Gruß aus Berlin
Michael

: Bearbeitet durch User
von JoJoBa (Gast)


Lesenswert?

Das Thema mit der "Zikluszeit" beim Arduino
hatte mich auch mal interessiert,
deshalb habe ich aus dem web jetzt ausgegraben...

Hier geht es darum, und Beispielcode ist auch dabei;

http://forum.arduino.cc/index.php?topic=292794.0

MfG

von Falk B. (falk)


Lesenswert?

@ Michael U. (amiga)

>Ich quäle auch keine µC, allerdings ist Multitasking z.B. auch keine
>µC-Domäne, zumindest nicht in der 8Bit-Klasse.

Quark. Jedes halbwegs komplexere Programm macht Multitasking. Das 
geht auch ohne Linux und Win10!

von JoJoBa (Gast)


Lesenswert?

Michael U. schrieb:
> warum sollte man rumhacken?

Ich finde es nicht so!
Glaube, dieses Forum lebt davon Meinungen zu eußern und
Erfahrungen auszutauschen.

Es liegt in der Natur der Dinge (oder im Wissenstand) wie und was
die User zum Thema beitragen.

Ich persönlich bin sogar sehr froh drüber, gerade unterschiedliche
Meinungen zu lesen, die geben mir oft einen Anstoß, mich im
web weiter zu informieren und neues aufzuschnappen :-)

...und Lustige Bemerkungen lockern die Athmosphäre.....

von Gerhard O. (gerhard_)


Lesenswert?

Jetzt habe ich nach hinein doch ein schlechtes Gewissen den Beitrag 
voreilig zurück gezogen zu haben, nachdem sich der Ulrich so viel Mühe 
machte darauf einzugehen. Dachte beim Nachlesen ein paar Minuten später, 
ist vielleicht doch nicht so das Thema und drückte den Panikknopf. 
Sorry.

Grüße,
Gerhard

von chris_ (Gast)


Lesenswert?

>Wenn wir also über Arduino und Codgeschwindigkeiten reden, sollten wir
>ganau diese Dinge ausdrücklich vor Augen halten  :-)
>...Arduino wurde ja gerade für Künstler und nichtprogrammierer
>entwickelt!

Hier im Forum gab es mal einen Thread über C++ auf uC. Der war ewig 
lang, aber irgendwo hatte einer der C++ Experten Pin-Funktionen, die den 
Arduinofunktionen sehr ähnlich waren, mit Templates realisiert. Die 
waren genauso schnell wie in Assembler geschrieben.
Eigentlich müsste jemand nur diese Templates in die Arduino-Lib 
einarbeiten, dann hätte sich das Problem erledigt.

Kennt Ihr das: Jemand müsste mal .....

von Gerhard O. (gerhard_)


Lesenswert?

Gerhard O. schrieb:
> der Ulrich so viel Mühe...

Meinte Michael.

Gerhard

von Peter D. (peda)


Lesenswert?

JoJoBa schrieb:
> Die Fortgeschrittenen setzen Assembler ein, die Anfänger eher die
> Arduino-C

Ui, das ist aber ein ganz schmales Brett. Ich kenne keinen 
Fortgeschrittenen, der noch in Assembler programmiert.

Der Arduino in C ist eine perfekte Lösung, damit kann man auch bei 
größeren Projekten einfach weitermachen.
Man muß nur noch das Programmieren lernen, also weg vom Spaghetticode 
und hin zum strukturierten Programmieren (vor dem Coden 
Programmablaufplan erstellen).

von JoJoBa (Gast)


Lesenswert?

Aus den Foren hier kenne ichs nicht, aber
das hier habe ich selber schon ausprobiert;

http://www.breadboarding.de/arduino-c-befehle/

MfG

von JoJoBa (Gast)


Lesenswert?

Und eine sehr interessante Lektüre, die zu
diesem Thread passt ist hier;

http://www.uni-koeln.de/phil-fak/muwi/ag/praktikum/assembler_arduino.pdf

Gruß!

von avr (Gast)


Lesenswert?

chris_ schrieb:
> Eigentlich müsste jemand nur diese Templates in die Arduino-Lib
> einarbeiten, dann hätte sich das Problem erledigt.
>
> Kennt Ihr das: Jemand müsste mal .....

Dann müssten die Leute aber eine neue Syntax lernen, denn Templates 
sehen halt ein bisschen anders aus => Daher wird das wohl auch keinen 
Einzug bei Arduino finden.
Es ist eben für Anfänger und als professionelles HAL nicht zu 
gebrauchen.

von Gerhard O. (gerhard_)


Lesenswert?

Bei uns in der Firma musste letztes Jahr für einen Kunden seine alte 
Hardware einmalig modernisiert werden, in vierzigfacher Ausführung, und 
unter strenger Kosteneinhaltung und Lieferungsfrist modernisiert werden 
weil der alte Hersteller nicht mehr seine Geräte unterstützen wollte und 
es keinen Ersatz auf dem Markt gibt. So wurde auf Arduino MEGA2560 und 
eine in-house gemachter Shield zurückgegriffen. Das war eine 
komplizierte Anwendung mit viel Communication und Real-time Steuerung 
von Motoren und anderer HW und Analogmessungen, PID Schleifen, etz.

Kurz und gut, alles lief Bestens und das Projekt wurde locker 
rechtzeitig fertig. Der MEGA2560 hatte keine Probleme sich den 
Echtzeitsanforderungen zu stellen. Die FW wurde von einem erfahrenen 
Kollegen erstellt und machte überhaupt keine Probleme. Ich schätze, an 
die 30-50K Lines an Source Code enstand dabei. Der FLASH des AVR war zu 
60% gefüllt. Ich hatte nichts damit zu tun, so, weiß ich das jetzt nicht 
genau. Allerdings wurde nicht zu viel Arduino Library Resourcen genutzt. 
Viel C++ war in den Modulen dabei.

Das einzige Problem war die Timing wegen des ungenauen Keramik 
Resonators den wir durch einen externen XTAL Oszillator ersetzen mußten. 
Ein Timer mußte auf 1s in zwei Stunden genau arbeiten und der Keramik 
Resonator ist da einfach nicht gut genug dafür.

Gerhard

von Dr. Sommer (Gast)


Lesenswert?

Gerhard O. schrieb:
> Ich schätze, an
> die 30-50K Lines an Source Code enstand dabei.
Und die wurden alle in der Arduino IDE getippt? Bei der Vorstellung 
graust es mir. Die Arduinos kann man ja normalerweise nicht mal 
step-by-step debuggen...

von Gerhard O. (gerhard_)


Lesenswert?

Dr. Sommer schrieb:
> Und die wurden alle in der Arduino IDE getippt?

Natürlich nicht. Programmer's Notepad oder Code Blocks, glaube ich, 
wars.

Es gibt im IDE nämlich eine Einstellung die es ermöglicht einen externen 
Text Editor zu verwenden mit automatischem Check ob sich der Timestamp 
ändert. Dann braucht man nur wie üblich auf Build/Load drücken.

Abgesehen davon waren da an die 40+ Source und Header Dateien. Das 
Arduino IDE hat ja auch Tabs, wenn auch nicht sehr komfortabel. Aber man 
braucht das IDE ja für nicht mehr wie das Bauen der App und Bootloader. 
Und dafür reicht's ja.

>Die Arduinos kann man ja normalerweise nicht mal
>step-by-step debuggen...

Sooo schlimm war das auch wieder nicht. So viel ich weiß, war nicht viel 
debuggen notwendig.

Du machst wirklich aus einem Maulwurfshügel einen Mt. Everest;-)

Fakt ist, daß alle Anforderungen in der erlaubten Zeit erfüllt worden 
sind und alles einwandfrei funktionierte. Was mehr kann man erwarten?

Ist mal etwas Anderes um zum Ziel zu kommen. Das Resultat zählt.

mfg,
Gerhard

von Dr. Sommer (Gast)


Lesenswert?

Gerhard O. schrieb:
> Du machst wirklich aus einem Maulwurfshügel einen Mt. Everest;-)

Ich weiß nicht, ich habe die Debugging Funktion der Cortex-M sehr zu 
schätzen gelernt, jedes mal wenn ich doch mal einen AVR benutze fluche 
ich dass ich nicht hinein schauen kann.

Wenn ihr dir Arduino IDE nur noch zum Kompilieren benutzt, hat sich 
deren Sinn doch auch erübrigt, und man kann auch in der jeweils 
verwendeten IDE kompilieren & flashen. Und dann kann man auch ein 
nicht-Arduino-Board nehmen welches normal geflasht wird, weil man dann 
nicht mehr den Einschränkungen der Arduino IDE unterliegt.

Wenn man die Arduino Library und die Arduino IDE nicht mehr wirklich 
verwendet, hat man quasi alle "Vorteile" abgelegt und kann Arduino auch 
ganz bleiben lassen, oder? Wenn man sowieso eine eigene Platine (euer 
Shield) entwickelt, kann man da auch noch nen uC drauf designen.

von Gerhard O. (gerhard_)


Lesenswert?

Dr. Sommer schrieb:
> Gerhard O. schrieb:
>> Du machst wirklich aus einem Maulwurfshügel einen Mt. Everest;-)
>
> Ich weiß nicht, ich habe die Debugging Funktion der Cortex-M sehr zu
> schätzen gelernt, jedes mal wenn ich doch mal einen AVR benutze fluche
> ich daß ich nicht hinein schauen kann.
Ich doch auch. Wenn ich mit STM32s arbeite, weiß ich das schon zu 
schätzen. Ist ja klar.
>
> Wenn ihr dir Arduino IDE nur noch zum Kompilieren benutzt, hat sich
> deren Sinn doch auch erübrigt, und man kann auch in der jeweils
> verwendeten IDE kompilieren & flashen. Und dann kann man auch ein
> nicht-Arduino-Board nehmen welches normal geflasht wird, weil man dann
> nicht mehr den Einschränkungen der Arduino IDE unterliegt.
Naja. Ich war ja nicht fürs Projekt verantwortlich. Mein Kollege wird 
natürlich schon einen Grund zu seinem Vorgehen gehabt haben.

Ich habe mal versuchshalber ein Projekt mit CodeVisionAVR gemacht und 
man kann von diesem IDE direkt auch den Arduino Boot Loader verwenden. 
Also, die ARDUINO IDE ist nicht notwendig. Man kann halt nur die 
Hardware nehmen.

AVRDude geht auch unabhängig leicht mit Kommandozeile zu gebrauchen. 
Aber das ist je eh ein alter Hut.
>
> Wenn man die Arduino Library und die Arduino IDE nicht mehr wirklich
> verwendet, hat man quasi alle "Vorteile" abgelegt und kann Arduino auch
> ganz bleiben lassen, oder? Wenn man sowieso eine eigene Platine (euer
> Shield) entwickelt, kann man da auch noch nen uC drauf designen.

Stimmt alles. Ich verwende die ARduino IDE/LIBS auch nur für Open Source 
Projekte von denen ich weiß, daß Arduino gefragt ist. Der Hardware ist 
das wurscht solange die SPI Schnittstelle an der Platine zugänglich ist.

Gerhard

von Marc (Gast)


Lesenswert?

Dr. Uninformed schrieb
>Und die wurden alle in der Arduino IDE getippt?

http://playground.arduino.cc/Code/Eclipse

von Dirk K. (dekoepi)



Lesenswert?

Schneller Test, folgendes Programm in der Arduino 1.6.5-IDE:
1
/*
2
  Arduino Lib vs C
3
  Measure speed of Arduino's digitalWrite() 
4
  vs direct bitmanipulation
5
   */
6
7
#define USE_ARDUINO
8
9
// the setup function runs once when you press reset or power the board
10
void setup() {
11
  // initialize digital pin 13 as an output.
12
  pinMode(13, OUTPUT);
13
  // this part is non critical for the test, thus keep it simple and stupid.
14
  // Pin D13 is actually PB5.
15
}
16
17
// the loop function runs over and over again forever
18
void loop() {
19
#ifdef USE_ARDUINO
20
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
21
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
22
#endif
23
24
#ifndef USE_ARDUINO
25
  PORTB ^= (1<<PB5);  // toggle PB5.
26
#endif
27
}

... aus Faulheit einfach den Blink-Beispiel-Sketch umgestrickt.

Siehe Oszilloskop:
- 500kHz mit Bitmanipulation
- 100kHz via digitalWrite(). (Wohl den Trigger falsch gesetzt wegen 5µs 
Periode erkannt.)

Der Preis der Abstraktion und der Abprüfung zahlreicher Nebenbedingungen 
in der Arduino-Lib.


Und die Frage aller Fragen: Wenn das 2 Takte braucht, wieso stehen da 
nicht 8MHz beziehungsweise 4MHz für die volle Periode? ;)

: Bearbeitet durch User
von D. Z. (Gast)


Lesenswert?

Dirk K. schrieb:
> Und die Frage aller Fragen: Wenn das 2 Takte braucht, wieso stehen da
> nicht 8MHz? ;)

Jetzt müsste man mal testen wie sich das hier im Vergleich schlägt:

http://avr.myluna.de/doku.php

von Rudolph (Gast)


Lesenswert?

Dirk K. schrieb:
> Und die Frage aller Fragen: Wenn das 2 Takte braucht, wieso stehen da
> nicht 8MHz? ;)

Weil die loop() nicht einer while(1)entspricht.
Aber auch die kleinste Schleife wird Zeit benötigen.

Und Exklusiv-Oder wird dann eher nicht zu sbi optimiert.
Probier mal "PINB = (1<<PB5);" zum toggeln.

von Dirk K. (dekoepi)


Lesenswert?

Rudolph schrieb:
> Und Exklusiv-Oder wird dann eher nicht zu sbi optimiert.
> Probier mal "PINB = (1<<PB5);" zum toggeln.

Du meinst wahrscheinlich |= ? So blinkt da wohl eher nichts. ;)
Oder gar, der Fairness halber:

PINB |= (1<<PB5);
PINB &= ~(1<<PB5);

... um dasselbe Konstrukt zu nutzen wie mit digitalWrite()?

: Bearbeitet durch User
von Dirk K. (dekoepi)


Lesenswert?

LunaAVR? Musste erst nachgucken, was das sein soll: Modernes Basic. Da 
schaudert es mich. Basic habe ich seit 1985 nicht mehr angefasst - da 
gab es auf dem C=64 für uns Kinder vom Lande noch nichts anderes und war 
gleich eingebaut. So etwas rühre ich nicht mehr an. (Zumal da dransteht, 
nur für Windows und Linux. Ich nutze Mac OS X.)

: Bearbeitet durch User
von Loddar (Gast)


Lesenswert?

Dirk K. schrieb:
> Du meinst wahrscheinlich |= ? So blinkt da wohl eher nichts. ;)

nein, er meinte schon das, beachte dass da PINB (!!) und nicht PORTB 
steht

Dein Programmvergleich ist auch nicht korrekt,
bei einem machst du in einem loop-DUrchlauf eine Operation,
beim anderen zwei. Dadurch hast du beim ersten den doppelten 
Loop-Overhead

von Dirk K. (dekoepi)


Lesenswert?

Ok, ich stricke heute Abend nach der Arbeit noch mal weiter.

PINB vs PORTB ist schon klar, aber wenn ich einfach den Pin auf 1 setze, 
ohne beispielsweise NOT oder ähnlichem, vermute ich, dass da nichts 
umspringt. Hier ist aber grad noch der Zustand ENOCOFFEE, nachher mit 
klarerem Kopf noch mal ...

von Loddar (Gast)


Lesenswert?

Dirk K. schrieb:
> PINB vs PORTB ist schon klar, aber wenn ich einfach den Pin auf 1 setze,
> ohne beispielsweise NOT oder ähnlichem, vermute ich, dass da nichts
> umspringt.

doch, das ist ein Befehl den die neueren AVR haben:
durch Schreiben auf PINB toggelt der Ausgang

von Dirk K. (dekoepi)


Lesenswert?

Muss man wissen, war mir unbekannt! Lese ich so aus dem Datenblatt zum 
ATmega328 nicht raus. Nettes Feature.

von Hans L. (holzwurm56)


Lesenswert?

Hallo,
wo gibt es einen Logikanalyser für 8,-EUR?

MfG

Hans

von Peter D. (peda)


Lesenswert?

Dirk K. schrieb:
> void loop() {
> #ifdef USE_ARDUINO
>   digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage
> level)
>   digitalWrite(13, LOW);    // turn the LED off by making the voltage
> LOW
> #endif
>
> #ifndef USE_ARDUINO
>   PORTB ^= (1<<PB5);  // toggle PB5.
> #endif
> }

Das ist Apfel mit Birnen vergleichen.
Warum willst Du den Loop Overhead mitmessen und einmal gleich doppelt?
1
void loop() {
2
  for(;;){
3
#ifdef USE_ARDUINO
4
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
5
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
6
#else
7
    PORTB |= (1<<PB5);
8
    PORTB &= ~(1<<PB5);
9
#endif
10
  }
11
}

von Dirk K. (dekoepi)


Lesenswert?

@Peter: Das erwähnte ich selbst schon hier: 
Beitrag "Re: Geschwindigkeit Arduino > C"

Aber Danke für die Bestätigung.

: Bearbeitet durch User
von Rudolph R. (rudolph)


Lesenswert?

Dirk K. schrieb:
> Lese ich so aus dem Datenblatt zum
> ATmega328 nicht raus. Nettes Feature.

Kapitel 14.2.2 Toggling the Pin

---
Writing a logic one to PINxn toggles the value of PORTxn, independent on 
the value of DDRxn. Note that the SBI instruction can be used to toggle 
one single bit in a port.
---

von Michael U. (amiga)


Lesenswert?

Hallo Falk,

Falk B. schrieb:
> @ Michael U. (amiga)
>
>>Ich quäle auch keine µC, allerdings ist Multitasking z.B. auch keine
>>µC-Domäne, zumindest nicht in der 8Bit-Klasse.
>
> Quark. Jedes halbwegs komplexere Programm macht Multitasking. Das
> geht auch ohne Linux und Win10!

naja, die auf einem 8Bit-AVR wäre wohl auch ein klein wenig 
problematisch.
Ich habe das so gesagt, weil relativ selten ein OS auf dem 8Bit AVR 
läuft.
Wenn Multitasking nur sagen soll, daß mehrere Sachen scheinbar 
gleichzeitig bearbeitet werden sollen, dann ist selbst BlinkWithoutDelay 
auf dem Arduino bereits Multitasking.

Gruß aus Berlin
Michael

von Rudolph R. (rudolph)


Lesenswert?

Michael U. schrieb:
> naja, die auf einem 8Bit-AVR wäre wohl auch ein klein wenig
> problematisch.
> Ich habe das so gesagt, weil relativ selten ein OS auf dem 8Bit AVR
> läuft

Dir ist aber schon klar, dass es verschiedene Level an Multitasking 
gibt?

Den einfachen Scheduler den ich immer benutze um einfaches kooperatives 
Multi-Tasking mit typisch vier Tasks zu machen würde ich nicht als 
Betriebs-System beschreiben.
Und nein, Interrupts zähle ich nicht zu den "Tasks".

von chris_ (Gast)


Lesenswert?

>wo gibt es einen Logikanalyser für 8,-EUR?

Nicht ganz 8€
http://www.amazon.de/Saleae-Analyzer-8Channel-saleae-support/dp/B00EEWBPU4

von Falk B. (falk)


Lesenswert?

@  Michael U. (amiga)

>Ich habe das so gesagt, weil relativ selten ein OS auf dem 8Bit AVR
>läuft.

Das sag es aber EXPLIZIT!

>Wenn Multitasking nur sagen soll, daß mehrere Sachen scheinbar
>gleichzeitig bearbeitet werden sollen, dann ist selbst BlinkWithoutDelay
>auf dem Arduino bereits Multitasking.

Das ist es auch! Für Multitasking braucht man nicht unbedingt ein OS 
oder RTOS.

von Ulrich F. (Gast)


Lesenswert?

Falk B. schrieb:
> Für Multitasking braucht man nicht unbedingt ein OS
> oder RTOS.

Umgekehrt wird da ein Schuh draus.
Es macht Sinn wenn ein OS Multitasking kann.

Was ist überhaupt ein OS?
Ab wann kann man es als solches Bezeichnen?
Ist RTOS schon ein OS?


Die AVRs bringen keinerlei Hardwareunterstürzung für Multitasking mit. 
Kein Speicherschutz, nix.

Kooperatives Multitasking in der AVR Welt sieht wohl mehr nach Polling 
aus. Klar kann man das sich den Mist schön reden, wird er aber nicht.

Eine Höllenarbeit, jeden Algorithmus so zu zerrupfen, dass er in kleinen 
Häppchen abgearbeitet werden kann. Aber wenigstens hat man den 
Algorithmus nach dem Umbau verstanden.
Lesbarer wird ein solches Programm, durch die Kur, nicht.

Also: Notwendig, ja, aber schön..?

von Rudolph R. (rudolph)


Lesenswert?

Ulrich F. schrieb:
> Die AVRs bringen keinerlei Hardwareunterstürzung für Multitasking mit.
> Kein Speicherschutz, nix.

Was hat Speicherschutz mit Multitaskung zu tun?
Klar ist das hübsch und sicher, aber keine Grundvorraussetzung.
AmigaOS war 1985 auch Multi-Tasking und gänzlich ohne MMU.
Da war es auch ohne Probleme möglich das System zu übernehmen oder 
abstürzen zu lassen, Multi-Tasking war das trotzdem.

> Kooperatives Multitasking in der AVR Welt sieht wohl mehr nach Polling
> aus. Klar kann man das sich den Mist schön reden, wird er aber nicht.

Kooperatives Multitasking bedeutet, dass ein Task die Kontrolle wieder 
abgeben muss, die wird ihm nicht entzogen.

Polling bedeutet, solange zu warten bis ein Ereignis eintritt.
Multitasking wäre jetzt jedesmal auf das Eintreten des Ereignisses zu 
prüfen wenn der Task aufgerufen wird.

von Michael U. (amiga)


Lesenswert?

Hallo,

ich habe es irgendwie geahnt, daß es zur Grundsatzdiskussion wird...

@Ulrich F.: ich stimme Dir und Deinen Fragen voll zu.
Multitasking ist ein Begriff der bestimmte Bedingungen erfüllt.

Die erfüllen die Ansätze auf dem AVR ohne OS nicht.
Für Multitasking ist das OS verantwortlich, es stellt den Scheduler zur 
Verfügung, es ist für Kommunikation zwischen den Prozessen 
verantwortlich usw.

Speicherschutz ist wichtig, aber nicht zwingend. Musterbeispiel ist das 
alte AmigaOS. Preemptives Multitasking, Semaphorenverwaltung usw.
Natürlich konnte jeder Amok laufende Task das ganze System zerlegen...

Trotzdem hat es Spaß gemacht, da zu programmieren.

Polling ist üblich auf kleinen AVR, (Timer-)Interruptgesteuerte 
Abarbeitung auch, erinnert mehr an die alten TSR-Programme von MS-DOS.

Letztlich diskutieren wir aber dann darüber, welchen Namen das Kind 
bekommen soll.

BlinkWithoutDelay z.B. ist kein Multitasking, die Prozesse sind nicht 
unabhängig voneinander, man hat den Prozessor während der Abarbeitung 
NICHT für sich allein. Das wäre für mich aber Bedingung, wenn es 
Multitasking heißen soll.

Gruß aus Berlin
Michael

von Falk B. (falk)


Lesenswert?

@  Ulrich F. (combie)


>> Für Multitasking braucht man nicht unbedingt ein OS
>> oder RTOS.

>Umgekehrt wird da ein Schuh draus.
>Es macht Sinn wenn ein OS Multitasking kann.

Das war gar nicht die Ausgangsfrage.

>Ist RTOS schon ein OS?

Logisch, das steckt ja schon in der Abkürzung drin!

>Die AVRs bringen keinerlei Hardwareunterstürzung für Multitasking mit.
>Kein Speicherschutz, nix.

Wozu auch, in der Liga braucht man das nicht!

>Kooperatives Multitasking in der AVR Welt sieht wohl mehr nach Polling
>aus.

Nö. Es ist und bleibt kooperatives Multitasking.

> Klar kann man das sich den Mist schön reden, wird er aber nicht.

Jaja.

>Eine Höllenarbeit, jeden Algorithmus so zu zerrupfen, dass er in kleinen
>Häppchen abgearbeitet werden kann.

Das machen teilweise sogar die Profis und das sehr gern. Stichwort 
Testbarkeit und Determiniertheit.

> Aber wenigstens hat man den
>Algorithmus nach dem Umbau verstanden.

Siehst du!

>Lesbarer wird ein solches Programm, durch die Kur, nicht.

Ansichtssache ;-)

>Also: Notwendig, ja, aber schön..?

Doch. Denn auch präemtive Tasks müssen sich meist in State Machines 
organisieren.

von Joerg W. (joergwolfram)


Lesenswert?

Universelle Routinen, insbesondere wenn sie auf mehereren 
Controllerfamilien laufen sollen, müssen halt Kompromisse machen. Und 
wenn I/O Routinen Port und Pin als Variablen erlauben sollen, wirds auf 
vielen Plattformen schnell haarig. Bis auf PIC (PIC-Assembler kann ich 
noch nicht) und PowerPC (Pins sind sowieso einzeln adressierbar) habe 
ich mir schnelle ASM-Routinen dafür geschrieben. Dafür läuft der 
folgende Code mit kleinen Anpassungen (Pins, PLL_Setting) inzwischen auf 
7 verschiedenen Controllerfamilien (ohne Interrupts sind es noch mehr).
1
#include "board.h"
2
3
#define LED_RED PORT_B,3
4
#define LED_GREEN PORT_D,2
5
6
void user_tick()
7
{
8
9
}
10
11
12
main()
13
{
14
    int state=0;
15
16
    set_clock(CLOCK_8_16); //PLL setting
17
    enable_tick(16000);    //1ms Tick interrupt
18
    enable_interrupts();
19
    set_portpin_output(LED_RED);
20
    set_portpin_output(LED_GREEN);
21
22
    for(;;)
23
    {
24
        set_portpin_level(LED_RED,state);
25
        set_portpin_level(LED_GREEN,1-state);
26
        wait_ticks(500);
27
        state=1-state;
28
        set_portpin_level(LED_RED,state);
29
        set_portpin_level(LED_GREEN,1-state);
30
        wait_ticks(500);
31
        state=1-state;
32
    }
33
}

PORT_B ist dann z.B. eine Konstante, die als Offset auf eine 
Registertabelle im Flash verwendet wird. Ebenso mache ich das mit den 
Pin-Nummern, für die es eine Tabelle mit meist 8 Maskenwerten gibt. Die 
ursprüngliche C-variante war ein Mehrfaches langsamer als eine direkte 
I/O-Byte Zuweisung und auch die ASM-Variante braucht noch ca. 5-10x 
soviel Takte. Aber damit kann ich leben...

Jörg

von Falk B. (falk)


Lesenswert?

@ Michael U. (amiga)

>Multitasking ist ein Begriff der bestimmte Bedingungen erfüllt.

Welche denn?

>Die erfüllen die Ansätze auf dem AVR ohne OS nicht.

Ohne sie zu nennen, kann man die Frage wohl kaum beantworten ;-)

>Für Multitasking ist das OS verantwortlich, es stellt den Scheduler zur
>Verfügung, es ist für Kommunikation zwischen den Prozessen
>verantwortlich usw.

Nö, das ist eine spezielle Form davon. Ganz allgemein hat das mit einem 
OS rein GAR NICHTS zu tun!

>Speicherschutz ist wichtig, aber nicht zwingend. Musterbeispiel ist das
>alte AmigaOS.

Weil es damals (tm) technisch nicht verfügbar war.

> Preemptives Multitasking, Semaphorenverwaltung usw.
>Natürlich konnte jeder Amok laufende Task das ganze System zerlegen...

Alles richtig, aber alles schon speziell.

>Trotzdem hat es Spaß gemacht, da zu programmieren.

In ASM! Cool!

>Letztlich diskutieren wir aber dann darüber, welchen Namen das Kind
>bekommen soll.

Nein, welche Eigenschaft zu Multitasking in seiner Minimalform benötigt 
werden.

>BlinkWithoutDelay z.B. ist kein Multitasking, die Prozesse sind nicht
>unabhängig voneinander,

Doch.
> man hat den Prozessor während der Abarbeitung
>NICHT für sich allein.

Aber sicher! Ausserdem haben das präemtive Tasks auch nur für kurze 
Zeit!

>Das wäre für mich aber Bedingung, wenn es
>Multitasking heißen soll.

Also ist für dich Multitasking nur auf Mehrkern-CPUs möglich. Damit war 
alles davor, auch Win2K etc. KEIN Multitasking. Komische Definition. 
Gefällt mir keine Sekunde.

von Michael U. (amiga)


Lesenswert?

Falk B. schrieb:
> @ Michael U. (amiga)
>
>>Multitasking ist ein Begriff der bestimmte Bedingungen erfüllt.
>
> Welche denn?
>
>>Die erfüllen die Ansätze auf dem AVR ohne OS nicht.
>
> Ohne sie zu nennen, kann man die Frage wohl kaum beantworten ;-)
>
>>Für Multitasking ist das OS verantwortlich, es stellt den Scheduler zur
>>Verfügung, es ist für Kommunikation zwischen den Prozessen
>>verantwortlich usw.
>
> Nö, das ist eine spezielle Form davon. Ganz allgemein hat das mit einem
> OS rein GAR NICHTS zu tun!
Ich sage doch, wir befassen uns damit, dem Kind einen Namen zu geben.
Wenn wir davon reden, daß auf einem System irgendwie mehrere Sachen 
scheinbar gleichzeitig bearbeitet werden, stimme ich Dir zu.
Ich habe aber die allgemeine Definition von Multitasking nicht erfunden 
und die sagt etwas anderes.
Die Frage, was ein OS ist, lassen wir mal außen vor.
Irgendeine Verwaltungseinheit kümmert sich um das Zusammenspiel, der 
Scheduler. Egal, wie simple der ist.
Auch beim kooperativen Multitasking entscheider der (und nur der) 
welcher Task nach Priotitäten oder Reihenfolge als nächster dran ist.
Jeder Task hat die CPU in dieser Zeit komplett für sich alleine im 
eigenen Kontext. Der Scheduler muß sich darum kümmern, alles zu sichern, 
was dem vorigen Task gehört (Register, Stackframe usw.).

>> Preemptives Multitasking, Semaphorenverwaltung usw.
>>Natürlich konnte jeder Amok laufende Task das ganze System zerlegen...
>
> Alles richtig, aber alles schon speziell.
Darunter liegt nur noch das alte Windows mit seinem koperativen 
Multitasking, anderes OS habe ich jetzt nicht in Erinnerung bzw. bin 
nicht damit in Berührung gekommen.

>>Trotzdem hat es Spaß gemacht, da zu programmieren.
>
> In ASM! Cool!
Nur kurz, 68k-ASM war mir damsl für meine Projekte zuviel Einarbeitung, 
also wurde es schlimmer: AmigaE...

>>Letztlich diskutieren wir aber dann darüber, welchen Namen das Kind
>>bekommen soll.
>
> Nein, welche Eigenschaft zu Multitasking in seiner Minimalform benötigt
> werden.
>
>>BlinkWithoutDelay z.B. ist kein Multitasking, die Prozesse sind nicht
>>unabhängig voneinander,
>
> Doch.
>> man hat den Prozessor während der Abarbeitung
>>NICHT für sich allein.
>
> Aber sicher! Ausserdem haben das präemtive Tasks auch nur für kurze
> Zeit!
Richtig. Bei BlinkWithoutDelay aber nur, weil der Compiler sich darum 
kümmert, ein spezielles Stück Software einzubauen, daß die konkret 
beutzen Register einer aufgerufenen Funktion rettet und wiederherstellt 
usw.

Wenn ich auf einem Multitasking-"OS" einen neuen Task brauche, rufe ich 
CreateTask() auf und bekomme mein eigenes Umfeld "von oben".
Natürlich macht eine Abfrage in einer main-loop, ob was zu tun ist und 
fer Funktionsaufruf funktionell ähnliches, eigentlich beschreibt aber 
Multitasking gerade die organisatorische Trennung dieser Ebenen.

Eigentlich ist das alles nicht meine Schiene, ich nehme da, was für 
meine Anwendung am besten passt und frage mich nicht, ob das nun schon 
Multitasking in irgendeinem definierten Sinn ist. ;-)

>
>>Das wäre für mich aber Bedingung, wenn es
>>Multitasking heißen soll.
>
> Also ist für dich Multitasking nur auf Mehrkern-CPUs möglich. Damit war
> alles davor, auch Win2K etc. KEIN Multitasking. Komische Definition.
> Gefällt mir keine Sekunde.

Selbstberständlich ist das Multitasking auch in meinem Sinn, es gibt 
einen Task-Scheduler, der sich um den Verwaltungskram kümmert, und meine 
Software, die ich als Task einhänge und nutze.
Mich kümmert in diesem Momant aber nicht, was da sonst alles im 
Hintergrund läuft, ich muß es nichtmal wissen. Auch beim AmiagOS nicht.

Gruß aus Berlin
Michael

von Ulrich F. (Gast)


Lesenswert?

Falk B. schrieb:
> Also ist für dich Multitasking nur auf Mehrkern-CPUs möglich.

Multitasking in seinen verschiedensten Ausprägungen.
Multithreading.
Prozesse und Prozessorkerne.

Weit über ein 1/2 Jahrhundert Erfahrung und Entwicklungen, auf dem 
Gebiet.
Und wie viel haben wir davon auf den kleinen AVRs?
Faustkeile...
Steinzeit, in Sachen Multitasking!
Mehr geben die Ressourcen einfach nicht her.

von Wolfsente (Gast)


Lesenswert?

Was ist denn schneller zum toggeln?

PINx |= 1<<3;
oder
PINB ^= 1<<3;

oder bleibts sich gleich?

Gruß
Wolfsente?

von Wolfsente (Gast)


Lesenswert?

Sry meinte

PINx |= 1<<3

oder

PORTx ^= 1<<3

von Michael U. (amiga)


Lesenswert?

Hallo,

PINx erfordert nur einen Schreibzugriff, PORTx ist ein 
read-modify-write.

Gruß aus Berlin
Michael

von Rudolph R. (rudolph)


Lesenswert?

Einfach mal compilieren und das erzeugte .lss File checken:

  PORTB |= (1<<PB2);
  80:  2a 9a         sbi  0x05, 2  ; 5

  PINB = (1<<PB2);
  82:  94 e0         ldi  r25, 0x04  ; 4
  84:  93 b9         out  0x03, r25  ; 3

  PORTB ^= (1<<PB2);
  86:  85 b1         in  r24, 0x05  ; 5
  88:  89 27         eor  r24, r25
  8a:  85 b9         out  0x05, r24  ; 5

Natürlich mit Optimierung, ich habe -Os drin.

Und wie man sieht gewinnt die erste Variante unter C sogar.

Dann eben doch so:

  PINB |= (1<<PB2);
  82:  1a 9a         sbi  0x03, 2  ; 3

Dann bekommt der Compiler das auch richtig optmiert.

von Wolfsente (Gast)


Lesenswert?

Michael U. schrieb:
> PINx erfordert nur einen Schreibzugriff, PORTx ist ein
> read-modify-write.

Also ist mit PINx schneller?
und warum ist es nur ein schreibzugriff?
weil bei PINx mach ich ja auch ne verODERung....

oder dauert ein XOR länger?

von Peter II (Gast)


Lesenswert?

Wolfsente schrieb:
> und warum ist es nur ein schreibzugriff?

weil die Hardware das "toggeln" übernimmt. Es muss halt nicht in 
Software gemacht werden.
Das ist wie die Betätigung eines Tasters. Bei einen Schalter muss du 
vorher nachschauen ob das Licht an oder Aus ist, ein Taster kannst du 
einfach drücken.

von Wolfsente (Gast)


Lesenswert?

vielen dank!
Find sowas immer richtig interessant. Ich sollte mich mal mehr mit 
assembler beschäftigen, dann könnte man sich sowas auch selber denken :D

von avr (Gast)


Lesenswert?

Rudolph R. schrieb:
> Und wie man sieht gewinnt die erste Variante unter C sogar.
>
> Dann eben doch so:
>
>   PINB |= (1<<PB2);
>   82:  1a 9a         sbi  0x03, 2  ; 3

Naja, da ist eigentlich nichts gewonnen. Bei normalen AVRs dauert 
sbi/cbi 2 Takte. Also genau so lange wie ein ldi+out. Mit out ist man am 
schnellsten Wenn der Compiler das entsprechende CPU-Register außerhalb 
der Schleife setzt.

von chris_ (Gast)


Lesenswert?

Ich habe gerade 6.3us für digitalWrite(13,x) auf einem Arduino Nano 
gemessen.

von Oliver S. (oliverso)


Lesenswert?

Ein einzelnes Bit an einem Port zu setzen oder löschen, ohne die andern 
zu verändern, geht aber nicht per ldi+out. Ist daher zwar genauso 
schnell, aber falsch.

Oliver

von Dirk K. (dekoepi)


Lesenswert?

Laut Datenblatt geht das aber schon - mit diesem speziellen Register. 
Habe den Hinweis oben geprüft, steht tatsächlich im ATmega328-DB unter 
14.2.2. Toggle Pin.

von Falk B. (falk)


Lesenswert?

@Michael U. (amiga)


>> Nö, das ist eine spezielle Form davon. Ganz allgemein hat das mit einem
>> OS rein GAR NICHTS zu tun!
>Ich sage doch, wir befassen uns damit, dem Kind einen Namen zu geben.

Den Namen haben wir schon, nämlich Multitasking! Die Frage ist, welche 
Eigenschaften damit MINDESTENS verbunden sind!

>Wenn wir davon reden, daß auf einem System irgendwie mehrere Sachen
>scheinbar gleichzeitig bearbeitet werden, stimme ich Dir zu.

Gut.

>Ich habe aber die allgemeine Definition von Multitasking nicht erfunden
>und die sagt etwas anderes.

Und WAS genau?

>Die Frage, was ein OS ist, lassen wir mal außen vor.

Gut.

>Irgendeine Verwaltungseinheit kümmert sich um das Zusammenspiel, der
>Scheduler. Egal, wie simple der ist.

Gut.

>Auch beim kooperativen Multitasking entscheider der (und nur der)
>welcher Task nach Priotitäten oder Reihenfolge als nächster dran ist.
>Jeder Task hat die CPU in dieser Zeit komplett für sich alleine im
>eigenen Kontext.

OK.

> Der Scheduler muß sich darum kümmern, alles zu sichern,
>was dem vorigen Task gehört (Register, Stackframe usw.).

Nö, das macht schon der Compiler, so weit muss man da praktisch nicht 
runter.


>> In ASM! Cool!
>Nur kurz, 68k-ASM war mir damsl für meine Projekte zuviel Einarbeitung,
>also wurde es schlimmer: AmigaE...

Sachen gibt . . . ;-)

>> Aber sicher! Ausserdem haben das präemtive Tasks auch nur für kurze
>> Zeit!
>Richtig. Bei BlinkWithoutDelay aber nur, weil der Compiler sich darum
>kümmert, ein spezielles Stück Software einzubauen, daß die konkret
>beutzen Register einer aufgerufenen Funktion rettet und wiederherstellt
>usw.

Das macht er bei jeder 08/15 Funktion! Du bist schon wieder auf dein 
präemtives OS fixiert!

>Wenn ich auf einem Multitasking-"OS" einen neuen Task brauche, rufe ich
>CreateTask() auf und bekomme mein eigenes Umfeld "von oben".

Sicher, aber das ist ein fortgeschrittener Spezialfall!

>Natürlich macht eine Abfrage in einer main-loop, ob was zu tun ist und
>fer Funktionsaufruf funktionell ähnliches, eigentlich beschreibt aber
>Multitasking gerade die organisatorische Trennung dieser Ebenen.

>Eigentlich ist das alles nicht meine Schiene, ich nehme da, was für
>meine Anwendung am besten passt und frage mich nicht, ob das nun schon
>Multitasking in irgendeinem definierten Sinn ist. ;-)

Damit hast du aber keine belastbare Definition von "Multitasking". 
Meine, ganz allgemein und grundlegende ist die hier.

https://www.mikrocontroller.net/articles/Multitasking#Einleitung

"Multitasking bedeutet ein scheinbar paralleles Ausführen von mehreren 
Prozessen auf einem Prozessor"

Ob nun kooperativ, präemtiv oder sonstwas ist egal, das sind spezielle 
Umsetzungen des grundlegenden Gedankens! So wie BMW und Mercedes 
spezielle Autos sind! Auch der Trabbi ist ein Auto!

von Falk B. (falk)


Lesenswert?

@  Ulrich F. (combie)

>Multitasking in seinen verschiedensten Ausprägungen.
>Multithreading.
>Prozesse und Prozessorkerne.

Sicher, das war aber gar nicht die Frage.

>Weit über ein 1/2 Jahrhundert Erfahrung und Entwicklungen, auf dem
>Gebiet.
>Und wie viel haben wir davon auf den kleinen AVRs?
>Faustkeile...
>Steinzeit, in Sachen Multitasking!
>Mehr geben die Ressourcen einfach nicht her.

Das war auch nicht die Frage. Sondern ob es auf einem 8 Bit (AVR) 
überhaupt angewendet wird. Und das wird es, sehr oft (wenn gleich nicht 
bei den "Patienten" des Forums ;-)

von Peter D. (peda)


Lesenswert?

Multitasking ohne OS ist gar nicht kompliziert. Man muß nur seine 
Programmsicht ein klein wenig umstellen. Immer, wenn auf irgendwas 
gewartet werden soll, tut man das nicht direkt, sondern kehrt zum Main 
zurück, Und die Stelle, an der man gerade war, merkt man sich als State 
(switch/case).
Dafür wird man dann auch belohnt mit mehr Übersichtlichkeit und 
Vorhersehbarkeit. Man braucht kein umständlichen Lock-Mechanismen und 
Datenübergaben, da jede Task ganz genau weiß, wann sie unterbrochen 
werden kann und das nicht dem Zufall überlassen muß.

von Dirk K. (dekoepi)



Lesenswert?

Endlich Feierabend - Hund geschwenkt, und ran an das Oszilloskop :D

Leicht erweiterter Code, ich denke, da sind jetzt alle Varianten drin:
1
/*
2
  Arduino Lib vs C
3
  Measure speed of Arduino's digitalWrite() 
4
  vs direct bitmanipulation
5
   */
6
#define IS_POPE_CATHOLIC 1
7
//#define USE_ARDUINO
8
//#define USE_PINx
9
#define USE_PORTx
10
11
// the setup function runs once when you press reset or power the board
12
void setup() {
13
  // initialize digital pin 13 as an output.
14
  pinMode(13, OUTPUT);
15
  // this part is non critical for the test, thus keep it simple and stupid.
16
  // Pin D13 is actually PB5.
17
}
18
19
// the loop function runs over and over again forever
20
void loop() {
21
22
  while (IS_POPE_CATHOLIC) {
23
#ifdef USE_ARDUINO
24
  digitalWrite(13, HIGH);
25
  digitalWrite(13, LOW);
26
#endif
27
28
#ifdef USE_PINx
29
  PINB = (1<<PB5);  // toggle PB5.
30
#endif
31
32
#ifdef USE_PORTx
33
  PORTB |= (1<<PB5);
34
  PORTB &= ~(1<<PB5);
35
#endif
36
  }
37
}

Screenshots im Anhang.

1) Arduino-Lib/digitalWrite(): 100 kHz.
2) Bitmanipulation/PINx-Toggle: 2,6 MHz.
3) Bitmanipulation/PORTx: 2,6 MHz. Duty-Cycle der resultierenden PWM ist 
geringer als beim "Hardware-gesteuerten Toggle" via PINx.

von Rudolph R. (rudolph)


Lesenswert?

Also wenn soltest Du das toggle auch zwei Mal machen.
1
#ifdef USE_PINx
2
  PINB = (1<<PB5);  // toggle PB5.
3
  PINB = (1<<PB5);  // toggle PB5.
4
#endif

Der einzige Unterschied der da noch bleibt ist das man vorher nicht 
wissen muss, wie das Bit stand.

Dirk K. schrieb:
> 3) Bitmanipulation/PORTx: 2,6 MHz. Duty-Cycle der resultierenden PWM ist
> geringer als beim "Hardware-gesteuerten Toggle" via PINx.

Logisch, da ist ja immer noch die Schleife mit drin.
Beim Toggle auch, nur eben im Moment doppelt.

von Dirk K. (dekoepi)



Lesenswert?

Das hätte ich nicht erwartet. PINx-Toggle zweimal am Stück - zack, da 
sind die 4 MHz :)

Aus Spaß auch noch die XOR-PORTx-Variante abgeprüft: 2 MHz, also wie vom 
Assembler-Compilat oben zu erwarten die tatsächlich langsamste Variante 
- aber noch immer Welten vor Arduino-Lib.

von Michael U. (amiga)


Lesenswert?

Hallo,

@Falk Brunner (falk):

naja, ich sehe da keinen direkten Widerspruch.

Dieser Satz steht da ja auch drin:
Das Herz jedes Multitasking-Systems ist der Scheduler. Dies ist ein 
Programm, das nach bestimmten Algorithmen überprüft, welcher Prozess als 
nächstes die CPU (also Rechenzeit) zugeteilt bekommt. Es gibt 
verschiedene Schedulingstrategien: usw.

Die while(1)-Loop ist der Scheduler, hier eben reines kooperatives 
Multitasking. Der Scheduler wartet, bis der ausgeführte Task ihm die 
Kontrolle zurückgibt.

Eigentlich hatte Rudolph R.(rudolph) um 12:41 schon die beste Definition 
geliefert, habe ich wohl übersehen:

> Polling bedeutet, solange zu warten bis ein Ereignis eintritt.
> Multitasking wäre jetzt jedesmal auf das Eintreten des Ereignisses zu
> prüfen wenn der Task aufgerufen wird.

Beim angesprochenen BlinkWithoutDelay wäre da auch genau der 
Unterschied:
ist die Abrfage mach den vergangenen ms in der loop() und diese schaltet 
bei Erreichen des Wertes die LED ist es Polling.
Wird eine blink() aufgerufen und dort wird entschieden, was passiert, 
ist es kooperatives Multitasking, zumindest, wenn alle Funktionen in der 
loop() so behandelt werden. Dann ist das der Scheduler.
Natürlich kann man das beliebig mischen, aber spätestens dann wird die 
Beriffsbestimmung eben ein Problem.

Darauf habe ich mich bezogen: nicht alles, was "gleichzeitig" auf einem 
AVR gemacht wird, ist Multitasking. Das hat zwingend mit OS u.ä. nichts 
zu tun.

Gruß aus Berlin
Michael

von chris (Gast)


Lesenswert?

>Das hätte ich nicht erwartet. PINx-Toggle zweimal am Stück - zack, da sind die 4 
MHz :)
Das nennt sich loop unrolling. Wenn man die Asymmetrie in Kauf nimmt, 
geht da noch mehr.

von Rudolph R. (rudolph)


Lesenswert?

chris schrieb:
> Das nennt sich loop unrolling. Wenn man die Asymmetrie in Kauf nimmt,
> geht da noch mehr.

Jain, das Ziel war eher Symmetrie im Test und sowieso macht es keinen 
Sinn für den Vergleich der Zugrife die Schleife mit drin zu haben.
1
  digitalWrite(13, HIGH);
2
  digitalWrite(13, LOW);
3
  PINB = (1<<PB5);  // toggle PB5.
4
  PINB = (1<<PB5);  // toggle PB5.
5
  PORTB |= (1<<PB5);
6
  PORTB &= ~(1<<PB5);

Das ist soweit äquivalent.
Und wenn man jetzt wissen will, wie schnell die einzelnen Blöcke für 
sich sind, dann sollte man sie mehrere Male hintereinander ausführen um 
den Einfluss der Schleife los zu werden.
1
  digitalWrite(13, LOW);
2
  delayMicroseconds(10); 
3
4
  digitalWrite(13, HIGH);
5
  digitalWrite(13, LOW);
6
  digitalWrite(13, HIGH);
7
  digitalWrite(13, LOW);
8
  digitalWrite(13, HIGH);
9
  digitalWrite(13, LOW);
10
11
  delayMicroseconds(10);
1
  digitalWrite(13, LOW);
2
  delayMicroseconds(10); 
3
4
  PINB = (1<<PB5);
5
  PINB = (1<<PB5);
6
  PINB = (1<<PB5);
7
  PINB = (1<<PB5);
8
  PINB = (1<<PB5);
9
  PINB = (1<<PB5);
10
11
  delayMicroseconds(10);

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.