Festlegen der Timer-Interruptzeit

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.

Antworten (3)

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.

Genau so verwende ich meine ISR (nur um ein Inkrement einer Variablen zu starten und den Wert der Variablen in main () zu überprüfen). Aber damit das Timing konsistent ist, darf die ISR niemals richtig gestoppt werden (im Gegensatz zu dem, was Sie gesagt haben)? Timer aktivieren.
Ich habe nicht gesagt, dass Sie den Timer während Ihres gesamten Schreibens deaktivieren müssten. Was ich gesagt habe, war, dass, wenn der Code richtig geschrieben ist, das Schreiben nicht durch den Timer-Interrupt beschädigt wird. Ich fuhr dann fort, dass es manchmal kritische enge Fenster geben kann, in denen Sie Interrupts für eine sehr kurze Zeit deaktivieren müssen. Dies könnte für eine Chip-Timing-Abhängigkeit sein oder wenn Sie eine atomare Operation für ein Datenelement garantieren müssen, für dessen Ausführung mehrere CPU-Anweisungen erforderlich sind.
Wie @berendi betonte, sollte es für die SPI-Situation in Ordnung sein, solange ich nicht mit SPI-Registern von der Timer-ISR herumspiele, oder?

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.

Ich verwende SST25VF010A. Ich werde es prüfen. Sie sagen, dass, wenn mein Timer-Interrupt tatsächlich 500 us von 1 ms (im schlimmsten Fall) dauert, ich den Timer-Interrupt für eine maximale Zeit von weniger als 1 ms (Zeit vor dem nächsten Interrupt) + verbleibende 500 us (verfügbar ab dem 1. Interrupt) deaktivieren kann, wenn ich habe um die Timeout-Integrität aufrechtzuerhalten?.
Nein, deaktivieren Sie Interrupts nicht länger als 1 ms. Nehmen wir den schlimmsten Fall an: Die Timer-Interrupt-Anforderung tritt auf, während Sie Interrupts in der Hauptanwendung deaktivieren. Wenn Sie nun Interrupts länger als 1 ms deaktiviert lassen, würde ein zweiter Timer-IRQ auftreten, während der Prozessor den ersten noch nicht bedienen konnte, sodass ein Interrupt verloren geht.
Wie kann der zweite Timer-IRQ auftreten, wenn ich den Interrupt deaktiviere? Wie können Sie auch "Unterbrechungen nicht länger als 1 ms deaktivieren" verfolgen, ohne dass ein Timer mir sagt, dass ich 1 ms nicht überschreiten soll??
- Es tritt kein Interrupt auf, es erfolgt eine Anfrage. Ich fordere Sie auf, mit dem aufzuhören, was Sie tun, aber Sie hören mich nicht, dann hören Sie nicht auf. - Ein Software-Interrupt-Timer läuft einfach nicht weiter, während Interrupts deaktiviert sind. Sie können dies nicht verwenden, um die Zeit zu verfolgen, die mit deaktiviertem Interrupt verbracht wurde. - Wenn Sie denken, Sie müssen Interrupts für mehr als 1 ms deaktivieren, dann überlegen Sie es sich, es sollte einen anderen Weg geben. Solche Konstrukte sollte man in der eingebetteten Programmierung vermeiden. Beschreiben Sie vielleicht das genaue Problem in einer separaten Frage, komplett mit der Beschreibung Ihrer Hardware.
Ich verwende einen Hardware-Timer-Interrupt. Kein Software-Interrupt.
Wenn Sie einen Hardware-Timer verwenden , können Sie seine Register lesen, um jederzeit die verstrichene Zeit zu bestimmen . Wenn Sie andererseits einen Hardware-Interrupt haben, der einen Interrupt-Handler (der Software ist) aufruft, der einen Software-Timer-Zähler erhöht, dann haben Sie ein Problem, wenn Interrupts zu lange deaktiviert sind.
Exakt. Ich verwende einen Hardware-Timer, der einen Software-Timer-Zähler erhöht. Daher die Frage.

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.