moderne Controller werden immer schneller getaktet - nur was kommt dabei an den IO-Pins davon an? Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high und dann wieder low zu setzen. Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat. Das ist also Welten langsamer. Wer nun Peripherie an IO-Pins anschließt und mit Pinsetz-/Pinrücksetzbefehlen arbeitet wird langsamer sein als mit AVR. Warum nur sind Arm scheinbar so langsam? Oder ist das ein Messfehler? Sind AVR wirklich so viel schneller? Wie sieht es mit MSP430 aus?
Matthias W. schrieb: > sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat. Dann suche weiter nach anderen Bildern. Oder mach dir selbst ein Bild. Matthias W. schrieb: > Das ist also Welten langsamer. Ja, Rückschritt statt Fortschritt!
Matthias W. schrieb: > Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high > und dann wieder low zu setzen. Bei welchem Takt? Wäre hier eine Angabe der Taktanzahl nicht zielführender? Grundsätzlich braucht ein AVR zum Toggeln nur einen Befehl, wenn man auf das PIN Register schreibt. Dazu kommen 2 Takte für den Sprung der Endlosschleife. > Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll > sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat. > Das ist also Welten langsamer. Bei ARM sieht das im Prinzip ähnlich aus. Selbst wenn man Read-Modify-Write machen müsste, wären das ein paar Takte mehr, aber beim vielfachen der Taktfrequenz wäre der ARM immernoch deutlich schneller und nicht um Größenordnungen langsamer Außerdem sagt 8 Bitter vs. 32 Bitter nichts über die Geschwindigkeit aus, und schon gar nicht bei Pin-Toggle Aufgabenstellungen. Die 32 Bit haben die Vorteil an ganz anderer Stelle (Arithmetik, Adressraum usw.). Welcher ARM, bei welchem Takt? Und du hast irgendein Beispiel, irgendwo im Netz gesehen und verallgemeinerst das jetzt? Auf so einer Grundlage kann man nicht vernünftig diskutieren. Zeig deine konkreten Beispiele an hand derer du deine kruden Thesen/Fragestellungen ableitest.
:
Bearbeitet durch User
Cyblord -. schrieb: > Grundsätzlich braucht ein AVR zum Toggeln nur einen Befehl, wenn man auf > das PIN Register schreibt. Dazu die Takte der Endlosschleife. Oder wenn > du einmalig setzen und löschen willst, reichen 2 Befehle, die in 2 In der Endlosschleife benötigt er 4 Takte. Das ergibt bei einem 8MHz Takt eine Signalrate von 2MHz. Matthias W. schrieb: > Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high > und dann wieder low zu setzen. Ohne Angabe vom Takt, welcher bei beiden gleich sein sollte für diesen Vergleich, nützt diese Messung nichts weil nicht gleiches mit gleichem verglichen wird.
:
Bearbeitet durch User
Mithilfe der Timer-Module kann man auf (fast?) allen ARM's einen Takt ausgeben mit dem man einen AVR (z.T. um ein Vielfaches) übertakten könnte.
Uhrmacher schrieb: > mach dir selbst ein Bild. ich habe selbst noch keinen Arm und keine vergleichbare Umgebung zum AVR mit Make, Avrdude, Gcc.
Kann ein Softwareproblem sein. Früher als richtige Männer noch richtige Männer waren, wurden IO_Pins direkt aka baremetal programmiert. Da konnte man das noch in ein paar Takten erledigen. Heutzutage muss der UserTask warten bis der Taski-scheduler ihn ranlässt, dann checkt der MemMapper ob der User überhaupt auf dem Mem-Bereich zugreifen darf und schliesslich muss der Treiber durch etliche HAL's durchgreifen bis sich schlussendlich an dem Port was tut. Da war selbst der mit 0,985248 MHz getatktete C64 mit dem BASIC-Befehl POKE 56577,255 schneller ...
Cyblord -. schrieb: > verallgemeinerst das jetzt? nein. Ich bin lediglich neugierig warum die einfache Aufgabe einen Pin mal high und dann low zu setzen auf dem Arm der mehr Taktfrequenz hat als der AVR fast Faktor 10 länger dauert. So sah es für mich aus. Korrigiert mich wenn es nicht so ist. Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar.
Matthias W. schrieb: > Beispiel: Ein 8bit-AVR braucht 375ns um in einer Schleife einen Pin high > und dann wieder low zu setzen. > > Bei einem Arm-Prozessor (32bit) der angeblich viel schneller sein soll > sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat. Dann wirf das Bild mal direkt in die Tonne. Bilder gibt es viele. Siehe: Beitrag "Re: STM32 Main loop zu langsam?" Da schafft man schon mal mit einem eher mäßigen Programm (auf HAL-Ebene) 2 MHz, also 500ns. Und wenn Du ein paar Beiträge weiterliest, erfährst Du, dass man auch mit simplen GPIO-Befehlen ohne Timer auf das Vierfache kommen kann:
1 | while(1) { |
2 | LI_CH1_GPIO_Port->BS = LI_CH1_Pin; |
3 | LI_CH1_GPIO_Port->BR = LI_CH1_Pin; |
4 | }
|
Damit sind 8MHz bzw. 125ns auch in einer Schleife locker drin. Also: Entsorge Dein "Bild", das ist Bullshit. EDIT: Aus den darunter folgenden Beiträgen geht nicht ganz klar hervor, ob der Faktor 8 lediglich an der Optimierung lag und
1 | HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN); |
bereits ausreichte, um auf die 8MHz zu kommen, oder ob es die obige Set/Reset-Schleife war.
:
Bearbeitet durch Moderator
bitwurschtler schrieb: > Heutzutage muss der UserTask warten bis der Taski-scheduler ihn > ranlässt wenn es so ist wäre das natürlich ein unfairer Vergleich, der jedoch dann zeigt wie viel langsamer ein Zugriff werden kann wenn man das so nutzt.
Also ich kann beim z.B. STM32F103... ohne Probleme einen Pin im ns-Bereich toggeln. Ich kann dir davon auch ein Bild machen :-) Gruß Daniel
Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen, aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als 1 us möglich ist. Falls gewünscht kann ich es heute Abend ausprobieren. Gruß Daniel
Matthias W. schrieb: > Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar Auslachen, stehen lassen. So verfährt man mti Typen wie dir.
Daniel B. schrieb: > Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen, > aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als > 1 us möglich ist. > Falls gewünscht kann ich es heute Abend ausprobieren. Es ist gewünscht :)
Daniel B. schrieb: > Für die folgende Aussage möchte ich meine Hand nicht ins Feuer legen, > aber ich bin der Meinung, dass selbst mit HAL ein Toggeln in weniger als > 1 us möglich ist. Glaube ich auch. Ich habe mir nochmal den Thread https://www.mikrocontroller.net/topic/goto_post/5170022 durchgelesen. Es sieht sogar so aus, als dass der TO dort allein mit der richtigen Optimierung auf seinem STM32F1 auf die 8 MHz gekommen ist. Denn schließlich ist HAL_GPIO_TogglePin() ja auch nichts mehr als das:
1 | void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) |
2 | {
|
3 | /* Check the parameters */
|
4 | assert_param(IS_GPIO_PIN(GPIO_Pin)); |
5 | |
6 | GPIOx->ODR ^= GPIO_Pin; |
7 | }
|
> Falls gewünscht kann ich es heute Abend ausprobieren.
Sehr gerne! Dabei würde mich dann folgendes interessieren:
1. Toggle per HAL
2. Toggle per Bitset auf ODR-Register
3. Toggle per Set und Reset
Ich würd's ja mal mit meinem STM32F7 ausprobieren, aber mein Oszilloskop hat nur 100Mhz Bandbreite, da wird man von den zu erwartenden 108Mhz nicht viel sehen...
Frank M. schrieb: > Entsorge Dein "Bild", das ist Bullshit. dieses sogenannte "Bullshit-Bild" stammt von dieser Seite: https://www.heise.de/developer/artikel/Review-Ein-Blick-auf-den-Arduino-Zero-2749795.html Review: Ein Blick auf den Arduino Zero "Alle Zeros haben einen mit 48 MHz arbeitenden 32-Bit-Prozessor aus dem Hause Atmel, der zur Beschleunigung von speicherintensiven Tasks einen DMA-Controller (Direct Memory Access) mitbringt." "Um die folgenden Schritte nachvollziehen zu können, ist ein Rechner mit Windows 8 und mindestens Version 1.7.4 der Arduino-IDE nötig. Für das Debugging kommt Atmel Studio und ein ergänzendes Plug-in des Unternehmens Visual Micro zum Einsatz." "Um die digitale Ausgabe zu testen, lässt sich eine weitere Version des zuvor verwendeten Sketch nutzen:" Es wird offenbar diese Ausgabe benutzt: void loop() { digitalWrite(13,LOW); digitalWrite(13,HIGH); } Das sollte ja wohl nicht so sehr verkehrt sein. "angeschlossenes Oszilloskop das in Abbildung 3 gezeigte Schirmbild." Auf dem Bild ist klar zu sehen daß die Zeit für eine solche Schleife 3.16us dauert. Das ist nicht mein Testaufbau - sondern ein Review von Heise. Ich hoffe doch daß diese Leute wissen was sie tun.
Dr. Sommer schrieb: > von den zu erwartenden 108Mhz nicht viel sehen man wird wohl sehen ob das viel schneller ist als die 3.16us die Heise hier angeblich gemessen hat - siehe das Bild.
Matthias W. schrieb: > Ich hoffe doch daß diese Leute wissen was sie tun. Die haben einfach nur das Arduino Zeug aktiviert. Das ist nicht gerade für seine Performance bekannt. Was eigentlich blöde ist, denn mit ein paar kleinen Änderungen könnte das deutlich schneller sein.
Cyblord -. schrieb: > Auslachen, stehen lassen. So verfährt man mti Typen wie dir. sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung bei.
Matthias W. schrieb: > Dr. Sommer schrieb: > von den zu erwartenden 108Mhz nicht viel sehen > > man wird wohl sehen ob das viel schneller ist als die 3.16us die Heise > hier angeblich gemessen hat - siehe das Bild. Naja, ich hab damit mal ein 37Mhz Signal gemessen (kam auch aus nem ARM) und das brauchte auch schon viel Phantasie. Das zu erwartende Ergebnis ist den Aufwand nicht wert...
Matthias W. schrieb: > Cyblord -. schrieb: >> Auslachen, stehen lassen. So verfährt man mti Typen wie dir. > > sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung > bei. Nun ja, weil derart unsachlicher Fragestellung ist IMO Hopfen und Malz verloren. Hier wird das Arduino Framework verwendet. Dessen Geschwindigkeit auf verschiedenen Plattformen wird dann irgendwie als Indikator für die Plattform an sich herangezogen. Von jemandem der offensichtlich null Ahnung von der Materie hat. Was will man da sonst sagen? Das sind meist so "ich stelle ja nur Fragen" Typen. Aber die Fragen sind abstrus und sinnlos und ohne jegliches Fachwissen. Jede Antwort eine Verwschendung von Zeit und Atemluft. Arbeite dich in die Thematik ein, mache selbst Versuche, bekomme einen Überblick über das Thema. Dann kannst du sinnvolle Fragen stellen über die man auch diskutieren kann.
Dr. Sommer schrieb: > Was eigentlich blöde ist, denn mit ein > paar kleinen Änderungen könnte das deutlich schneller sein. also sollte man solche Tests anders machen. das Ergebnis jedoch ist einfach so wie oben zu sehen. Kann das jemand bestätigen? im Vergleich dazu könnte man sich das Ergebnis mit einem Arduino nano 3 mit derselben IDE-Umgebung ansehen. Das wäre interessant.
Matthias W. schrieb: > Cyblord -. schrieb: >> Auslachen, stehen lassen. So verfährt man mti Typen wie dir. > > sachlich klingt das nicht. Es trägt auch leider nichts zur Aufklärung > bei. Ich denke, es wäre auch für Dich kein Verlust an Information, wenn Du diesen "Nutzer" ausblendetest. Von ihm kommt nichts, was sich zu lesen lohnte. BTDT
:
Bearbeitet durch User
Cyblord -. schrieb: > Arbeite dich in die Thematik ein, mache selbst Versuche, bekomme einen > Überblick über das Thema. ich arbeitete bereits 1982 mit Mikrocontrollern, baute damals ein 8085-System erfolgreich auf und dann ein 68000-System. Möglicherweise warst Du da noch gar nicht auf der Welt . . . Du kannst sicher sein daß ich einen Überblick habe . . .
Feldkurat K. schrieb: > Von ihm kommt nichts, was sich zu lesen lohnte. Schade. Ich bin immer gerne bereit zu lernen - seit sehr vielen Jahren ist das so. Jeder Mensch hat auch seine guten Seiten und manchmal auch gute und wertvolle Hinweise.
Matthias W. schrieb: > Es wird offenbar diese Ausgabe benutzt: > void loop() { > digitalWrite(13,LOW); > digitalWrite(13,HIGH); > } digitalWrite() ist eine inefffiziente Arduino-Funktion, Du vergleichst Äpfel mit Birnen. In diesem Fall musst Du auch auf dem AVR genau diese Loop unter Ardduino als Benchmark ausführen. Mach das bitte mal und berichte. Leider hast Du die Zahlen aus dem Ursprungsbeitrag ohne Quellenangabe genannt. mittlerweile hast Du für die STM32-Werte den Heise-Link nachgeliefert. Und wo kommen die 375ns beim AVR her?
Matthias W. schrieb: > Es wird offenbar diese Ausgabe benutzt: > void loop() { > digitalWrite(13,LOW); > digitalWrite(13,HIGH); > } > > Das sollte ja wohl nicht so sehr verkehrt sein. Dann vergleiche das aber bitte auch mit der Zeit, die das gleiche Programm auf einem 8bit-AVR braucht. Die Arduino Library macht beim digitalWrite() ein bisschen mehr, als am Pin zu wackeln. Äpfel mit Birnen ...
Dr. Sommer schrieb: > einfach nur das Arduino Zeug aktiviert. es klingt so als wenn dies in solchen Fällen nicht performant ist.
Matthias W. schrieb: > Du kannst sicher sein daß ich einen Überblick habe . . . Macht leider nicht den Eindruck. Noch nicht mal den Artikel, auf den sich deine ganze Fragestellung bezieht, konntest du von Anfang an, angeben. Du rotzt hier solche Fragen ohne jeglichen Kontext rein. So kann man natürlich auch seit 1982 arbeiten. Keine Frage. Nur macht es das besser? >> einfach nur das Arduino Zeug aktiviert. > es klingt so als wenn dies in solchen Fällen nicht performant ist. Es ist in keinem Fall performant. Schau dir doch einfach mal 5 Minuten den Quellcode von digitalWrite im Arduino FW an. Für dich als Profi sollte das sofort alle Fragen bezüglich Performance beantworten. Aber statt eigener Recherche unter Einsatz deines enormen jahrezentelangen Fachwissens blubbert man lieber irgendwas ins Forum. Und als Grundlage vergleicht man direkte ASM Befehle auf dem AVR, mit Arduino auf ARM. Glückwunsch!
:
Bearbeitet durch User
Wolfgang schrieb: > Die Arduino Library macht beim > digitalWrite() ein bisschen mehr, als am Pin zu wackeln. das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere Sachen. Wenn man echte Performance vergleichen will kann man die Arduino-Umgebung also schlecht verwenden. Ist es das was Du sagen willst mit Deinem Äpfel und Birnen-Vergleich? Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards zu zeigen? Im Gegensatz zu ihm kenne ich den Overhead nicht der hinter der Abarbeitung dieser Schleife sich verbirgt. Vermutlich lernen wir hier gerade wieviel Overhead dahinterstecken muss.
Matthias W. schrieb: > Der Nutzer jedoch der diese Zeilen geschrieben hat > erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere > Sachen. Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird (->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits berechnet und diese beschrieben werden. Das sind schon einige Takte. Matthias W. schrieb: > Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein > sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards > zu zeigen? Du hast ja sehr viel Vertrauen in Journalisten. Meinst du man endet als brotloser Schreiberling wenn man Experte für Embedded-Entwicklung ist?
Matthias W. schrieb: > das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat > erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere > Sachen. Das ist halt Arduino. Man tauscht Perfomance für Komfort. > Wenn man echte Performance vergleichen will kann man die > Arduino-Umgebung also schlecht verwenden. Ist es das was Du sagen willst > mit Deinem Äpfel und Birnen-Vergleich? Zumindest sollte man entweder auf beiden Plattformen Bare-Metal oder auf beiden Arduino verwenden, meinst du nicht? > Warum nur verwendet dann der Redakteur von Heise der doch erfahren sein > sollte ausgerechnet die Arduino-IDE um die Performance dieses ARM-boards > zu zeigen? Wahrscheinlich ein "Maker". Die Wissen doch gar nicht dass es Außerhalb von Arduino noch eine Welt gibt. Die sind darauf hängengeblieben, aber komplett. > Im Gegensatz zu ihm kenne ich den Overhead nicht der hinter der > Abarbeitung dieser Schleife sich verbirgt. Vermutlich lernen wir hier > gerade wieviel Overhead dahinterstecken muss. WIR wissen das alles schon. Du scheinst grade irgendwie aufgewacht zu sein, und wunderst dich über Arduino.
Dr. Sommer schrieb: > Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten > Pin-Nummer der Controller nicht diese Kontrollen werden doch wohl durch den Compiler erledigt bevor das Programm dann überhaupt beginnt zu laufen. So viele Tests sollten ja nicht bei so einer einfachen Endlosschleife nötig sein. Man müsste sich den Code wohl ansehen der hinter diesem Konstrukt steckt. Das ist dann jedoch ein anderes Thema.
Matthias W. schrieb: > diese Kontrollen werden doch wohl durch den Compiler erledigt bevor das > Programm dann überhaupt beginnt zu laufen. Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit. Man könnte das mit templates und constexpr machen, aber dann müsste der User vielleicht spitze Klammern in seinem Code verwenden, und das könnte Arduino-User verschrecken. Matthias W. schrieb: > So viele Tests sollten ja > nicht bei so einer einfachen Endlosschleife nötig sein. Wie und wie oft die Funktion aufgerufen wird hat überhaupt keinen Einfluss darauf, ob da eine Prüfung in der Funktion drin ist oder nicht. Matthias W. schrieb: > Man müsste sich den Code wohl ansehen der hinter diesem Konstrukt > steckt. Endlich mal ein sinnvoller Vorschlag
Compileroptimierung vergessen? Auf Werte von >3us komme ich nur mit -O0 & max Debugging (-g3) Beispiel ARM SAM D21@24MHz -O0 -g3 -> 5,7us -O0 -g1 -> 4,6us -O3 -g1 -> 168ns Alles mit HAL. Direkt auf hri-Ebene ist es ca. 30% schneller. Auf dem SAM V71@300MHz passiert bei Toggeln des Pins gar nix mehr. Der Io-Teiber kommt da nicht hinterher. Ich schätze mal der Author der 3us-Messung hat einfach keine Ahnung
:
Bearbeitet durch User
Cyblord -. schrieb: > Du scheinst grade irgendwie aufgewacht zu > sein, und wunderst dich über Arduino. ich nehme die Arduino-Umgebung bewusst normalerweise nicht her weil sie mir zu undurchsichtig ist und ich lieber mit einem brauchbaren Editor, Make, Avrdude arbeite. in der Tat wundert es mich wenn der Overhead so extrem groß sein soll. Das ist schwer zu glauben. Faktor 2 könnte ich noch verstehen. Aber hier reden wir von viel mehr ! eben das weckt auf - vielleicht auch andere !
Bei dem Anliegen geht es doch überhaupt nicht um einen objektiven Vergleich. Der TE möchte einfach nicht, dass sein sehr einfaches Weltbild durcheinandergebracht wird. Daher pauschaliert er auch sämtliche ARM- und AVR-Prozessoren, ohne zu berücksichtigen, dass in der letzten 30 Jahren(!) mittlerweile mindestens tausend unterschiedliche ARM-basierte Prozessoren und Microcontroller eingeführt wurden. Und natürlich muss man auch nicht berücksichtigen, dass es auch bei AVR deutliche Leistungsunterschiede gibt oder die Ausführungsgeschwindigkeit ganz empfindlich von der Anzahl an Waitstates des Programmspeichers und der Nutzung und Architektur eines Caches abhängt. Was nicht sein darf, ist eben auch nicht. Daher nun die erfreuliche Feststellung für den TE: Jeder beliebige AVR ist schneller als jeder beliebige andere ARM-basierte Prozessor oder Microcontroller. Und auch in Zukunft wird dies immer so bleiben.
Das hier ist die fragliche Stelle: https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/wiring_digital.c#L74 Kurioserweise in C programmiert. Da ist deutlich mehr drin als ein simpler Register-Zugriff, inklusive der erwähnten Prüfung. Aber kein Test auf Buffer-Overflow. Dubios. Intelligenterweise sind auch Fallunterscheidungen drin, die das nochmal extra langsam machen (Pipeline-Flush).
Matthias W. schrieb: > Cyblord -. schrieb: >> verallgemeinerst das jetzt? > > nein. Ich bin lediglich neugierig warum die einfache Aufgabe einen Pin > mal high und dann low zu setzen auf dem Arm der mehr Taktfrequenz hat > als der AVR fast Faktor 10 länger dauert. So sah es für mich aus. > > Korrigiert mich wenn es nicht so ist. > > Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar. Es stellt sich auch die Frage welche Togglerate bei 3V3 single ended physikalisch möglich ist. So ein Pin hat u.U. ne ziemliche kapazitive Last da pumpt man für 10 MHz aka 100 ns schon einigen Strom durch. Und irgendwann sind die Chip- PCB-Strukturen zu klein um diesen Strom abzuhalten. Und dann läuft beim ARM ziemlich viel über das Busprotokoll, da entsehen auch mal schnell ein paar takte Latency oder sync-verluste im Vergleich zum "monolithischen" AVR. Gelegentlich kommt nach dem Bus noch Bridge und wieder ein paar Takte verzögerung: https://m.eet.com/media/1043205/AtmelHUISoCFig5.jpg Die Laufzeiten durch eine GPIO interconnect Matrix sind auch nicht zu vernachlässigen. Das ist halt der Preis den man zahlen muss wenn jedes Pin mit jedem peripheral block verschaltet werden kann.
Andreas S. schrieb: > Jeder beliebige AVR ist schneller als jeder beliebige andere > ARM-basierte Prozessor oder Microcontroller. Nein Andreas - darum geht es mir überhaupt nicht. Es gab/gibt die Überlegung auch einen ARM einzusetzen. Dabei sind mir Dinge wie Zugriff auf IO-Pins wichtig. Daher schaut man auch Tests an - so wie diesen Test. Und dann wundert man sich. Wenn es darum ginge ARM gleich abzuschießen müsste man sich nicht die Mühe machen zu fragen und sich ggf. auch unsachliche Antworten anzuhören.
Andreas S. schrieb: > Bei dem Anliegen geht es doch überhaupt nicht um einen objektiven > Vergleich. doch Andreas - genau darum geht es mir.
Zufällig spiele ich gerade mit dem stm32f446.
1 | while(1){ |
2 | GPIOB->BSRRL=GPIO_Pin_7; |
3 | GPIOB->BSRRH=GPIO_Pin_7; |
4 | }
|
Dr. Sommer schrieb: > Das hier ist die fragliche Stelle: vielen Dank. Das ist doch sehr interessant. > Kurioserweise in C programmiert. Da ist deutlich mehr drin als ein > simpler Register-Zugriff Es sind nicht gerade viele Zeilen. Das sollte doch normalerweise schnell gehen? Man könnte natürlich dies auch mal für einen Test teilweise auskommentieren.
Thomas W. schrieb: > while(1){ > GPIOB->BSRRL=GPIO_Pin_7; > GPIOB->BSRRH=GPIO_Pin_7; > } Danke Thomas. Weniger als 70ns also. Das ist ok.
Matthias W. schrieb: > Es gab/gibt die Überlegung auch einen ARM einzusetzen. Dabei sind mir > Dinge wie Zugriff auf IO-Pins wichtig. Daher schaut man auch Tests an - > so wie diesen Test. Und dann wundert man sich. "Ich überlege meinen Trabi gegen einen neuen Mercedes SLS AMG einzutauschen, und habe mir angeschaut wie schnell man damit rückwärts fahren kann. Das kann mein Trabi schneller (vorwärts)! Jetzt frage ich mich schon ob der Mercedes schnell genug für mich ist." Thomas W. schrieb: > Zufällig spiele ich gerade mit dem stm32f446. Da geht noch was. Takt auf Maximum, ART an? Roll die Schleife mal von Hand aus Matthias W. schrieb: > Es sind nicht gerade viele Zeilen. Das sollte doch normalerweise schnell > gehen? Schnell ist relativ. Wenn es 10 Takte sind, ist es schon 5-10x langsamer als der 1-2 Takt den ein optimales Programm braucht (ob AVR oder ARM).
Dr. Sommer schrieb: > Ich überlege meinen Trabi gegen einen neuen Mercedes SLS AMG > einzutauschen nein - so ist es in meinem Fall nicht. Es wird geschaut was für die Anwendung besser passt. Daher bin ich vom AVR erst mal gedanklich auf einen MSP430 umgestiegen. Der Grund ist nicht die Rechenleistung - sondern die Peripherie.
Auf die Schnelle, weil ich weg muss. Alles komplett mit HAL und CubeMX. einmalig toggeln: while (1) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); } mehrmals toggeln: while (1) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); } Wenn es also nur auf das Ansprechen der Pins geht, kommt man sogar mit HAL auf 250ns.
:
Bearbeitet durch User
Dr. Sommer schrieb: > Thomas W. schrieb: >> Zufällig spiele ich gerade mit dem stm32f446. > Da geht noch was. Takt auf Maximum, ART an? Roll die Schleife mal von > Hand aus Mit Optimierung bekomme ich kein Rechteck mehr...
Thomas W. schrieb: > Mit Optimierung bekomme ich kein Rechteck mehr... Sehr schön! Genau das meinte ich :-) Daniel B. schrieb: > HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); Diese Funktion ist ziemlich dumm implementiert. Man braucht von ST ja nicht erwarten dass die wissen wie man die eigenen Controller programmiert...
while (1) { GPIOC->BSRR |= (1<<5); GPIOC->BRR |= (1<<5); } Jetzt sind wir schon bei 125 ns. Das geht aber bestimmt noch besser :-) Bis heute Abend.
> wo das Setzen/Rücksetzen 3.16us gedauert hat
Auf ungefähr diese Zeit komme ich beim ESP8266 mit dem Arduino Framework
bei 80Mhz Systemtakt.
Ich weiß aber auch, dass die Funktion digitalWrite() wesentlich
umfangreicher ist, als ein direkter Zugriff auf das I/O Register,
insofern überrascht mich das nicht.
1 | extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { |
2 | pwm_stop_pin(pin); |
3 | if(pin < 16){ |
4 | if(val) GPOS = (1 << pin); |
5 | else GPOC = (1 << pin); |
6 | } else if(pin == 16){ |
7 | if(val) GP16O |= 1; |
8 | else GP16O &= ~1; |
9 | }
|
10 | }
|
11 | |
12 | void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin) |
13 | {
|
14 | if(pwm_mask){ |
15 | pwm_mask &= ~(1 << pin); |
16 | if(pwm_mask == 0) { |
17 | ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); |
18 | timer1_disable(); |
19 | timer1_isr_init(); |
20 | }
|
21 | }
|
22 | }
|
Frank M. schrieb: > HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN); > bereits ausreichte, um auf die 8MHz zu kommen, oder ob es die obige Hmmm. Hier einmal mit HAL
1 | HAL_GPIO_TogglePin(GPIOB, PB0_Pin); |
und einmal mit
1 | GPIOB->ODR=0x00000000; |
2 | GPIOB->ODR=0x00000001; |
STM32F103 / 72 MHz
:
Bearbeitet durch User
Rein aus Interesse mal ein STM32F030F4 vermessen: 48MHz Systemtakt -> Pin toggelt mit exakt 4 MHz (entspricht also 250ns) Code wie bei Daniel B.
Zum Arm kann ich nicht viel sagen... Aber zum Arduino schon. Arduino UNO, 16MHz, ATMega328P
1 | // ausschnitt
|
2 | void loop() |
3 | {
|
4 | for(;;) |
5 | {
|
6 | digitalWrite(13,!digitalRead(13)); // 54 KHZ auf einem UNO |
7 | }
|
8 | }
|
Dagegen:
1 | #include <CombiePin.h> |
2 | |
3 | Combie::Pin::OutputPin<4> out; |
4 | |
5 | int main() |
6 | {
|
7 | out.init(); |
8 | for(;;) out.toggle();// 2,667MHz auf einem UNO |
9 | }
|
Mehr als 2,667 MHz sitzen nicht drin. Und das hat auch nix mit Arduino zu tun.
1 | // ausschnitt
|
2 | void loop() // 2,667 MHz symmetrischer Rechteck |
3 | {
|
4 | |
5 | for(;;) PINB = 0xFF; |
6 | }
|
Die beiden loop() Varianten werden ab und zu von der Timer ISR unterbrochen.
Stefan U. schrieb: > Auf ungefähr diese Zeit komme ich beim ESP8266 mit dem Arduino Framework > bei 80Mhz Systemtakt. Danke für die Messung Stefan !
Arduino F. schrieb: > Arduino UNO, 16MHz, ATMega328P Danke für die Messungen. > digitalWrite(13,!digitalRead(13)); // 54 KHZ auf einem UNO man sieht wie langsam das durch die Arduino-Befehle wird. > out.init(); > for(;;) out.toggle();// 2,667MHz auf einem UNO das passt zu meiner Messung.
Lama schrieb: > Rein aus Interesse mal ein STM32F030F4 vermessen: > 48MHz Systemtakt -> Pin toggelt mit exakt 4 MHz (entspricht also 250ns) Danke Lama !
Wolfgang schrieb: > Die Arduino Library macht beim > digitalWrite() ein bisschen mehr, als am Pin zu wackeln. Ja und was? Berechnet die nebenher Bitcoins? So ziemlich jeder Compiler für C, Pascal, Ada... arbeitet das mit einem sbi PORT, Pin oder einem in, xor, out in wenigen Takten ab. Mir fällt gerade absolut nix ein, was hier an die 100 Takte (3µs x 32MHz angenommen) rechtfertigen würde.
Karl schrieb: > Mir fällt > gerade absolut nix ein, was hier an die 100 Takte (3µs x 32MHz > angenommen) rechtfertigen würde. Bitte erst den Thread lesen: Dr. Sommer schrieb: > Das hier ist die fragliche Stelle: > > https://github.com/arduino/ArduinoCore-samd/blob/master/cores/arduino/wiring_digital.c#L74 Dr. Sommer schrieb: > Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten > Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs > sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass > aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird > (->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits > berechnet und diese beschrieben werden. Das sind schon einige Takte. Karl schrieb: > arbeitet das mit einem > sbi PORT, Pin oder einem in, xor, out in wenigen Takten ab Dr. Sommer schrieb: > Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit.
Allenfalls sollte Matthias W. das Thema etwas professioneller anpacken. Ja, es gibt Controller, bei denen die IO nicht mit dem Core Schritt haelt. Ja, es gibt Controller, bei denen das RAM nicht mit dem Core Schritt haelt. Beide Informationen sind, es ist wirklich unglaublich, wir haben wahnsinniges Glueck, im Datenblatt des jeweiligen Controllers zu finden. Falls man die Zeit nicht hat, das soll's geben, kann man sich das jeweilige Interface anschauen. Was ist die Logikfamilie, wie ist der Hub. Und dann auf die maximale Geschwindigkeit schliessen. Normalerweise ist bei LVCMOS um die 100MHz Schluss. Es gibt allerdings auch CPLD's mit LVCMOS, die Sub 1ns Flanken rauslassen. Da muss man sich dann auch Muehe geben. Ob man die im Datenblatt spezifizierte Geschwindigkeit erreicht ist dann eine andere Frage. Gibt es per ASM einen direkten Portzugriff, oder kommt da noch eine Hardwareschicht, wie Callgate, Trapgate, Memorymanager, oben drauf. Ist ein (virtualisierendes) Betriebssystem per Software oben drauf. Kommt dann noch eine IO Library drauf. Die ganze Packung kann einen Faktor hundert ausmachen. Wir wissen leider nichts ueber die Anwendung des TO.
Karl schrieb: > Ja und was? 1. Von der Arduino Pinnummer auf Register und Maske umschlüsseln 2. evtl. vorhandene PWM abschalten. Der Code liegt auf Github öffentlich aus, kannst dich also selber kundig machen.
Habe im Moment nur einen STM32F767ZI (Nucleo-Board) zur Verfügung.
1 | while (1) |
2 | {
|
3 | GPIOC->BSRR = (1<<8); |
4 | delayXX(); |
5 | GPIOC->BSRR = (1<<(8+16)); |
6 | delayXX(); |
7 | }
|
Ohne Delays mit dem Oszi (Leihgerät TEK2024C) für mich nicht mehr messbar ( siehe NoDelay Pic). Mit einem Delay (1 NOP), erahnbar, mit Delay (2 NOPs), eine erkennbare Kurve mit ca. 8.6Mhz Gehe ich recht in der Annahme, dass hier schlicht und einfach die GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ?
Daniel B. schrieb: > Gehe ich recht in der Annahme, dass hier schlicht und einfach die > GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ? Das Datasheet sagt was von bis zu 180 MHz, siehe Anhang - man beachte die markierten Voraussetzungen.
Daniel B. schrieb: > Gehe ich recht in der Annahme, dass hier schlicht und einfach die > GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ? Die Last durch Deinen Tastkopf (1:1?) oder durch die Bandbreite(nbegrenzung) Deiner Oszis kann auch solche Bilder erzeugen.
Daniel B. schrieb: > Gehe ich recht in der Annahme, dass hier schlicht und einfach die > GPIO HW nicht mehr hinterherkommt mit rauf-und-runter ? Kann, kann aber auch an mangelnder Bandbreite Deines Messgerätes liegen.
Zwölf M. schrieb: > Ja, es gibt Controller, bei denen die IO nicht mit dem Core Schritt > haelt. > Ja, es gibt Controller, bei denen das RAM nicht mit dem Core Schritt > haelt. Danke ! ja - ich bin wie viele andere kein profunder Insider aller uCs dieser Welt. ARM ist für mich Neuland. Daher weiß ich nicht ob und welchen Einfluss diese Punkte in der Praxis beim ARM haben - falls dies so sein sollte. > Beide Informationen sind im Datenblatt zu finden. Datenblätter wie AVR oder MSP können 600 Seiten umfassen. Ja - ich gebe zu nicht Datenblätter von ARM angesehen zu haben. Das kostet eine Menge Zeit. > Was ist die Logikfamilie, wie ist der > Hub. Und dann auf die maximale Geschwindigkeit schliessen. Normalerweise > ist bei LVCMOS um die 100MHz Schluss. ja. daran liegt das obige Problem jedoch nicht. Die Pins schalten sicher alle schnell genug - egal ob AVR, MSP oder ARM. Daran liegt die große Verzögerung nicht. Warum soll ARM langsamer sein wenn die Si-Technologie wohl dieselbe ist? > Ob man die im Datenblatt spezifizierte Geschwindigkeit erreicht ist dann > eine andere Frage. Gibt es per ASM einen direkten Portzugriff, oder > kommt da noch eine Hardwareschicht, wie Callgate, Trapgate, > Memorymanager, oben drauf. Ist ein (virtualisierendes) Betriebssystem > per Software oben drauf. Kommt dann noch eine IO Library drauf. Die > ganze Packung kann einen Faktor hundert ausmachen. dies ist wichtig wenn man entscheidet welche CPU man mit welchen Tools wie verwendet. Die meisten dieser Bremser nutze ich nicht. Nun weiß ich daß ARM Pins grundsätzlich recht schnell schalten kann und daß die Arduino-Umgebung stark verlangsamen kann. Vielen Dank für die Beiträge.
>> Die Arduino Library macht beim >> digitalWrite() ein bisschen mehr, als am Pin zu wackeln. > Ja und was? Habe ich etwas weiter oben geschrieben - mit Quelltext.
Wie gesagt, Leihgerät von einem Freund, reicht mir um zu sehen, ob sich etwas auf den SPI / I2C Pins etwas tut, und was auf dem DAC rauskommt. TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1. @Matthias W: Ist eigentlich egal, ob Du die Arduino Umgebung oder HAL Umgebung oder etwas selber geschriebenes, sobald Du ein paar Subroutinen dazwischen hast, bricht die Geschwindigkeit massiv ein. So meine Erfahrung, ohne jetzt alles analysiert zu haben.
:
Bearbeitet durch User
Dr. Sommer schrieb: > Dr. Sommer schrieb: >> Das hier ist die fragliche Stelle: > https://github.com/arduino/ArduinoCore-samd/blob/m... Und? Da steh genau nichts, was derart viele Takte erfordert. > Dr. Sommer schrieb: >> Der Nutzer erwartet z.B. dass bei Angabe einer nicht existenten >> Pin-Nummer der Controller nicht irgendwie abstürzt sondern eine halbwegs >> sinnvolle Fehler-Behandlung durchgeführt wird. Außerdem erwartet er dass >> aus der Pin-Nummer 17 der GPIO-Pin PA7 (beispielhaft) gefunden wird >> (->Array-Zugriff), daraus die Adresse der GPIO-Register und -Bits >> berechnet und diese beschrieben werden. Das sind schon einige Takte. Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur Programmlaufzeit. Das wäre ja reichlich bescheuert. > Dr. Sommer schrieb: >> Nö. Sofern die Funktion nicht geinlined wird passiert das zur Laufzeit. Häh? Läuft da Python drauf oder was? Da wird ein Maschinencode generiert und der wird genau so in wenigen Takten ausgeführt.
> "the compensation cell should be used"
Was ist das? Kenn ich (noch) nicht.
Dr. Sommer schrieb: > Das Datasheet sagt was von bis zu 180 MHz, siehe Anhang - man beachte > die markierten Voraussetzungen. Cool, schon wieder was gelernt :-) Bringt aber auf die Schnelle in meinem Bespiel nichts. Habe mal:
1 | ....
|
2 | HAL_Init(); |
3 | SystemClock_Config(); |
4 | GPIO_Init(); |
5 | HAL_EnableCompensationCell(); |
eingebaut. Weiss aber nicht, ob das so riecht, ändert auf jeden Fall an dem Ergebnis nichts.
Karl schrieb: > Und? Da steh genau nichts, was derart viele Takte erfordert. Dann sind's wohl Gespenster. Karl schrieb: > Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur > Programmlaufzeit. Ich wiederhole es nochmal: Das geht nur, wenn die Funktion geinlined wird. Und das passiert anscheinend nicht. Karl schrieb: > Das wäre ja reichlich bescheuert. Ist halt Arduino. Karl schrieb: > Da wird ein Maschinencode generiert > und der wird genau so in wenigen Takten ausgeführt. Der Maschinencode der digitalWrite-Funktion muss aber die erforderlichen Berechnungen durchführen. Dieser Code hat keine Ahnung mit welchen Argumenten er wo im Code aufgerufen wird.
Karl schrieb: > Ähm sorry, das macht der Compiler alles vorher und ganz gewiss nicht zur > Programmlaufzeit. Das wäre ja reichlich bescheuert. Gähn... Die Arduino Pin Nummern können als Variable übergeben werden. Z.B. können sie in einem Array liegen. Damit MUSS das zur Laufzeit aufgeschlüsselt werden. 1. Es zwingt dich ja keiner diese Funktionen zu nutzen. 2. Meistens ist das völlig egal, wie lange die Funktionen brauchen. Die Zeit wird woanders verwartet, oder verpollt.
Daniel B. schrieb: > TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1. Dann wird es mit 100 MHz und Rechteck nichts. Neben der 100 MHz Grundwelle braucht das Rechteck auch 300, 500 usw Mhz. Da aber macht das 200 MHz Scope die Graetsche.
Boah Leute, lernt doch mal mit den Chips richtig umzugehen: ldr R0, =(GPIOA_BASE+GPIO_BSRR) ldr R1, =0x00000001 ldr R2, =0x00010000 Lop: str R1, [R0] // Pin au 0 setzen str R2, [R0] // Pin auf 1 setzen b Lop Gibt an zwei von drei Takten einen Flankenwechsel… Abhängig vm Prozessortakt könnte es sein, dass die I/O-Pins nicht mehr mitkommen.
Uwe B. schrieb: > Daniel B. schrieb: >> TEK 2024C 4 x 200Mhz mit Standardtastköpfen 10:1. > > Dann wird es mit 100 MHz und Rechteck nichts. Neben der 100 MHz > Grundwelle braucht das Rechteck auch 300, 500 usw Mhz. Da aber macht das > 200 MHz Scope die Graetsche. Jup, und man schaue sich mal an, welchen Widerstand ein 200 MHz Tastkopf bei 100 MHz darstellt. Das ist nicht mehr gar so hochohmig wie man es gerne hätte.
Guido Körber schrieb: > Boah Leute, lernt doch mal mit den Chips richtig umzugehen: So weit waren wir schon längst. Durch Ausrollen der Schleife wird's noch besser. Das geht übrigens in C genauso gut. Viel interessanter ist die Konfiguration des Takts und die Geschwindigkeit vom Flash und eventueller Caches (ART, ITCM, L1).
Sehr gut, sogar noch mein minimales Oszi-Wissen erweitert heute Nachtmittag :-) Dann kann ich leider nicht mehr mitmachen beim Speedrennen....
ich finde diese Diskussionen um das Pin Wackeln sehr müssig. Wenn es schnell gehen soll bekommt man es hin, auch mit Arduino oder HAL oder anderen Libs. Mit den Libs kann man immer noch den Pin einfach initialisieren und für den schnellen Zugriff geht man an der Lib mit direkten Registerzugriffen vorbei. In C geht das mit #defines und inline Code immer noch einigermassen elegant, ein bisschen muss man dem Perfomancegott halt an Sicherheit opfern. Nur warum will man beim ARM überhaupt noch Pins schnell toggeln? Es wird z.B. noch gemacht für Grafikdisplays (und da nutzt man eben die genannten Möglichkeiten), aber hier gibt es in den ARM Familien viel bessere Controller mit der passenden HW Unterstützung, FSMC bei den STM32 z.B. oder TFT Controller für komplettes HSync/VSync Timing. Es gibt Controller mit Ethernet HW, da braucht man nur einen Speicherblock vorzubereiten und den Empfang scharfzuschalten. Die HW füllt den, löst einen Int aus und füllt den nächsten Block. Damit hat man sehr schnelle Kommunikation mit geringen Latenzen, mit welchem AVR geht das? Dann die vielen Möglichkeiten mit DMA, auch damit kann man Bitmuster rasend schnell auf Ports ausgeben. Andere Controller (NXP) mit SCT, einer State Machine in HW die auf verschiedene Events reagiert. Damit bekommt man z.B. Timings für die beliebten WS28xx LED hin mit nahezu 0 Prozessorlast. Oder robuste Steuerung für BLDC die eben in HW läuft. Viele schnellere SPI, QSPI, CAN, I2C und dazu viel Speicher und DMA. usw. usw. Und dann die Prozessorarchitektur danach zu bewerten wie schnell man einen Pin wackeln kann? Echt albern.
Matthias W. schrieb: > Frank M. schrieb: >> Und wo kommen die 375ns beim AVR her? > > das ist ein Arduino nano3 mit 16MHz. Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler. Wie Arduino Fanboy oben dokumentiert hast, kommst Du mit der Arduino-IDE unter der Verwendung von digitalWrite() gerade mal in den zweistelligen kHz-Bereich auf einem AVR. Mit einfachen Register-Zugriffen (in C) sind wir dann beim STM32 im zweistelligen ns-Bereich, wo der AVR noch nichtmals in Assembler hinkommt. Damit kann man nun endlich die Birnen mit den Birnen (Arduino + digitalWrite) und die Äpfel mit den Äpfeln (optimiertes C) vergleichen. Und schon sieht der AVR richtig alt aus.
:
Bearbeitet durch Moderator
Johannes S. schrieb: > Und dann die Prozessorarchitektur danach zu bewerten wie schnell man > einen Pin wackeln kann? Echt albern. so albern ist das auch nicht. Es gibt schon Anwendungen wo man so etwas ggf. brauchen kann. es könnte sein daß man ein batteriegepuffertes RAM extern anschließen will. Oder ein schnelles MRAM mit parallelem Zugriff. Dabei ist es dann schon ein Unterschied ob eine Speicherzelle 3us oder 300ns braucht. Falls so etwas mit DMA geht kann man es natürlich auch damit machen. Man muss halt an den Speicher Adressen und Daten anlegen. Bei den 8051 bzw. 8085 war das auch nicht anders. Bei bestimmten AVR kann man memory mapped kleinere Speicher betreiben. Wenn die Speicher größer sind wird es Krampf. Es macht schon Sinn sich klarzumachen was geht und was eher nicht. Ob man es dann nutzt ist eine andere Frage. Viele Funktionen sind heute on chip. Manche aber nicht so gut wie man es sich wünscht. Z.B. sind DACs mit mehr als 12bit auf Controllern eher unüblich. Da muss man dann überlegen was man wie extern anschließt. SPI geht zwar aber taktet deutlich schneller und kann bei jedem Flankenwechsel Störungen verursachen die ggf. dann im Ausgang zu sehen sind. Wenn ein LSB nur ein paar uV groß ist und der Spannungshub klein wird das problematischer als wenn man 5V oder 10V Hub hat so wie es früher bei DACs mal war. Über manches kann man nachdenken . . . Wie man es dann realisiert ist eine andere Frage.
Frank M. schrieb: > Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler. nein - in C !
Matthias W. schrieb: > es könnte sein daß man ein batteriegepuffertes RAM extern anschließen > will. Oder ein schnelles MRAM mit parallelem Zugriff. Und warum sollte man dafür nicht die auf ARM's vorhandenen Speichercontroller (FSMC und FMC bei STM32) nutzen?
Dr. Sommer schrieb: > Matthias W. schrieb: >> es könnte sein daß man ein batteriegepuffertes RAM extern anschließen >> will. Oder ein schnelles MRAM mit parallelem Zugriff. > > Und warum sollte man dafür nicht die auf ARM's vorhandenen > Speichercontroller (FSMC und FMC bei STM32) nutzen? Gabs 1982 noch nicht. Er macht seit dem alles über Pin Wackeln. Google und PDF Datenblätter gabs damals übrigens auch noch nicht, darum nutzt er es nicht.
:
Bearbeitet durch User
Matthias W. schrieb: > Oder ein schnelles MRAM mit parallelem Zugriff. Dabei ist es dann > schon ein Unterschied ob eine Speicherzelle 3us oder 300ns braucht. auch dafür gibt es Mitglieder in den ARM Familien da besonders fix können, ext. Speicher ist ein gutes Argument. Vor allem weil die Cortex-M auch den grossen Adressraum haben um grossen Speicher (non-paged) unterzubringen... Matthias W. schrieb: > Viele Funktionen sind heute on chip. Manche aber nicht so gut wie man es > sich wünscht. Z.B. sind DACs mit mehr als 12bit auf Controllern eher > unüblich. ja, ist richtig, die kleinen Strukturen auf den Chips sind nicht analogfreundlich. SPI ist da aber absolut üblich und auch hier würde das gut mit DMA oder dem FSMC von STM gut gehen. Für die Ausgabe auf einen DAC möchte man vielleicht auch einen konstanten Takt haben, da ist eine Schleife in SW die ständig durch Interrupts gestört wird auch nicht so toll.
Matthias W. schrieb: > Frank M. schrieb: >> Ja, aber nicht mit der Arduino-IDE compiliert, sondern in Assembler. > > nein - in C ! Okay, geschenkt. Pin-Wackeln macht der gcc wie ein Assembler-Programmierer. Hauptsache, Du vergleichst zukünftig nicht mehr ganz allgemein die Performance von irgendwelchen Arduino-Programmen mit C-Programmen. Darum ging es mir.
Arduino F. schrieb: > 2. Meistens ist das völlig egal, wie lange die Funktionen brauchen. Die > Zeit wird woanders verwartet, oder verpollt. Bei Arduino: Bestimmt. Bei einem richtigen Compiler kann man halt in der Zeit andere Sachen machen.
Karl schrieb: > Bei einem richtigen Compiler kann man halt in der Zeit andere Sachen > machen. Arduino verwendet den G++, den C++ Compiler der GCC. Ist das kein richtiger Compiler? Wenn nein, was ist einer?
Dr. Sommer schrieb: > Arduino verwendet den G++, den C++ Compiler der GCC. Ist das kein > richtiger Compiler? Wenn nein, was ist einer? Ach, das verstehst du nicht... Er möchte gerne schimpfen, und hat jetzt was gefunden.
Frank M. schrieb: > von irgendwelchen Arduino-Programmen mit C-Programmen. Darum > ging es mir. die Arduino-Programme sind ja auch C bzw. C++. Nur daß ich eben nur 2 Zeilen C in der Schleife nutzte und die Arduino-Umgebung halt viel mehr Code-Zeilen was die wenigsten wohl wissen.
Johannes S. schrieb: > SPI ist da aber absolut üblich üblich schon - aber vielleicht nicht immer so glücklich, denn jeder Takt der da ans DAC-chip geführt wird - und bei SPI sind es 8-16x so viele oder noch mehr Takte wird eine Störung auf der GND-Leitung verursacht. Bei ein paar uV für das LSB kann man sich denken wie störbehaftet dann das Ausgangssignal eines 16bit DAC werden kann.
Matthias W. schrieb: > Wolfgang schrieb: >> Die Arduino Library macht beim >> digitalWrite() ein bisschen mehr, als am Pin zu wackeln. > > das mag ja so sein. Der Nutzer jedoch der diese Zeilen geschrieben hat > erwartet wohl genau das was er geschrieben hat und nicht noch 100 andere > Sachen. Dann muss er direkt den Prozessor programmieren und nicht blind irgendwelche Funktionen aufrufen, die sonstwelche Nebenjobs erledigen. Es steht doch jedem frei, einen Arduino ohne Weichspülfunktionen zu programmieren. Die Bibliotheken sind auf schnelle Erfolgserlebnisse und nicht auf Performance getrimmt. Den 8bit-AVR hat er doch anscheinend auch direkt programmiert.
TM F. schrieb: > In der Endlosschleife benötigt er 4 Takte. Dann hat die Ausgabe aber ein ziemlich häßlichen Duty von 1:3. Das zählt normalerweise nicht wirklich. Realistisch muss man für die meisten praktisch relevanten Aufgaben deshalb 6 Takte ansetzen. Nur dann kann man ein Duty von 1:1 erreichen. Aber: Wer würde das schon mit einer Busy-Loop lösen wollen, wenn es Sachen wie SPI, UART(im SPI-Mode) und Timer gibt, die allesamt in der Lage sind, 1/2 Systemtakt mit Duty 1:1 auszugeben, ohne die MCU damit behelligen zu müssen... Die MCU ist viel intelligenter als diese Peripherie und sollte freigehalten werden, um komplexere Aufgaben zu lösen, als stupide Takte auszugeben.
Wolfgang schrieb: > Dann muss er direkt den Prozessor programmieren das mache ich die ganze Zeit (mit C eben, früher AVR-Assembler) und meide solche Tools wie die Arduino-Umgebung wo ich kann. Es war dieser Redakteur der diesen Benchmark eben mit dieser Umgebung betrieb - bitte nicht vergessen. Nur so kamen wir nun dahinter was sich an zeitlichem Overhead hier offenbar verbirgt.
Johannes S. schrieb: > Für die Ausgabe auf einen > DAC möchte man vielleicht auch einen konstanten Takt haben, da ist eine > Schleife in SW die ständig durch Interrupts gestört wird auch nicht so > toll. ja Johannes. Gut wenn man ggf. genügend SPI-Schnittstellen hat. Oder man muss diese umschalten. Dabei muss man ggf. aber sehr aufpassen wenn die SPI-Slaves unterschiedliche Einstellungen benötigen. Interrupts sollten auch da ggf. nicht dazwischenfunken.
Dr. Sommer schrieb: > die auf ARM's vorhandenen > Speichercontroller (FSMC und FMC Danke für den Hinweis !
Matthias W. schrieb: > Gut wenn man ggf. genügend SPI-Schnittstellen hat. und auch da hat man reichlich Auswahl, moderne LPC54xxx mit bis zu 10, selbst die kleinen LPC8xx haben 2. Bei STM findet man auch reichlich mit 2..6 SPI. > Interrupts sollten > auch da ggf. nicht dazwischenfunken. dann nimmt man MCUs mit DMA die auch SPI als Ziel kennen.
Matthias W. schrieb: > Es war dieser Redakteur der diesen Benchmark eben mit dieser Umgebung > betrieb - bitte nicht vergessen. häufig wird bei dem Wunsch das Andenken an diesen Redakteur nicht zu vergessen, die frühere soziale Missachtung des Redakteurs vertuscht: Matthias W. schrieb: > ich arbeitete bereits 1982 mit Mikrocontrollern .. > Du kannst sicher sein daß ich einen Überblick habe . . . Matthias W. schrieb: > Für mich zählt das was das Oszi anzeigt. Das Oszibild war klar. Matthias W. schrieb: > sah ich im Netz ein Bild wo das Setzen/Rücksetzen 3.16us gedauert hat. wenn Matthias W. schon früher darüber informiert gewesen wäre, dass es sich um den Überblick, Oszibild, Benchmark des Redakteurs gehandelt hat, dann käme der Wunsch vermutlich aufrichtiger rüber. Matthias W. schrieb: > Nur so kamen wir nun dahinter was sich > an zeitlichem Overhead hier offenbar verbirgt. wenn keiner von euch die Möglichkeit hat hinter einen zeitlichen Overhead zu kommen der sich "offenbar" 'verbirgt, dann wird das natürlich kompliziert. Ähnlich wie bei dem Wusch das Gedenken an den Redakteur nicht zu vergessen könntet ihr versuchen euch erst die einzelnen Punkte verständlich zu machen: - wie habt ihr das offenbare verbergen mitbekommen? - konntet ihr nicht den Redakteur fragen ob ein Framework u.U. etwas mit (zeitlichem) Overhead zu tun haben könnte? kurz: wenn ihr euch etwas sortieren könntet und versucht "ich"/"wir"/"Redakteur" als unterschiedliche Menschen(gruppen) zu verstehen, dann könnte das u.U. einige Missverständnisse aufklären.
Matthias W. schrieb: > Nur so kamen wir nun dahinter was sich > an zeitlichem Overhead hier offenbar verbirgt Warum redest du ständig in der Mehrzahl von dir?
-Nucleo-Board mit STM32F103 -konfiguriert mit CubeMX -gemessen mit Analog Discovrey 2, welches ganz schon an seine Grenzen kam -geändert wurde jeweils nur der Code in der while-Schleife 57 ns while (1) { GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); } 57 ns while (1) { GPIOC->BSRR = GPIO_PIN_5; GPIOC->BRR = GPIO_PIN_5; } 70 ns while (1) { GPIOC->BSRR = (1<<5); GPIOC->BSRR = (1<<21); } 125 ns while (1) { GPIOC->BSRR |= (1<<5); GPIOC->BRR |= (1<<5); } 140 ns while (1) { GPIOC->ODR = (1<<5); GPIOC->ODR &= ~(1<<5); } 220 ns while (1) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET); } 360 ns while (1) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); } High-Low mehrmals in einer while-Schleife while (1) { GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); } Wenn er mal in Fahrt gekommen ist, dann geht das High-Low-Ziehen der Pins anscheinend auch noch wesentlich schneller :-) Weil ich gerade so am Messen war, hier noch ein Atmega168PA mit 16MHz an 5,1V. Schlägt sich nicht schlecht, der Kleine. 125ns while (1) { PORTD |= (1<<2); PORTD &= ~(1<<2); } Über Sinn- oder Unsinn des Ganzen kann man natürlich streiten. Genauso über meine Fähigkeiten und die meiner Messgeräte. Natürlich gibt es noch andere und je nachdem auch sinnvollere Möglichkeiten einen Pin zu toggeln. Hiermit will ich auch keine hochqualitativen Aussagen machen. Ich fand es einfach gerade interessant und vielleicht hilft es irgendjemand irgendwann. Gruß Daniel
:
Bearbeitet durch User
Daniel B. schrieb: > Wenn er mal in Fahrt gekommen ist, dann geht das High-Low-Ziehen der > Pins anscheinend auch noch wesentlich schneller :-) Der Sprung der Schleife ist halt "langsam". Deine Ergebnisse sind etwas komisch, hast du die Compiler Optimierung an?
Dr. Sommer schrieb: > hast du die Compiler Optimierung an? Gute Frage, ich habe keine Ahnung wo ich das prüfen, oder verändern kann. Ich arbeite mit der System Workbench for STM32. Wenn du mir helfen könntest diese Einstellung zu finden, kann ich dir mehr sagen.
Hab damit noch nicht viel gearbeitet. Vermutlich in den Projekt Einstellungen. Oder einfach mal die "Release" Konfiguration auswählen...
Optimierungslevel -O2 ist eingestellt. Soweit ich es mit meinem Oszi beurteilen kann, liegen wir jetzt bei ca. 30ns. Und der Sprung in die while-Schleife ist jetzt wesentlich kürzer. while (1) { GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); GPIOC->BSRR = (1<<5); GPIOC->BRR = (1<<5); }
Johannes S. schrieb: > Und dann die Prozessorarchitektur danach zu bewerten wie schnell man > einen Pin wackeln kann? Echt albern. Ja, sehe ich auch so. Das ist etwa so, wie die Performance von zwei Pogrammiersprachen zu vergleichen, indem man in beiden ein Programm schreibt, das in einer Schleife hundert Million mal zwei Zahlen addiert und schaut, welches schneller fertig ist. Hier noch ein Link, der ganz gut zu beschrieben scheint, warum digitalWrite() im Vergleich zu direktem Pinwackeln so langsam ist: https://www.peterbeard.co/blog/post/why-is-arduino-digitalwrite-so-slow/
Rolf M. schrieb: > Hier noch ein Link, der ganz gut zu beschrieben scheint Danke für den interessanten Link Rolf !
Daniel B. schrieb: > -Nucleo-Board mit STM32F103 > -konfiguriert mit CubeMX Vielen Dank für die Messungen Daniel.
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.