Gute Ansätze zur Implementierung von mehr als einer zeitkritischen Funktion mit einem Mikrocontroller?

8

Welche Philosophie oder welchen Ansatz verfolgt man bei der Implementierung hochkritischer Funktionen in Mikrocontrollern, falls vorhanden?

Ich arbeite an einem Projekt, bei dem eine präzise Rechteckwellenform mit unterschiedlicher Frequenz ausgegeben wird. Ich habe dies mit einem Timer und einer Interrupt-Funktion gemacht. Um dies jedoch korrekt zu implementieren, musste ich den Offset für die Anzahl der Taktzyklen kalibrieren, die während der Interrupt-Serviceroutine ausgeführt wurden. Ich würde mir vorstellen, dass diese Präzision gestört würde, wenn eine andere solche Wellenform nebeneinander laufen würde (sagen wir, die Frequenz müsste genau zur gleichen Zeit geändert werden). Es scheint verschwenderisch, für jede solche Zeit einen Mikrocontroller zu haben.

Nehmen Sie ein anderes Beispiel für die Implementierung einer Uhrfunktion (wie in hh: mm: ss). Ich kann mir nicht vorstellen, dass jeder High-Level-Mikrocontroller / Computer über einen dedizierten Echtzeituhr-Chip verfügt, um die Zeit im Auge zu behalten. Es fällt mir jedoch schwer, mir vorzustellen, dass es mit dem Kernprozessor genau gemessen wird, der gerade eine Vielzahl von Funktionen bedient, die in der Zwischenzeit in asynchronen Intervallen ausgeführt werden. Ich würde mir vorstellen, dass die Zeitzählung Offset-Fehler hat, die sich abhängig von den ausgeführten Funktionen ändern.

Gibt es einen Entwurfsprozess oder einen Ansatz, um die erreichbare Präzision einzudämmen oder zu tolerieren? Oder hat jemand Hinweise oder Vorschläge, wo ich weitere Informationen dazu finden könnte?

Mitternachtsblau
quelle
Dinge, die eine genaue RTC erfordern, haben häufig einen dedizierten Chip oder eine Unterfunktion mit eigener Leistung und Kristall, um die Zeit zu verfolgen, wenn das Gerät ausgeschaltet wird. Die Zeit ist ein großer Aufwand.
pjc50
Verwenden Sie keine so schreckliche Architektur mehr (oder verwenden Sie sie nicht mehr richtig) - Hardware-Timer sollten nicht von der Zeit abhängen, die für die Wartung des ISR aufgewendet wird -, solange das Nachladen "rechtzeitig" erfolgt, sollte dies keine Rolle spielen.
Spehro Pefhany
Welcher Mikrocontroller? Dies würde qualitativ bessere Antworten ermöglichen.
StainlessSteelRat
@ SpehroPefhany Ich muss sagen, ich bin ziemlich unerfahren darin. Das Problem, das ich mit der Rechteckwelle habe, besteht darin, dass ich möchte, dass sich die Frequenz bei jedem Ausgangsübergang ändert (können) (was für 2 verschiedene Rechteckwellen in asynchronen Intervallen erfolgen würde und möglicherweise sogar zusammenfallen könnte). Eine Rechteckwelle war ein kleinerer Teil einer größeren Frage, die ich mir vorgestellt hatte. Wie würden Sie bei der Wellenformgenerierung mehr als eine beliebige analoge Wellenform implementieren? Wäre das Opfer eine gemeinsame "Abtastrate"?
MitternachtBlau
@StainlessSteelRat Ich habe bewusst keinen bestimmten Mikrocontroller angegeben, da ich der Meinung war, dass die Frage ziemlich weit gefasst war. Für mich scheint es, dass es für die Prozessorarchitektur in großen Computern bis hin zu Mikrocontrollern gelten könnte. Zum Teil möchte ich wissen, ob Ressourcen verfügbar sind, um zu lernen, wie man gute Designs erstellt / den Fehler begrenzt, wenn mehr als eine zeitkritische Funktion implementiert wird.
MitternachtBlau

Antworten:

10

Verwenden Sie die Hardware, um präzise Rechteckwellen auszugeben. In den meisten Mikrocontrollern sind PWM-Generatoren eingebaut, die dies können. Sie stellen die Periode und die Einschaltzeit in Taktzyklen ein, den Rest erledigt die Hardware. Um es auf eine neue Frequenz zu ändern, schreiben Sie die neue Periode in das Periodenregister und die Hälfte der Periode in das Arbeitszyklusregister.

Die Echtzeituhr, die aufgrund einer anderen Auslastung des Prozessors Zeit verliert, funktioniert nur dann so, wenn sie sehr schlecht geschrieben ist. Im Allgemeinen wird die Hardware verwendet, um einen periodischen Interrupt zu erstellen, der einige Vielfache von Sekunden beträgt, und die Firmware teilt sich weiter von dort. Dies funktioniert unabhängig davon, wie beschäftigt der Prozessor ist, da der Interrupt immer dann ausgeführt wird, wenn er benötigt wird. Solange die Interruptroutine einen kleinen Teil der Gesamtzyklen in Anspruch nimmt, wird der größte Teil des Prozessors immer noch auf die Vordergrundaufgabe angewendet.

Es gibt auch Möglichkeiten, die Zeit durch Abfragen in unbekannten Intervallen zu halten. Sie müssen die Hardware zählen lassen, und wann immer Sie mit der Aktualisierung der Uhr beginnen, aktualisieren Sie sie basierend auf der Gesamtzahl der verstrichenen Ticks. Solange diese Routine oft genug ausgeführt wird, damit der verwendete Zähler nicht zwischen den Läufen umbrochen wird, geht keine Zeit verloren.

Olin Lathrop
quelle
Es tut uns leid! Ich hätte mit meiner Frage breiter sein sollen. Eine Rechteckwelle war nur ein besonderes Beispiel für eine zeitkritische Anwendung, an die ich gedacht hatte. Wäre es mit der von Ihnen erwähnten PWM-Generatormethode möglich (falls erforderlich), die Frequenz bei jedem Rechteckwellenübergang zu aktualisieren? Was wäre, wenn Sie dies für zwei asynchrone Rechteckwellen tun müssten? Was ist mit zehn? Ich frage mich, ob es für solche Dinge allgemeine Designansätze gibt. Die Methoden, die Sie für die periodische Unterbrechung und Abfrage zur Aktualisierung der Uhr erwähnen, werfen sicherlich etwas Licht auf.
MitternachtBlau
1
@mid: Die meisten Mikros können zu Beginn einer PWM-Periode unterbrechen. Einige haben doppelt gepufferte Register, sodass Sie die Parameter während eines Zeitraums aktualisieren und sie dann zu Beginn des nächsten Zeitraums wirksam werden lassen können. Einige Mikros können die PWM über DMA speisen. Ich habe dies einmal verwendet, um die Hardware automatisch zum Dithering zu bringen.
Olin Lathrop
3

Das Schlüsselwort hier ist "Hardware-Unterstützung". Für alles Ernsthafte benötigen Sie unterstützende Hardware im µC. Das gebräuchlichste integrierte Peripheriegerät ist eine Zeitgeberschaltung, die relativ präzise und ohne Störung durch andere CPU-Operationen läuft.

Darauf aufbauend können viele Funktionen mit einem mittelfristigen Timing ausgeführt werden, das so präzise ist wie die Taktquelle Ihres Controllers.

Aber: Wie Sie vielleicht bereits erfahren haben, gibt es neben der mittel- oder langfristigen Genauigkeit immer auch Timing- Jitter bei der Software-Behandlung von Hardware-Ereignissen (einschließlich Dingen wie Timer-Überlauf). Dies wird durch verschiedene mögliche Ausführungszustände zum Zeitpunkt des Auftretens eines Ereignisses verursacht, die zu unterschiedlichen Verzögerungen führen, bis die tatsächliche Reaktion auf das Ereignis eintreten kann.

Daher lautet das Fazit: Für alles, was Jitter mit hoher Geschwindigkeit oder nahezu Null erfordert, ist Hardware-Unterstützung unerlässlich. Viele Hardware-Peripheriegeräte sind in den meisten µCs enthalten, wie z. B. UARTs & c. Je leistungsfähiger und kostspieliger die µCs sind, desto mehr unterstützende Hardware ist normalerweise integriert. Wenn Ihr µC nicht die Hardware bereitstellt, die Sie benötigen, müssen Sie in der Tat externe, dedizierte Hardware für die Aufgabe in Betracht ziehen.

JimmyB
quelle
Das Verständnis von Jitter ist der Schlüssel - Sie können mehrere Hardware-Timer haben, die alle unabhängig voneinander den Überblick behalten. Wenn jedoch alle gleichzeitig einen Interrupt auslösen, können nicht alle gleichzeitig gewartet werden.
pjc50
2

Machen Sie so viel wie möglich mit Hardware, insbesondere für sehr zeitkritische Funktionen. Alle Mikrocontroller verfügen über Timer / Zähler, die speziell zum Zählen und Zeitsteuern von Ereignissen erstellt wurden.

Abgesehen davon ist dies wirklich eine sehr breite Frage. Es gibt also keine gute Antwort.

Die einzig wahre Antwort ist Erfahrung. Probieren Sie es aus, profilieren Sie es, betonen Sie es, reparieren Sie es. Sie müssen Codebereiche mit hoher Nutzung identifizieren. 20% der Software, die 90% der Zeit ausgeführt wird, bedeutet, dass jede entfernte Anweisung die Leistung verbessert.

Gutes Design hat immer Hardware, Software und Speicher in Einklang gebracht. Dies gilt für alle Mikroprozessoren, insbesondere aber für Mikrocontroller. Maximieren Sie eine oder verwenden Sie eine ineffizient und Sie haben ein schlechtes Produkt. Mit zunehmender Siliziumdichte sind immer mehr Merkmale in der Hardware von Mikrocontrollern enthalten. Mehr Funktionen bedeuten jedoch mehr Erwartungen. Wenn Sie den integrierten Speicher verdoppeln, fügen Sie eine Funktion hinzu, die ihn verwendet.

Alle ISRs haben Overhead, der von den vom ISR verwendeten Registern abhängt. Wenn die Latenz zum Speichern des Maschinenzustands im Vergleich zur Wartung des ISR für sehr zeitkritische Funktionen erheblich ist, ist Ihr Design möglicherweise nicht skalierbar. Daher der allgemeine Konsens der Antworten auf die Verwendung von Hardware.

Die Verwendung von Software-Interrupts kann das Aufblähen des ISR-Maschinenzustands verringern.

// Timer0 ISR
Temp = Temp + 1
if (Temp == 150)
    call Inc_Seconds()

Alle Register für Inc_Seconds () müssen verschoben werden, wenn sie nur einmal alle 150 Zyklen verwendet werden.

// Timer0 ISR
Temp = Temp + 1
if (Temp == 150)
    _Software_Interrupt
...
// Software_Interrupt ISR
    call Inc_Seconds()

Jetzt tritt der Latenzschlag nur einmal alle 150 Zyklen auf.

Wenn Sie eine Echtzeituhr in hh: mm: ss implementieren, spielt es eine Rolle, ob sie 50 ms entfernt ist. Keine Person würde den Fehler erkennen. Dies ist sicherlich kein Echtzeit-Betriebsproblem.

Wie für Ereignisse, die gleichzeitig auftreten müssen. Müssen sie? Wenn sie müssen, muss sich das Hardware-Design darum kümmern. Andernfalls muss ein Software-Kompromiss stattfinden. Wenn Sie nicht zwei Bits gleichzeitig setzen können, setzen Sie ein Bit. Nächster Befehlssatz der andere. Genauigkeit eines Taktzyklus bei RISC-Prozessoren. Ich würde behaupten, das war gut genug.

StainlessSteelRat
quelle
0

Für Rechteckwellenformen sollten Sie ein PWM-Peripheriegerät verwenden, das mit Ihrem XTAL unter Verwendung eines Zählers PLL-fähig ist, um zu wissen, wann ein Zyklus durchgeführt werden muss (zum Einstellen der wenigen Frequenzen). In jedem Datenblatt erfahren Sie, wie das geht :)

Um die Zeit zu halten , benötigen Sie eine RTC, um dies nahezu genau zu tun, es sei denn, Sie gehen zu Assembler- und Author-Opcodes, damit Sie das genaue Exec-Timing jedes Befehls in einem Exec-Pfad von Hand kennen. Es wird wahrscheinlich auch ein neues Licht auf die bewährte Aussage „goto wird als schädlich angesehen“ werfen.

AlexanderBrevig
quelle
3
Ihre Kommentare zur Software RTC gelten nur für die am unachtsamsten implementierten Lösungen. Ein vernünftiger und zuverlässiger Weg, dies zu tun, besteht darin, einen Hardware-Timer zu verwenden, um alle 1 ms (oder 10 ms) einen Interrupt zu erzeugen. In der Serviceroutine haben Sie eine statische Zählervariable, die dann die Anzahl der Interrupts bis zu 1000 (oder 100) zählt. Wenn die volle Zählung erreicht ist, setzen Sie den Zähler zurück und erhöhen Sie dann Ihren Sekundenzähler. Alle 60 Sekunden setzen Sie die Sekundenzählervariable auf Null zurück und erhöhen Ihre Minutenzählervariable. Erweitern Sie dies bei Bedarf auf Monate und Jahre.
Michael Karas