Gibt es in einer Bibliothek mit gemeinsamen Funktionen (Instruction Set ----> High Level Program) Informationen darüber, wie viele Taktzyklen sie verwenden?

Ich bin eine mathematische Person. Denken Sie also aus dieser Perspektive.

Um meine Frage etwas konkreter zu machen. Ich dachte daran, ein Hobby-Servo über einen seriellen Uart-Datenstrom zu steuern.

Ich erfinde Zahlen, um die Idee zu kommunizieren.

KONTEXT:

Angenommen, ein Servo muss mit 100 Hz aufgefrischt werden und benötigt eine Auflösung von 1 Grad.

Dies impliziert also, dass die serielle Kommunikation DATA (101101000) mit einer Breite von 9 Bit senden muss. (Mir ist klar, dass es einen Overhead gibt, HALTEN SIE ES EINFACH ATM). @ 100Hz. Daher 900 Bit pro Sekunde Übertragungsrate.

Da ein Servo durch ein PWM-Signal gesteuert wird. Und im Falle eines Arduino mit 16 MHz Takt.

Diese serielle Übertragung verbraucht einen Prozentsatz der Zeit und lässt den Rest übrig, um das PWM-Signal zur Steuerung des Servos zu erzeugen.

Hauptfrage:

Wie finde ich im Allgemeinen "angesichts der Bibliotheksnatur von Programmiersprachen" die Anzahl der Anweisungen auf niedriger Ebene, die für eine bestimmte Funktion oder Routine verwendet werden? So kann ich sehen, ob ich genug Zeit habe, um mich in diesen Fall einzufügen. Das PWM-Signal zwischen Datenübertragung.

Meinst du einen bestimmten Prozessor? Und welches OS hast du im Sinn?
Atmel AtMega32u4 Mikrocontroller. Meine Frage war jedoch allgemeiner Natur. Denn es geht mehr darum, wie man diese Informationen für "Einlegeplatte" findet und entsprechend auswählen kann.
das ist cool, ich habe trotzdem einen Fehler in Frage gefunden. 9 * 100 = 900 nicht 9000 lol. Danke.
In menschlicher Hinsicht ist die Arbeitsbelastung des Mikrocontrollers bei einer 100-Hz-Servoaktualisierung ähnlich wie beim Umblättern einer Buchseite etwa einmal am Tag ... Ich vermute wirklich nur die Genauigkeit des Vergleichs
Sie schreiben den Code und vergleichen ihn dann mit einem Bereich. Triggern Sie auf die fallende UART-Flanke und zeigen Sie dann die PWM an. Beim Versuch, eine Theorie darüber aufzustellen, wie viele Anweisungen die Ardunio-Bibliotheken nicht geben werden, gibt es zu viel C++-Glibber zwischen dem Benutzercode und der Hardware. Wenn Zählanweisungen wichtig sind, dann schreiben Sie den Treiber selbst. Das Codieren von Echtzeit-Mikrocontrollersystemen mit Arduino klingt schmerzhaft.

Antworten (2)

Im Allgemeinen wird jede in C geschriebene Bibliothek wahrscheinlich keine Informationen darüber haben, wie viele Taktzyklen benötigt werden, um eine Funktion auszuführen. Der Grund dafür ist, dass es von Ihren Compiler-Optimierungseinstellungen abhängt und welchen Compiler Sie verwenden.

Normalerweise können Sie nur anhand des Quellcodes erkennen, wie lange etwas dauern wird, wenn Sie sich die Assemblersprache ansehen. Und nur dann, indem Sie das Timing für jede Anweisung im Datenblatt nachschlagen.

Ich glaube, dass die Arduino-Boards die Atmel AVR-Prozessoren verwenden. In diesem Fall können Sie Atmel Studio verwenden, um den Code für jede Bibliotheksfunktion zu simulieren. Der Simulator zählt die verstrichene Zeit der Simulation.

Setzen Sie einfach einen Haltepunkt vor und nach dem Code, den Sie timen möchten. Führen Sie den Code bis zum ersten Haltepunkt aus und notieren Sie die Zeit. Laufen Sie dann zum zweiten Haltepunkt und überprüfen Sie die Zeit. Der Unterschied zwischen diesen beiden Zeiten ist das, was Sie messen möchten.

Der serielle Empfang und die PWM-Erzeugung laufen tatsächlich ohne CPU-Beteiligung parallel, da Ihr Chip wahrscheinlich über dedizierte Hardware für diese beiden Funktionen verfügt. Die CPU muss nur das PWM-Tastverhältnis anpassen, wenn es sich ändern muss, und ein Zeichen nehmen, sobald der Empfangspuffer voll ist.

Auch in Bezug auf die 9 Bits: Wenn Ihr UART ein 9-Bit-Wort unterstützt, beträgt Ihre Gesamtzahl von Bits 9 Datenbits plus ein Start- und Stoppbit, also 11 Bits pro Wert. Wenn Ihr UART nur 8 Bit unterstützt, müssen Sie zwei Bytes senden, für insgesamt 20 Bitzeiten, wenn Sie die Start- und Stoppbits einbeziehen.

Beachten Sie, dass die Zeit, die zum Senden eines Bytes benötigt wird, ohne Simulation nur anhand der Baudrate grob bestimmt werden kann. Beispielsweise dauert eine Rate von 9600 bps (10 Bits)/(9600 Bits pro Sekunde) = 1,04 ms pro Byte (beim Senden mit 8 Datenbits, 1 Startbit, 1 Stoppbit). Da Sie nur einmal alle 10 ms aktualisieren müssen, wären sogar 9600 bps (was ziemlich langsam ist) mehr als ausreichend.

Die UARTs in AVR-Chips unterstützen 9 Bits, aber das 9. Bit muss aus einem separaten Register gezogen werden.
Danke user96037, das ist genau das, wonach ich gesucht habe. Ich wusste nicht, dass PWM parallel ist (sehr nützliche Informationen). Guter Punkt zur Compiler-Effizienz. Ich hatte ein sehr allgemeines konzeptionelles Verständnis, danke, dass Sie sich die Zeit genommen haben, zu antworten!
Interessanterweise haben einige der XMOS-Teile eine Werkzeugkette, die diese Informationen direkt in der IDE anzeigt, zusammen mit der ziemlich großen Anzahl von Ausführungseinheiten, die erforderlich sind, um jede einzelne einfach genug zu halten, um diese Art von Determinismus für einen nützlichen Satz von Anwendungscode zu ermöglichen. In einem allgemeineren Sinne ist dieses Problem ein Spezialfall des "Halteproblems". xmos.com/products/tools

Selbst bei einem RISC-Prozessor wie diesem, bei dem alle Befehle die gleiche Anzahl von Zyklen benötigen, wird es schwierig, wenn nicht unmöglich sein, die genaue Anzahl von Zyklen (und somit Zeit) einer gegebenen Bibliotheksroutine zu bestimmen. Insbesondere wenn man bedenkt, dass jede bedingte Entscheidung innerhalb jedes Bibliotheksaufrufs mehr oder weniger Anweisungen (und Zeit) in den Ausführungspfad einbringen kann. Wenn Sie mit einem vollständigen Debugger- und Simulationssystem arbeiten würden (das Atmel möglicherweise zu einem Preis anbietet), wäre es dann möglich, Haltepunkte zu setzen und das genaue Timing für jeden möglichen Fall jeder Routine zu messen. Aber ich vermute, es wäre frustrierend, es sei denn, die Bibliotheksfunktionen wären so konzipiert, dass alle Fälle zum gleichen Timing führten.

Wenn ich Sie wäre und diese Bedenken hätte, würde ich daher ein Oszilloskop mit mindestens doppelter Trace- und Trigger-Fähigkeit verwenden, um Timing und Synchronisation auf deterministischere Weise zu testen. Das heißt, ich kann eine beliebige Anzahl von Testsequenzen starten und verschiedene digitale Pins umschalten, um den Ausgangszustand zu ändern, wenn eine bestimmte Aufgabe abgeschlossen ist. Dies würde es mir ermöglichen, sowohl die Gesamtzeit zum Erledigen verschiedener Aufgaben als auch Unterschiede zwischen verschiedenen Fällen klar zu sehen. Das Ergebnis, auf das Sie hoffen und das Sie meiner Meinung nach angesichts der Geschwindigkeit der CPUs erhalten werden, ist, dass Sie mehr als ausreichend zusätzliche Zeit haben und alle Ihre Aufgaben in einer Zeit erledigt werden, die im Vergleich zu der viel langsameren Geschwindigkeit unbedeutend ist der tatsächlichen seriellen 9-Bit-Wörter.

Wenn sich herausstellt, dass Sie selbst bei vernachlässigbarer Verarbeitungszeit immer noch nicht damit zufrieden sind, durch die Geschwindigkeit der seriellen Übertragung begrenzt zu werden, müssen Sie entweder eine viel schnellere Bit- / Baudrate verwenden oder müssen Verwenden Sie mehrere Prozessoren (jeder mit seiner eigenen seriellen E/A). dann können sie alle ihre Daten vorbereiten und von einem einzigen Befehl zum gleichzeitigen Senden ausgelöst werden (z. B. ein einzelner digitaler E/A-Punkt, der allen CPUs signalisiert, dass sie senden sollen).

Viel Glück! Hoffentlich ist die Arduino-Geschwindigkeit kein Problem, und das Senden von Daten an alle Ihre Servos einzeln ist immer noch ausreichend.

Und ich weiß nicht, ob es wichtig ist, aber alle Arduino-Prozessoren, die ich kenne, haben mehrere direkte PWM-Ausgänge.

Aber seien Sie sich auch bewusst, dass es wahrscheinlich bessere Foren als das Elektrotechnik-Forum für spezifische Fragen zur Codierung oder Prozessorfähigkeit gibt.

+1, lustig (nicht wirklich) ist, dass sich das Timing erneut ändert, wenn Sie den Code für die Produktion ohne verschiedene Debug-Hooks kompilieren.
@AliChen Nun, ich habe nicht mit den Amtel-Simulationstools gearbeitet, aber ich kann Ihnen sagen, dass Sie mit der Simulation auf anderen Plattformen (insbesondere einigen Mikrochip-MCUs) die Ausführung zwischen zwei beliebigen Punkten genau vorhersagen können. In den frühen Tagen, als eingebaute UARTs etwas kosteten, hatte ich erfolgreich mehrere serielle "Bit-Banger" auf diese Weise entworfen, und ich würde mir vorstellen, dass solche Tools für das OP gut genug wären, WENN er diese Tools hätte und vollständig gewartet würde Kontrolle über den Code. Für seine Situation würde ich es so machen, wie ich es vorgeschlagen habe.
Danke auch für deine Informationen Randy. Mir fehlten die Worte, also habe ich nur einen einzigen Fall erstellt, in dem es klar genug war, um die Informationen zu erhalten :). Zu meinen tatsächlichen Bedürfnissen. Sie könnten einen komplexeren Fall erstellen, in dem Ihre laufenden Servos mit einer Aktualisierung von viel mehr als 100 Hz multiplizieren. Ich dachte darüber nach, wie ich einen externen Prozess wie einen Servo oder eine Gruppe von Servos mit dem internen CPU-Entscheidungsbaum synchronisieren würde. Offensichtlich kann die Komplexität des Entscheidungsbaums sehr schnell wachsen. Aber ohne Messung der Taktzyklen im Verhältnis zum Code hatte ich keine Ahnung, was ich tun sollte.