Ich habe in meiner Anwendung Timer-Interrupts verwendet, hauptsächlich aus Zeitgründen wie Timeout-Erkennung für Prozesse, Impulserzeugung usw. alle 1 ms. Jetzt habe ich Zweifel.
Angenommen, in main(), wenn ich eine andere Operation durchführe, wie vielleicht das Schreiben eines großen Datenblocks auf einen SPI-Flash, und der Timer-Interrupt auftritt, wird der Datenschreibprozess aufgrund einer Unterbrechung durch den Timer-ISR angehalten oder Daten werden aufgrund einer Unterbrechung beschädigt durch Timer ISR? Ich frage mich nur, ob die Timer-Interruptzeit unter Berücksichtigung solcher Operationen entschieden wird, aus denen der vollständige Anwendungscode besteht.
Wenn ja, wenn ein SPI-Flash-Schreibvorgang etwa 5 ms dauert und ein Timer-Interrupt alle 1 ms auftritt, wie kann ich Zeitüberschreitungen, Impulserzeugung usw. verfolgen, ohne Datenbeschädigungsszenarien zu gefährden, da ich jetzt den Timer-Interrupt auf mehr als 5 ms ändern muss , und dann kann ich keine Referenz von Timeouts für Prozesse führen, bei denen kleine Timeouts wie 1 ms erforderlich sein können.
Aktualisieren
Ich verwende einen Hardware-Timer, und wenn der Interrupt auftritt, verwende ich einen Software-Timer-Zähler (Variable) in der ISR, um die Zeit im Auge zu behalten.
Wenn Sie den Mainline-Code schreiben, in dem die SPI-Flash-Schreibvorgänge auf die richtige Weise stattfinden, sollte das Auftreten des Timer-Interrupts den laufenden Vorgang nicht beschädigen. Wenn der Hauptstrombetrieb bestimmte Zeitabhängigkeiten aufweist, die beibehalten werden müssen, dann ist es notwendig, die Interrupts für kurze Zeiträume zu deaktivieren, wenn die kritischen Zeitfenster auftreten.
Eine andere Sache ist, den Code im Timer-Interrupt sehr einfach und prägnant zu halten. Geben Sie keinen echten Entscheidungscode in die Zeitgeberroutine ein. Machen Sie sich stattdessen eine Sammlung von Software-verwalteten Timer-Variablen. Der Timer-Interrupt überprüft einfach jede dieser Variablen, und wenn er nicht Null ist, würde er den Wert einfach um eins verringern. Der Mainstream-Code würde eine oder mehrere dieser Variablen auf geeignete Nicht-Null-Werte setzen, wenn eine Zeitspanne benötigt wird. Dann kann die Zeitgebervariable im normalen Verlauf ihrer Hauptoperationen überprüft werden, um zu sehen, ob sie auf Null gegangen ist. Dies kann somit signalisieren, dass ein Timeout oder eine Zeitverzögerung aufgetreten ist.
Wenn ein großer Datenblock auf einen SPI-Flash geschrieben wird und der Timer-Interrupt auftritt, wird der Datenschreibvorgang aufgrund einer Unterbrechung durch den Timer-ISR angehalten oder werden Daten aufgrund einer Unterbrechung durch den Timer-ISR beschädigt?
Auf keinen Fall (aber überprüfen Sie das Datenblatt Ihres Blitzes, um sicherzugehen). SPI-Flash hat keine Timeouts, nur Untergrenzen für Timings. Sie haben alle Zeit der Welt, um einen Schreibvorgang oder eine andere Operation abzuschließen. Es sollte keine Datenkorruption auftreten, solange Sie die SPI-Register nicht innerhalb Ihres ISR berühren (für Anfänger würden Sie später etwas sperren).
ob die Timer-Interruptzeit unter Berücksichtigung solcher Operationen entschieden wird, die den vollständigen Anwendungscode bilden?
Natürlich sollten Sie immer die Zeit berücksichtigen, die möglicherweise in einem Interrupt-Handler verbracht wird. Wenn Sie eine wirklich zeitkritische Aufgabe zu erledigen haben, können Sie Interrupts für kurze Zeit deaktivieren, machen Sie einfach Folgendes
Die Summe der maximalen Zeit, die in Interrupt-Handlern und in einem kritischen Abschnitt (wo Interrupts deaktiviert sind) verbracht wird, sollte die Zeit zwischen aufeinanderfolgenden Interrupts des gleichen Typs nicht überschreiten.
Auf diese Weise haben Sie immer noch eine genaue Zeitmessung und verlieren keine Unterbrechungen. Die meisten (wenn nicht alle) Interrupt-Controller sind intelligent genug, um eine Interrupt-Anfrage zu halten, bis die CPU sie verarbeiten kann, aber sie verfolgen nicht, wie viele Anfragen des gleichen Typs ohne Bedienung aufgetreten sind.
Zusätzlich zu dem, was @berendi gesagt hat, können Sie zwei Dinge tun.
1) Deaktivieren Sie Interrupts, kurz bevor Sie die kritische Datenübertragung durchführen. Und verwenden Sie stattdessen die Abfrage. Angenommen, Sie übertragen Daten aus einem Puffer, senden Sie etwa 10 Datenrahmen (verwenden Sie hier eine beliebige Zahl) und fragen Sie den Interrupt-Pin ab. Auch wenn der Interrupt deaktiviert ist, wird das Flag gesetzt, sodass Sie sich dem Ereignis annähern* können, ohne die Datenübertragung anhalten zu müssen.
2) Halten Sie den Interrupt aktiviert. Haben Sie sehr wenige Anweisungen innerhalb der ISR. Ein Hochgeschwindigkeitscontroller ist in der Lage, sehr kleine Prozesse zwischen der Datenübertragung zu bewältigen**. Da das SPI-Peripheriegerät die Last übernimmt, sobald Sie die Daten in den Puffer ausgeben, hat der Prozessor dazwischen nur wenig Zeit. Es kann gut kalkulierte Ereignisse aufnehmen. Berücksichtigen Sie die Interrupt-Eingangs- und -Ausgangslatenz sowie die Verarbeitungszeit der Anweisungen.
Wenn der Controller alternativ DMA unterstützt, kann Ihr Anliegen einfach angegangen werden.
*vorausgesetzt, Sie tun dies häufig genug, um zwei Ereignisse zu erkennen.
** Während kritischer Datenübertragungen wird empfohlen, Interrupts zu deaktivieren und zu aktivieren.
AlphaGoku
Michael Karas
AlphaGoku