Richtige Methode zum Warten von N Zyklen in ARM Cortex-M4

Nachdem Sie eine Uhr für einen bestimmten Port aktiviert haben, müssen Sie 4 Zyklen warten, bis die Uhr die Initialisierung abgeschlossen hat. Wie kann man richtig auf N Zyklen warten?

In meinem Code habe ich das verwendet:

__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");

Danach scheint die uKeil IDE aufzuhören, sich zu beschweren.

Alternativ warten Sie auf das Uhrenstatusregister. Falls die Initialisierung länger dauert als erwartet (PLL-Fehler oder Stromausfall/Quarzstart)
NOPs sind eine schlechte Idee. "NOP tut nichts. NOP ist nicht unbedingt ein zeitaufwendiges NOP. Der Prozessor entfernt es möglicherweise aus der Pipeline, bevor es die Ausführungsphase erreicht. Verwenden Sie NOP zum Auffüllen, um beispielsweise die folgende Anweisung an einer 64-Bit-Grenze zu platzieren." was von infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/… zitiert wird
Diese MCUs sind Pipeline-basiert und nicht deterministisch, sodass Sie im Gegensatz zu den alten Tagen nicht einfach Anweisungen einfügen und davon ausgehen können, dass sie einige Zeit in Anspruch nehmen. Sie können einigen Code in einer bestimmten Situation sicher optimieren, aber Sie müssen ihn optimieren, Sie können nicht nur Anweisungen zählen. Der richtige Weg, eine bestimmte Zeit zu verbrauchen, ist die Verwendung eines Timers (und dann gibt es die nicht deterministische Latenz und den damit verbundenen Handler-Code, der jedoch vorhersehbarer und zuverlässiger ist als Anweisungen zum Zählen von Hand).
wenn man sich auf einfache weise die zeit totschlagen will und sich der compiler nicht in die wege stellt, funktioniert voltatile, ich bevorzuge eine dummy-funktion, an irgendeiner stelle den befehl bx lr. dann mache eine Schleife for(i=0;i<100;i++) dummy(i); und der Compiler kann diese Schleife nicht wegoptimieren.

Antworten (1)

Dies ist eine Methode von hier :

 volatile unsigned long delay;

 SYSCTL_RCGC2_R |= 0x00000010;   // 1) activate clock for Port E
 delay = SYSCTL_RCGC2_R;         //    allow time for clock to stabilize

Sie könnten uns auch die Uhr(en) einrichten und für ein paar Zyklen etwas anderes tun (etwas initialisieren), aber das ist ein potenzieller Fehler in der Zukunft.


Bearbeiten: Die Dummy-Zeile kompiliert zu:

  400286:   681b        ldr r3, [r3, #0]
  400288:   9301        str r3, [sp, #4]

Auf dem Cortex M4

ldr ist 2 Zyklen

str ist 2 Zyklen

Siehe hier für M4-Zykluszählungen.

Das Schlüsselwort volatile verhindert, dass die Anweisungen ldr und str kombiniert werden, wie ich es verstehe.

Ich sehe, was du da gemacht hast.
Ich habe das schon einmal gesehen, aber es ist sehr vage für mich. Woher weiß ich, ob eine Dummy-Aufgabe mindestens 4 Zyklen dauert?
@Daveel; Ich denke, "Gedächtnisbarrieren" und "flüchtig" werden Ihnen die Antwort geben