Zykluszählung mit modernen CPUs (zB ARM)

14

In vielen Anwendungen kann eine CPU, deren Befehlsausführung eine bekannte zeitliche Beziehung zu erwarteten Eingabestimuli aufweist, Aufgaben ausführen, die eine viel schnellere CPU erfordern würden, wenn die Beziehung unbekannt wäre. In einem Projekt, in dem ich ein PSOC zum Generieren von Videos verwendet habe, habe ich beispielsweise alle 16 CPU-Takte ein Byte Videodaten mit Code ausgegeben. Da das Testen, ob das SPI-Gerät bereit ist, und das Verzweigen, wenn nicht, 13 Takte dauern würde und das Laden und Speichern zum Ausgeben von Daten 11 Takte dauern würde, gab es keine Möglichkeit, das Gerät auf Bereitschaft zwischen Bytes zu testen. Stattdessen habe ich einfach dafür gesorgt, dass der Prozessor für jedes Byte nach dem ersten genau den Code von 16 Zyklen ausführt (ich glaube, ich habe eine echte indizierte Last, eine indizierte Dummy-Last und einen Speicher verwendet). Der erste SPI-Schreibvorgang für jede Zeile erfolgte vor dem Start des Videos. und für jedes nachfolgende Schreiben gab es ein 16-Zyklus-Fenster, in dem das Schreiben ohne Pufferüberlauf oder -unterlauf stattfinden konnte. Die Verzweigungsschleife erzeugte ein Unsicherheitsfenster mit 13 Zyklen, aber die vorhersagbare Ausführung mit 16 Zyklen bedeutete, dass die Unsicherheit für alle nachfolgenden Bytes in dasselbe Fenster mit 13 Zyklen passte (was wiederum in das 16-Zyklus-Fenster passte, in dem das Schreiben akzeptabel sein konnte auftreten).

Für ältere CPUs waren die Befehlszeitinformationen klar, verfügbar und eindeutig. Für neuere ARMs scheinen die Timing-Informationen viel vager zu sein. Ich verstehe, dass bei der Ausführung von Code aus dem Flash das Caching-Verhalten die Vorhersage erheblich erschweren kann. Daher würde ich davon ausgehen, dass Code mit Zykluszählung aus dem RAM ausgeführt werden sollte. Selbst wenn Code aus dem RAM ausgeführt wird, wirken die Spezifikationen etwas vage. Ist die Verwendung von zyklisch gezähltem Code immer noch eine gute Idee? Wenn ja, was sind die besten Techniken, damit es zuverlässig funktioniert? Inwieweit kann man mit Sicherheit davon ausgehen, dass ein Chiphersteller nicht stillschweigend in einen "neuen, verbesserten" Chip eintaucht, der in bestimmten Fällen die Ausführung bestimmter Anweisungen zyklisch verzögert?

Angenommen, die folgende Schleife beginnt an einer Wortgrenze, wie würde man anhand von Spezifikationen genau bestimmen, wie lange es dauern würde (angenommen, Cortex-M3 mit Null-Wartezustandsspeicher; für dieses Beispiel sollte nichts anderes über das System von Bedeutung sein).

myloop:
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  mov r0, r0; Kurze einfache Anweisungen, um das Vorabrufen weiterer Anweisungen zu ermöglichen
  fügt r2, r1, # 0x12000000 hinzu; 2-Wort-Anweisung
  ; Wiederholen Sie das Folgende, möglicherweise mit verschiedenen Operanden
  ; Addiert so lange Werte, bis ein Übertrag auftritt
  itcc
  Addscc r2, r2, # 0x12000000; 2-Wort-Anweisung plus zusätzliches "Wort" für itcc
  itcc
  Addscc r2, r2, # 0x12000000; 2-Wort-Anweisung plus zusätzliches "Wort" für itcc
  itcc
  Addscc r2, r2, # 0x12000000; 2-Wort-Anweisung plus zusätzliches "Wort" für itcc
  itcc
  Addscc r2, r2, # 0x12000000; 2-Wort-Anweisung plus zusätzliches "Wort" für itcc
; ... etc, mit mehr bedingten Zwei-Wort-Anweisungen
  Unter R8, R8, # 1
  bpl myloop

Während der Ausführung der ersten sechs Befehle hätte der Kern Zeit, sechs Wörter abzurufen, von denen drei ausgeführt würden, so dass bis zu drei vorabgerufen werden könnten. Die nächsten Anweisungen bestehen aus jeweils drei Wörtern, so dass der Kern Anweisungen nicht so schnell abrufen kann, wie sie ausgeführt werden. Ich würde erwarten, dass einige der "it" -Anweisungen einen Zyklus benötigen, aber ich weiß nicht, wie ich vorhersagen soll, welche.

Es wäre schön, wenn ARM bestimmte Bedingungen spezifizieren könnte, unter denen das "it" -Befehls-Timing deterministisch wäre (z. B. wenn es keine Wartezustände oder Code-Bus-Konflikte gibt und die vorhergehenden zwei Befehle 16-Bit-Register-Befehle usw. sind). aber ich habe keine solche Spezifikation gesehen.

Beispielanwendung

Angenommen, man versucht, eine Tochterplatine für einen Atari 2600 zu entwerfen, um eine Komponentenvideoausgabe mit 480P zu generieren. Der 2600 verfügt über einen Pixeltakt von 3,579 MHz und einen CPU-Takt von 1,19 MHz (Punkttakt / 3). Für 480P-Komponentenvideo muss jede Zeile zweimal ausgegeben werden, was eine Punkttaktausgabe von 7,158 MHz impliziert. Da der Atari-Videochip (TIA) eine von 128 Farben mit einem 3-Bit-Lumasignal und einem Phasensignal mit einer Auflösung von ungefähr 18 ns ausgibt, ist es schwierig, die Farbe nur durch Betrachten der Ausgänge genau zu bestimmen. Ein besserer Ansatz wäre, Schreibvorgänge in die Farbregister abzufangen, die geschriebenen Werte zu beobachten und jedes Register in die TIA-Luminanzwerte einzuspeisen, die der Registernummer entsprechen.

All dies könnte mit einem FPGA durchgeführt werden, aber einige recht schnelle ARM-Geräte sind weitaus billiger als ein FPGA mit genügend RAM, um die erforderliche Pufferung zu bewältigen (ja, ich weiß, dass für die Volumes, die so etwas produzieren, die Kosten nicht hoch sind). t ein realer Faktor). Das Erfordernis, dass der ARM das eingehende Taktsignal überwacht, würde jedoch die erforderliche CPU-Geschwindigkeit erheblich erhöhen. Vorhersagbare Zykluszahlen könnten die Dinge sauberer machen.

Ein relativ einfacher Entwurfsansatz besteht darin, dass eine CPLD die CPU und den TIA überwacht und ein 13-Bit-RGB + -Synchronsignal erzeugt und dann ARM-DMA 16-Bit-Werte von einem Port abruft und sie mit dem richtigen Timing in einen anderen schreibt. Es wäre jedoch eine interessante Designherausforderung, zu sehen, ob ein billiger ARM alles kann. DMA könnte ein nützlicher Aspekt eines All-in-One-Ansatzes sein, wenn seine Auswirkungen auf die CPU-Zykluszahlen vorhergesagt werden könnten (insbesondere, wenn die DMA-Zyklen in Zyklen auftreten könnten, in denen der Speicherbus ansonsten inaktiv war), aber zu einem bestimmten Zeitpunkt im Prozess Der ARM müsste seine Funktionen zur Tabellensuche und Busüberwachung ausführen. Beachten Sie, dass der Atari 2600 im Gegensatz zu vielen Videoarchitekturen, bei denen Farbregister während der Austastintervalle geschrieben werden, während des angezeigten Teils eines Frames häufig in Farbregister schreibt.

Vielleicht wäre der beste Ansatz, ein paar diskrete Logikchips zu verwenden, um Farbschreibvorgänge zu identifizieren und die unteren Bits der Farbregister auf die richtigen Werte zu zwingen, und dann zwei DMA-Kanäle zu verwenden, um die eingehenden CPU-Bus- und TIA-Ausgangsdaten abzutasten, und einen dritten DMA-Kanal zum Erzeugen der Ausgangsdaten. Die CPU kann dann alle Daten von beiden Quellen für jede Abtastzeile verarbeiten, die erforderliche Übersetzung durchführen und für die Ausgabe puffern. Der einzige Aspekt der Aufgaben des Adapters, der in "Echtzeit" erfolgen müsste, wäre das Überschreiben von Daten, die in COLUxx geschrieben wurden, und dies könnte unter Verwendung von zwei gemeinsamen Logik-Chips erledigt werden.

Superkatze
quelle

Antworten:

7

Ich stimme für DMA. Es ist in Cortex-M3 und höher sehr flexibel - und Sie können alle möglichen verrückten Dinge tun, z. B. Daten automatisch von einem Ort abrufen und mit einer bestimmten Rate an einen anderen ausgeben oder bei bestimmten Ereignissen, ohne dass CPU-Zyklen anfallen. DMA ist viel zuverlässiger.

Aber es könnte ziemlich schwer sein, im Detail zu verstehen.

Eine andere Option sind Soft-Cores auf FPGAs mit Hardware-Implementierung dieser engen Dinge.

BarsMonster
quelle
1
Ich mag den DMA-Begriff. Ich glaube jedoch nicht, dass der Cortex M3-Core über DMA verfügt - das hängt von den Chips der einzelnen Hersteller ab und scheint von allen unterschiedlich implementiert zu werden. Eine Sache, die ich bei mindestens einer Implementierung, mit der ich tatsächlich gespielt habe (STM32L152), als lästig empfinde, ist, dass ich bei der Ausgabe von DMA-Daten keinen Pin-Strobe finden kann. Es ist auch nicht klar, welche Faktoren die Aktualität von DMA beeinflussen können.
Superkatze
1
Auf jeden Fall habe ich in Bezug auf eine der ersten Anwendungen, die ich für präzises Cycle-Banging in Betracht gezogen habe, mehr Informationen in der ursprünglichen Frage veröffentlicht. Ich bin gespannt, was du denkst. Eine andere Situation, in der ich mir Gedanken über das Radfahren machte, war, Anzeigedaten auf ein Farb-LCD zu strahlen. Die Daten würden im RAM mit 8-Bit-Farben gepuffert, aber die Anzeige benötigt 16-Bit-Farben. Die schnellste Möglichkeit, Daten auszugeben, bestand darin, Hardware zum Generieren der Schreib-Strobes zu verwenden, sodass die CPU nur Daten austakten musste. Wäre es gut, 8-> 16-Bit in einen kleinen Puffer zu übersetzen ...
Supercat
1
... und dann veranlassen, dass DMA das überträgt, oder was wäre der beste Ansatz?
Superkatze
4

Timing-Informationen sind verfügbar, können jedoch, wie Sie bereits betont haben, gelegentlich vage sein. In Abschnitt 18.2 und Tabelle 18.1 des Technischen Referenzhandbuchs für den Cortex-M3 finden Sie zahlreiche Timing-Informationen ( pdf hier ) und einen Auszug hier:

Auszug aus dem 18.2

die eine Liste von Bedingungen für ein maximales Timing geben. Der Zeitpunkt für viele Anweisungen hängt von externen Faktoren ab, von denen einige Unklarheiten hinterlassen. Ich habe jede der Unklarheiten hervorgehoben, die ich im folgenden Auszug aus diesem Abschnitt gefunden habe:

[1] Zweige benötigen einen Zyklus für die Anweisung und laden die Pipeline dann erneut für die Zielanweisung. Nicht genommene Zweige sind insgesamt 1 Zyklus. Aufgenommene Zweige mit einem sofortigen Aufladevorgang bestehen normalerweise aus 1 Zyklus Pipeline-Aufladung (insgesamt 2 Zyklen). Aufgenommene Verzweigungen mit Registeroperanden bestehen normalerweise aus 2 Zyklen Pipeline-Neuladen (insgesamt 3 Zyklen). Das Neuladen der Pipeline ist länger [Wie viel länger?], Wenn zu nicht ausgerichteten 32-Bit-Befehlen verzweigt wird und auf langsameren Speicher zugegriffen wird. Auf dem Codebus wird ein Verzweigungshinweis ausgegeben, der das Vorladen eines langsameren Systems [Wie viel langsamer?] Ermöglicht. Dies kann [Ist das optional?] Die Verzweigungszielstrafe für langsameren Speicher reduzieren [Um wie viel?], Aber niemals weniger als hier gezeigt.

[2] Im Allgemeinen dauern Ladespeicherbefehle zwei Zyklen für den ersten Zugriff und einen Zyklus für jeden weiteren Zugriff. Geschäfte mit sofortigem Versatz benötigen einen Zyklus.

[3] UMULL / SMULL / UMLAL / SMLAL verwenden abhängig von der Größe der Quellwerte eine vorzeitige Beendigung [Welche Größen?]. Diese sind unterbrechbar (abgebrochen / neu gestartet) und haben im schlimmsten Fall eine Wartezeit von einem Zyklus. MLAL-Versionen dauern vier bis sieben Zyklen und MULL-Versionen dauern drei bis fünf Zyklen . Für MLAL ist die signierte Version einen Zyklus länger als die nicht signierte.

[4] IT-Anweisungen können gefaltet werden . [Wann? Zeige Kommentare.]

[5] Die DIV-Zeiten hängen von Dividende und Divisor ab . [Gleiches Problem wie bei MUL] DIV ist unterbrechbar (abgebrochen / neu gestartet) und hat im schlimmsten Fall eine Wartezeit von einem Zyklus. Wenn Dividende und Teiler sind in der Größe ähnlich [Wie ähnlich?] , wird die Division schnell beendet. Die Mindestzeit beträgt für Divisoren, die größer als Dividende und Divisor Null sind. Ein Divisor von Null gibt Null zurück (kein Fehler), obwohl ein Debug-Trap verfügbar ist, um diesen Fall abzufangen. [Welche Bereiche wurden für MUL angegeben?]

[6] Schlaf ist ein Zyklus für den Befehl plus so viele Schlafzyklen wie angemessen. WFE verwendet nur einen Zyklus, wenn das Ereignis verstrichen ist. WFI ist normalerweise mehr als ein Zyklus, es sei denn, ein Interrupt pendiert genau bei der Eingabe von WFI.

[7] ISB dauert einen Zyklus (fungiert als Verzweigung). DMB und DSB benötigen einen Zyklus, sofern keine Daten im Schreibpuffer oder in der LSU anstehen. Kommt während einer Schranke ein Interrupt, wird dieser abgebrochen / neu gestartet.

Für alle Anwendungsfälle ist es komplexer als die Zählung "Dieser Befehl ist ein Zyklus, dieser Befehl ist zwei Zyklen, dies ist ein Zyklus ...", die in einfacheren, langsameren, älteren Prozessoren möglich ist. In einigen Anwendungsfällen treten keine Mehrdeutigkeiten auf. Wenn Sie auf Unklarheiten stoßen, schlage ich vor:

  1. Wenden Sie sich an Ihren Händler, und fragen Sie ihn, zu welchem ​​Zeitpunkt die Anweisungen für Ihren Anwendungsfall vorliegen.
  2. Test, um das mehrdeutige Verhalten anzugeben
  3. Prüfen Sie erneut, ob Prozessorrevisionen vorliegen, insbesondere, wenn Herstelleränderungen vorgenommen werden.

Diese Anforderungen geben wahrscheinlich die Antwort auf Ihre Frage "Nein, es ist keine gute Idee, es sei denn, die aufgetretenen Schwierigkeiten sind die Kosten wert" - aber das wussten Sie bereits.

Kevin Vermeer
quelle
1
Ich würde das Folgende als vage betrachten: "Das Neuladen von Pipelines ist länger, wenn zu nicht ausgerichteten 32-Bit-Befehlen verzweigt wird, zusätzlich zu Zugriffen auf langsameren Speicher" sagt nicht aus, ob es genau einen Zyklus hinzufügt, und "IT-Befehle können gefaltet werden" nicht nicht angeben, unter welchen Bedingungen sie sein werden oder nicht.
Supercat
1
Das "IT" -Timing scheint besonders problematisch zu sein, da dies eine Anweisung ist, die häufig in einer engen Schleife mit gezählten Zyklen verwendet wird, und ich bin mir ziemlich sicher, dass sie nicht immer geklappt werden kann. Ich würde vermuten, dass man, wenn man immer zum Anfang einer zeitabhängigen Schleife verzweigt, die Schleife zwingt, an einer Wortgrenze zu beginnen, bedingte Ladevorgänge oder Speicherungen innerhalb der Schleife vermeidet und keine "IT" -Anweisung sofort abgibt Nach dem Laden oder Aktualisieren des Registers wären die "IT" -Zeitangaben konsistent, aber die Spezifikation macht das nicht klar.
Superkatze
1
Meine Vermutung wäre, dass die IT wahrscheinlich (wahrheitsgemäß) Folgendes bemerken könnte: "Ohne Wartezustände oder Code-Bus-Konflikte ist die IT-Faltung garantiert, wenn (1) der vorhergehende Befehl ein 16-Bit-Befehl war, auf den nicht zugegriffen wurde Speicher oder Programmzähler, und (2) entweder ist der nächste Befehl ein 16-Bit-Befehl oder der vorhergehende Befehl war nicht das Ziel einer "nicht ausgerichteten" Verzweigung. Eine solche Spezifikation würde es ermöglichen, Programme mit vorhersagbarem IT-Befehls-Timing zu schreiben, indem sichergestellt wird, dass der Code wie angegeben angeordnet ist.
Superkatze
1
Wow - ich gebe zu, dass ich nur einfache Zykluszählungen im schlimmsten Fall durchlaufen habe, anstatt tatsächlich mit den Vorbehalten unter dem Tisch zu kämpfen. Meine aktualisierte Antwort zeigt einige andere Unklarheiten auf.
Kevin Vermeer
1
Es gibt viele Situationen, in denen man an Worst-Case-Zählungen interessiert ist, und eine faire Zahl, in der man an Best-Case-Zählungen interessiert ist (z. B. wenn ein SPI-Port alle 16 Zyklen ein Byte ausgeben kann, würde das Generieren jedes Bytes 14 Zyklen dauern Im besten Fall würde die Prüfung der Bereitschaft 5 Zyklen dauern, im besten Fall würde die Prüfung der Bereitschaft für jedes Byte die Geschwindigkeit auf ein Byte pro 19 Zyklen begrenzen, und im besten Fall würde blindes Schreiben mit zwei hinzugefügten NOPs eine Geschwindigkeit von einem Byte pro 16 Zyklen ermöglichen ). Die Fälle, in denen ein genaues Timing erforderlich ist, sind nicht so häufig, können jedoch auftreten.
Superkatze
3

Eine Möglichkeit, dieses Problem zu umgehen, besteht darin, Geräte mit deterministischen oder vorhersagbaren Timings zu verwenden, z. B. die Parallax Propeller- und XMOS-Chips:

http://www.parallaxsemiconductor.com/multicoreconcept

http://www.xmos.com/

Das Zählen von Zyklen funktioniert sehr gut mit dem Propeller (Assembler-Sprache muss verwendet werden), während die XMOS-Geräte über ein sehr leistungsfähiges Software-Dienstprogramm verfügen, den XMOS Timing Analyzer, der mit Anwendungen arbeitet, die in der Programmiersprache XC geschrieben sind:

https://www.xmos.com/download/public/XMOS-Timing-Analyzer-Whitepaper%281%29.pdf

Leon Heller
quelle
1
Ich fange an zu glauben, dass Leon Anteile an XMOS hat ... ;-)
Federico Russo
1
Ich mag nur ihre Chips und die Leute, die dort arbeiten. Parallax ist auch eine nette Firma mit guten Produkten.
Leon Heller
1
Ja, nichts für ungut. Mir fällt auf, dass alle Antworten (mit Ausnahme einer), bei denen XMOS erwähnt wird, von Ihnen stammen. Es ist nichts Falsches daran, von etwas begeistert zu sein.
Federico Russo
@Federico, @Leon - Genau das beunruhigt mich bei XMOS: Warum gibt es nur einen Benutzer auf der Welt (zumindest sieht es so aus)? Wenn es so toll ist, warum ist es nicht das Gerede der Stadt? Ich habe noch nie jemanden darüber reden hören, noch weniger davon.
Stevenvh
Probieren Sie die XMOS-Foren aus: xcore.com
Leon Heller
2

Das Zählen von Zyklen wird problematischer, wenn Sie sich von Mikrocontrollern auf niedriger Ebene entfernen und auf Prozessoren für allgemeine Zwecke umsteigen. Die ersten haben in der Regel ein genau festgelegtes Anweisungs-Timing. Das liegt auch daran, dass ihre Architektur ziemlich einfach ist, sodass die Unterrichtszeiten fest und bekannt sind.

Ein gutes Beispiel dafür sind die meisten Microchip-PICs. Die Serien 10, 12, 16 und 18 haben eine sehr gut dokumentierte und vorhersehbare Befehlszeit. Dies kann ein nützliches Merkmal bei kleinen Steuerungsanwendungen sein, für die diese Chips vorgesehen sind.

Wenn Sie sich von extrem niedrigen Kosten verabschieden und der Designer daher mehr Chipfläche aufwenden kann, um eine höhere Geschwindigkeit durch eine exotischere Architektur zu erzielen, verlieren Sie auch die Vorhersehbarkeit. Schauen Sie sich moderne x86-Varianten als extreme Beispiele an. Es gibt mehrere Ebenen von Cache-Speichern, Speicher-Virtualisierung, Lookahead-Abruf, Pipelining und mehr, die das Zählen von Befehlszyklen nahezu unmöglich machen. Bei dieser Anwendung spielt es jedoch keine Rolle, da der Kunde an einer hohen Geschwindigkeit interessiert ist und nicht an einer Vorhersagbarkeit des Befehlszeitpunkts.

Sie können diesen Effekt sogar bei höheren Microchip-Modellen beobachten. Der 24-Bit-Kern (24-, 30- und 33-Bit-Serie) hat ein weitgehend vorhersagbares Befehls-Timing, mit Ausnahme einiger Ausnahmen, wenn Register-Bus-Konflikte vorliegen. In einigen Fällen fügt die Maschine beispielsweise einen Stillstand ein, wenn der nächste Befehl ein Register mit einigen indirekten Adressierungsmodi verwendet, deren Wert im vorherigen Befehl geändert wurde. Diese Art von Stall ist auf einem dsPIC ungewöhnlich, und die meiste Zeit kann man sie ignorieren, aber es zeigt, wie sich diese Dinge einschleichen, weil die Designer versuchen, Ihnen einen schnelleren und leistungsfähigeren Prozessor zu bieten.

Die grundlegende Antwort lautet also, dass dies Teil des Kompromisses ist, wenn Sie sich für einen Prozessor entscheiden. Für kleine Steuerungsanwendungen können Sie etwas Kleines, Billiges, Niedriges mit vorhersagbarem Befehlszeitpunkt auswählen. Wenn Sie mehr Rechenleistung benötigen, ändert sich die Architektur, sodass Sie auf ein vorhersehbares Anweisungs-Timing verzichten müssen. Glücklicherweise ist dies weniger ein Problem, wenn Sie zu rechenintensiveren und universell einsetzbaren Anwendungen gelangen, sodass die Kompromisse meiner Meinung nach einigermaßen gut funktionieren.

Olin Lathrop
quelle
Ich stimme zu, dass die rechenintensiveren Anwendungen im Allgemeinen weniger empfindlich auf das mikroskopische Timing reagieren. Es gibt jedoch einige Szenarien, in denen möglicherweise etwas mehr Verarbeitungsaufwand als beim PIC-18 erforderlich ist, aber auch Vorhersagbarkeit erforderlich ist. Ich frage mich, inwieweit ich mich bemühen sollte, Dinge wie die 16-Bit-PIC-Architekturen zu lernen, oder inwieweit ich davon ausgehen sollte, dass der ARM wahrscheinlich angemessen sein wird.
Superkatze
0

Ja, Sie können es immer noch tun, auch auf einem ARM. Das größte Problem bei einem ARM ist, dass ARM Kerne verkauft, keine Chips, und das Kern-Timing ist bekannt, aber was der Chip-Anbieter umgibt, variiert von Anbieter zu Anbieter und manchmal von Chip-Familie zu einer anderen innerhalb des Anbieters. Ein bestimmter Chip eines bestimmten Anbieters kann also durchaus deterministisch sein (wenn Sie beispielsweise keine Caches verwenden), ist jedoch schwerer zu portieren. Wenn Sie mit 5 und dort mit 11 Uhren arbeiten, ist die Verwendung von Timern problematisch, da die Anzahl der Anweisungen zum Abtasten des Timers und zum Ermitteln, ob Ihr Timeout abgelaufen ist. Nach den Klängen Ihrer bisherigen Programmiererfahrung bin ich bereit zu wetten, dass Sie wahrscheinlich mit einem Oszilloskop debuggen, so wie ich es tue. Sie können also eine enge Schleife auf dem Chip mit der Taktrate versuchen, den SPI oder den I2C betrachten oder eine beliebige Wellenform hinzufügen oder nops entfernen, Ändern Sie die Anzahl der Male durch die Schleife und stimmen Sie im Grunde. Wie bei jeder Plattform trägt die Nichtverwendung von Interrupts erheblich zur deterministischen Ausführung von Befehlen bei.

Nein, es ist nicht so einfach wie ein PIC, aber dennoch durchaus machbar, insbesondere wenn die Verzögerung / Taktung der Taktrate des Prozessors nahekommt. Bei einigen ARM - basierten Anbietern können Sie die Taktrate multiplizieren und etwa 60 MHz aus einer 8 - MHz - Referenz herausholen. Wenn Sie also eine 2 - MHz - Schnittstelle benötigen, anstatt alle 4 Anweisungen etwas zu tun, können Sie die Taktrate erhöhen (wenn Sie die haben) Energiehaushalt) und verwenden Sie dann einen Timer und geben Sie sich viele Uhren, um auch andere Dinge zu tun.

Oldtimer
quelle