Das Konzept der Zeit im Kontext von RTOS wurde in einem der
vorherigen Artikel zusammen mit der Idee der in RTOS verfügbaren zeitbezogenen Funktionen vorgestellt.

Frühere Artikel in der Reihe: Timer ankreuzen
Alle zeitbezogenen Funktionen werden von einer Hardware-Uhr gesteuert. Dies ist ein einfacher Oszillator, der in regelmäßigen Abständen Interrupt-Anforderungen generiert. Damit Taktnummern für Anwendungsprogramme sinnvoll sind, muss die Frequenz des Generators bekannt sein.
Timer-Interrupt-Behandlung
Vom Hardware-Timer erzeugte Interrupts müssen auf bestimmte Weise im Interrupt-Handler (Interrupt Service Routine, ISR) bedient werden, der alle zeitbezogenen RTOS-Funktionen implementiert. Details des Timer-Interrupt-Handlers in Nucleus SE werden in einem der folgenden Artikel erläutert.
Zeitbezogene Funktionen
Nucleus RTOS und Nucleus SE enthalten mehrere zeitbezogene Mechanismen:
- System Tick Clock (Tick Clock) : Ein einfacher Zähler, der mithilfe eines Timer-Interrupt-Handlers inkrementiert wird. Sowohl Nucleus RTOS als auch Nucleus SE verfügen über einen 32-Bit-Zähler, und Aufgaben verfügen über Mechanismen zum Lesen und Schreiben seines Werts. In Nucleus SE ist ein Zeitgeber optional.
- Anwendungszeitgeber : Sowohl Nucleus RTOS als auch Nucleus SE unterstützen Zeitgeberobjekte. Ihre Verwendung und Implementierung in Nucleus SE wird im nächsten Artikel ausführlicher erläutert.
- Zeitscheibenplanung : In Nucleus RTOS werden Aufgaben mit derselben Priorität mithilfe des Round-Robin-Algorithmus bedient. Sie können jedoch auch Zeitscheiben verwenden. In Nucleus SE ist ein Zeitscheibenplaner optional. Dies wurde in früheren Artikeln ausführlich erörtert (eine allgemeine Ansicht des TS-Schedulers (Zeitscheibe) und des TS in Nucleus SE ).
- Unterbrechen einer Aufgabe (Aufgabenschlaf) : Eine Aufgabe kann sich für einen festgelegten Zeitraum selbst anhalten („einschlafen“). Dieser Mechanismus wurde bereits zuvor ausführlich beschrieben.
- Zeitüberschreitungen bei API-Aufrufen : In Nucleus RTOS und Nucleus SE können Sie bei einigen API-Aufrufen eine Aufgabe anhalten, während Sie darauf warten, dass eine Ressource verfügbar ist. Die Pause kann undefiniert sein, oder im Fall von Nucleus RTOS kann eine optionale Zeitüberschreitungsperiode (Wartezeit) angegeben werden. Nucleus SE unterstützt keine API-Aufrufzeitlimits.
Genauigkeit
Und jetzt lohnt es sich, kurz über die Genauigkeit des System-Timers zu sprechen.
Die Genauigkeit der Zeitfunktionen hängt direkt von der Frequenz des Taktgenerators ab. Wenn beispielsweise alle 10 Millisekunden Impulse eintreffen und die Anwendungsaufgabe eine Verzögerung von 100 Millisekunden benötigt, benötigt sie offensichtlich 10 Impulse. Es ist jedoch nicht bekannt, wann der vorherige Impuls empfangen wurde: Es könnte erst vor fast 10 Millisekunden geschehen sein. Daher kann eine Verzögerung von 100 Millisekunden bis zu 110 Millisekunden dauern.
Ein offensichtlicher Weg, um dieses Problem zu lösen, besteht darin, die Frequenz des Generators zu erhöhen. Wenn Impulse in Intervallen von 1 Millisekunde folgen, dauert eine Verzögerung von 100 Millisekunden niemals mehr als einhundertein Millisekunden. Der Nachteil dieser Lösung besteht darin, dass der Timer-Interrupt-Handler zehnmal mehr Prozessorzeit benötigt, was übermäßig ist. Der Systemdesigner muss ein Gleichgewicht zwischen der erforderlichen Genauigkeit des Timers und der verfügbaren Prozessorleistung finden.
Systemzeiteinstellung
Wie bei den meisten Nucleus SE-Objekten wird die Systemzeiteinstellung größtenteils durch die Direktiven
#define in der Datei
nuse_config.h gesteuert. Der Hauptparameter ist
NUSE_SYSTEM_TIME_SUPPORT , wodurch der Systemzeitunterstützungsmechanismus aktiviert wird. Sie müssen die Anzahl der Objekte nicht angeben: Die Systemzeit ist entweder aktiviert oder nicht.
Die Auswahl eines Werts ungleich Null ist der Hauptaktivator der Systemzeit. Dieser Parameter wird beim Definieren von Datenstrukturen verwendet, auf die später in diesem Artikel näher eingegangen wird. Darüber hinaus aktiviert ein Wert ungleich Null die API-Einstellungen.
API-Aktivierung
Jede API-Funktion (Dienstprogrammaufruf) in Nucleus SE verfügt über eine aktivierende Anweisung #define in der Datei nuse_config.h. Für die Systemzeit sind diese Symbole:
NUSE_CLOCK_SETNUSE_CLOCK_RETRIEVEStandardmäßig sind sie auf
FALSE gesetzt , sodass alle Serviceaufrufe deaktiviert sind und die Aufnahme von Code, der sie implementiert, blockiert wird. Um die Systemzeit in der Anwendung zu konfigurieren, müssen Sie die erforderlichen API-Serviceaufrufe auswählen und auf
TRUE setzen .
Das Folgende ist ein Codeausschnitt aus der Standarddatei nuse_config.h.
#define NUSE_SYSTEM_TIME_SUPPORT FALSE /* */ #define NUSE_CLOCK_SET FALSE /* */ #define NUSE_CLOCK_RETRIEVE FALSE /* */
Wenn Sie versuchen, den Systemzeit-API-Serviceaufruf zu verwenden, während der Systemzeitaktivator deaktiviert ist, tritt ein Kompilierungsfehler auf. Wenn Ihr Code einen API-Aufruf verwendet, der nicht aktiviert wurde, tritt ein Layoutfehler auf, da der Implementierungscode nicht in der Anwendung enthalten war.
System Time Utility-Aufrufe
Nucleus RTOS unterstützt zwei Dienstprogrammaufrufe, die sich auf die Systemzeit beziehen und die folgenden Funktionen bieten:
- Einstellen des Wertes der Systemzeit. Nucleus SE ist in der Funktion NUSE_Clock_Set () implementiert.
- Abrufen des Werts der Systemzeit. Nucleus SE ist in der Funktion NUSE_Clock_Retrieve () implementiert.
Betrachten Sie die Implementierung jedes dieser Aufrufe genauer.
Serviceaufrufe zum Einstellen und Abrufen der Systemzeit
Mit der Systemzeit können Sie nur Vorgänge ausführen, bei denen ein bestimmter Wert festgelegt und der aktuelle Wert abgerufen wird. Nucleus RTOS und Nucleus SE bieten zwei grundlegende API-Aufrufe zur Implementierung dieser Vorgänge.
Die Interpretation des Systemzeitwerts hängt von der Anwendung ab, da es sich im Wesentlichen um einen Zähler der Anzahl von "Taktzyklen" handelt, die seit dem letzten Zurücksetzen des Zählers aufgetreten sind. Um diese Informationen nutzen zu können, muss die Frequenz des Generators bekannt sein.
Zeiteinstellung
Jede Aufgabe kann die Systemzeit durch Aufrufen dieser API-Funktion festlegen.
Rufen Sie auf, um die Systemzeit in Nucleus RTOS einzustellenPrototyp eines Serviceabrufs:
VOID NU_Set_Clock (UNSIGNED new_value);Parameter:
new_value - Wert, der der Systemzeit zugewiesen werden soll
Rückgabewert: keine.
Rufen Sie auf, um die Systemzeit in Nucleus SE einzustellenDieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.
Prototyp eines Serviceabrufs:
void NUSE_Clock_Set (U32 new_value);Parameter:
new_value - Wert, der der Systemzeit zugewiesen werden soll
Rückgabewert: keine
Implementierung der Zeiteinstellung in Nucleus SEDer Code ist sehr einfach. Der angegebene Wert wird im kritischen Abschnitt in
NUSE_Tick_Clock geschrieben.
Systemzeit abrufen
Eine Task kann mithilfe dieser API-Funktion den Systemzeitwert ermitteln.
Rufen Sie an, um die Systemzeit in Nucleus RTOS abzurufenPrototyp eines Serviceabrufs:
UNSIGNED NU_Retrieve_Clock (VOID);Parameter: Keine
Rückgabewert: aktueller Wert der Systemzeit
Aufruf, um die Systemzeit in Nucleus SE abzurufenPrototyp eines Serviceabrufs:
U32 NUSE_Clock_Retrieve (void);Parameter: Keine
Rückgabewert: aktueller Wert der Systemzeit
Implementierung der Zeiterfassung in Nucleus SEDer Code ist sehr einfach. Die Funktion gibt den im kritischen Abschnitt erhaltenen
NUSE_Tick_Clock- Wert zurück.
Datenstrukturen
Die Systemzeit verwendet eine Datenstruktur (im RAM), bei der es sich um ein 32-Bit-Wort handelt.
Ich empfehle dringend, dass der Anwendungscode keinen direkten Zugriff auf diese Datenstruktur verwendet, sondern über die bereitgestellten API-Funktionen darauf zugreift. Dies vermeidet Inkompatibilität mit zukünftigen Versionen von Nucleus SE und unerwünschte Nebenwirkungen und vereinfacht die Portierung von Anwendungen auf Nucleus RTOS. Im Folgenden werden Details zu Datenstrukturen bereitgestellt, um das Verständnis des Serviceabrufcodes und des Debuggens zu vereinfachen.
RAM-Daten
Datenstruktur:
NUSE_Tick_Clock - eine Variable vom Typ
U32 , die den
Uhrzähler der
Systemzeit speichert.
Diese Datenstruktur wird von der Funktion
NUSE_Init_Task () beim Start von Nucleus SE auf Null initialisiert. Einer der folgenden Artikel enthält eine vollständige Beschreibung der Nucleus SE-Startverfahren.
ROM-Daten
Es sind keine Datenstrukturen mit der Systemzeit im ROM verknüpft.
Die Speichermenge für die Systemzeit
Wie bei allen anderen Nucleus SE-Objekten ist die für die Systemzeit erforderliche Speichermenge vorhersehbar.
Die Speichermenge im ROM beträgt 0.
Die Speichermenge im RAM (in Bytes) beträgt immer 4.
Nicht realisierte API-Aufrufe
Alle Systemzeit-Nucleus RTOS-API-Serviceaufrufe haben in Nucleus SE ein Äquivalent.
Kompatibel mit Nucleus PLUS
Wie bei allen anderen Nucleus SE-Objekten war es mein Ziel sicherzustellen, dass der Anwendungscode so kompatibel wie möglich mit Nucleus RTOS ist. Die Systemzeit ist keine Ausnahme und wird aus Anwendersicht ähnlich wie in Nucleus RTOS implementiert. Nucleus RTOS API-Aufrufe können direkt auf Nucleus SE portiert werden.
Im folgenden Artikel werden wir Software-Timer betrachten.