Die ganze Wahrheit über RTOS. Artikel 11. Aufgaben: Konfiguration und Einführung in die API



Das Konzept eines Problems wurde in früheren Artikeln vorgestellt. Tatsächlich ist eine Aufgabe einfach eine Reihe von Werten, die in Prozessorregister geladen werden können (damit die Aufgabe ausgeführt werden kann) oder in einem Zustand gespeichert werden können, der für die zukünftige kontextbezogene Umschaltung auf die Aufgabe bereit ist. Meistens hat eine Aufgabe einen eigenen Stapel.

Bei Verwendung des RTC-Schedulers (Run to Completion) wird die Kontextumschaltung natürlich nicht verwendet, und die Aufgabe kann nur als Wert des Programmzählers (Code-Einstiegspunkt) betrachtet werden.

Die Definition der Aufgabe enthält nicht den Code selbst. Die Task sollte den Code ausführen, gehört aber nicht dazu. Aufgaben können gemeinsame Funktionen haben. Darüber hinaus kann der gesamte Code für mehrere Aufgaben gemeinsam genutzt werden. Allgemeiner Code sollte fast immer gemäß den Wiedereintrittsanforderungen geschrieben werden. Die meisten Compiler können mit diesem Code problemlos umgehen, müssen jedoch bei Bibliotheksfunktionen vorsichtig sein, da sie möglicherweise nicht für Multitasking-Anwendungen geeignet sind.

Eine solche Definition schreibt bestimmte Regeln vor, die beim Entwickeln der in diesem Artikel beschriebenen Datenstrukturen von Aufgaben und API-Funktionen befolgt werden sollten. Ich werde die Konfiguration von Aufgaben in Nucleus SE überprüfen und einen detaillierten Überblick über Serviceaufrufe (API-Aufrufe) erhalten, die für Aufgaben in Nucleus SE und Nucleus RTOS gelten.

Frühere Artikel in der Reihe:
Artikel 10. Scheduler: Erweiterte Funktionen und Kontexterhaltung
Artikel 9. Scheduler: Implementierung
Artikel 8. Nucleus SE: Internes Design und Bereitstellung
Artikel 7. Nucleus SE: Einführung
Artikel 6. Andere RTOS-Dienste
Artikel 5. Aufgabeninteraktion und Synchronisation
Artikel 4. Aufgaben, Kontextwechsel und Interrupts
Artikel 3. Aufgaben und Planung
Artikel 2. RTOS: Struktur und Echtzeitmodus
Artikel 1. RTOS: Einführung.

Aufgabenkonfiguration


Anzahl der Aufgaben


In Nucleus SE wird die Aufgabenkonfiguration hauptsächlich von den Direktiven #define in nuse_config.h gesteuert . Der Schlüsselparameter NUSE_TASK_NUMBER bestimmt die Anzahl der Aufgaben, die in der Anwendung konfiguriert werden können. Der Standardwert ist 1 (d. H. Eine Aufgabe während der Ausführung) und der Maximalwert des Parameters ist 16. Ein falscher Wert führt zu einem Kompilierungsfehler, der durch Einchecken von nuse_config_chech.h generiert wird (dies ist in nuse_config.c enthalten , was bedeutet kompiliert mit diesem Modul), wird die # Fehler- Direktive ausgelöst . Dieser Parameter wird verwendet, um Datenstrukturen zu bestimmen, deren Größe von ihrem Wert abhängt.

In Nucleus SE ist es außer bei Verwendung des RTC-Schedulers wichtig, dass immer mindestens eine Aufgabe zur Ausführung bereit ist. Wenn Sie den Prioritätsplaner verwenden, müssen Sie sicherstellen, dass die Aufgabe mit der niedrigsten Priorität niemals angehalten wird. Eine solche Aufgabe sollte als "Hintergrundaufgabe" betrachtet werden.

Im Gegensatz zu einigen anderen Echtzeitkernen verwendet Nucleus SE keine "Systemaufgaben". Dies bedeutet, dass alle 16 Aufgaben für den Benutzeranwendungscode oder die Middleware verfügbar sind.

API-Parameter


Jede API-Funktion (Dienstprogrammaufruf) in Nucleus SE wird durch die Direktive #define in nuse_config.h aktiviert. Für Aufgaben sind diese Parameter:

  • NUSE_TASK_SUSPEND
  • NUSE_TASK_RESUME
  • NUSE_TASK_SLEEP
  • NUSE_TASK_RELINQUISH
  • NUSE_TASK_CURRENT
  • NUSE_TASK_CHECK_STACK
  • NUSE_TASK_RESET
  • NUSE_TASK_INFORMATION
  • NUSE_TASK_COUNT

Standardmäßig sind alle oben genannten Parameter auf FALSE gesetzt , wodurch jeder Serviceabruf deaktiviert und die Aufnahme von Code verhindert wird, der sie implementiert. Um Aufgaben für die Anwendung zu konfigurieren, müssen Sie die erforderlichen API-Aufrufe auswählen und die entsprechenden Zeichen auf TRUE setzen .

Das Folgende ist ein Ausschnitt aus der Standarddatei nuse_config.h .



Wenn Ihr Code einen API-Aufruf verwendet, der nicht aktiviert wurde, wird beim Verknüpfen ein Fehler angezeigt, da der Implementierungscode nicht in der Anwendung enthalten war.

Funktionsparameter


Nucleus SE kann einige Aufgabenfunktionen hinzufügen. Die erforderlichen Parameter befinden sich wiederum in der Datei nuse_config.h :

Mit NUSE_SUSPEND_ENABLE können Sie Aufgaben anhalten . Wenn diese Option nicht ausgewählt ist, warten alle Aufgaben ständig auf die Planung. Die Aktivierung dieses Parameters ist erforderlich, wenn der Prioritätsplaner verwendet wird.

Mit NUSE_BLOCKING_ENABLE können Sie Aufgaben für mehrere Funktions-API-Aufrufe anhalten . Wenn diese Option aktiviert ist, muss auch NUSE_SUSPEND_ENABLE aktiviert sein.

Mit NUSE_INITIAL_TASK_STATE_SUPPORT können Sie den Anfangszustand der Aufgabe festlegen. Wenn diese Option nicht ausgewählt ist, werden alle Aufgaben unmittelbar nach der Erstellung zum Scheduler hinzugefügt.

Utility-Task-Aufrufe


Nucleus RTOS unterstützt 16 Service Calls (APIs) für die Arbeit mit Aufgaben, die die folgenden Funktionen bieten:

FunktionsbeschreibungNucleus RTOSNucleus SE
Unterbrechen Sie eine AufgabeNU_Suspend_Task ()NUSE_Task_Suspend ()
Aufgabe fortsetzenNU_Resume_Task ()NUSE_Task_Resume ()
Unterbrechen Sie eine Aufgabe für eine bestimmte
die Periode
NU_Sleep ()NUSE_Task_Sleep ()
CPU-SteuerungsfreigabeNU_Relinquish ()NUSE_Task_Relinquish ()
Abrufen der ID der aktuellen AufgabeNU_Current_Task_Pointer ()NUSE_Task_Current ()
Überprüfen der verfügbaren StapelgrößeNU_Check_Stack ()NUSE_Task_Check_Stack ()
Aufgabe auf unbenutzt zurücksetzen
Zustand (zurücksetzen)
NU_Reset_Task ()NUSE_Task_Reset ()
Bereitstellung von Informationen zu einer bestimmten AufgabeNU_Task_Information ()NUSE_Task_Information ()
Konfigurierter Zähler
Aufgaben (im Moment) in der Anwendung
NU_Established_Tasks ()NUSE_Task_Count ()
Hinzufügen einer neuen Aufgabe zur Anwendung (Erstellung)NU_Create_Task ()Nicht implementiert.
Entfernen einer Aufgabe aus der AnwendungNU_Delete_Task ()Nicht implementiert.
Zeiger auf alle Aufgaben zurückgeben
im Anhang
NU_Task_Pointers ()Nicht implementiert.
Extrusionsalgorithmus ändernNU_Change_Preemption ()Nicht implementiert.
Ändern Sie die AufgabenprioritätNU_Change_Priority ()Nicht implementiert.
Ändern Sie das Zeitquantum einer AufgabeNU_Change_Time_Slice ()Nicht implementiert.
AufgabenerfüllungNU_Terminate_Task ()Nicht implementiert.

Die Implementierung jedes der oben genannten Serviceaufrufe wird nachstehend sowie in den folgenden Artikeln zu RTOS ausführlich erläutert.

Aufgabenverwaltungsdienste


Grundlegende Vorgänge mit Aufgaben: Halten Sie eine Aufgabe auf unbestimmte Zeit an, setzen Sie sie fort, halten Sie eine Aufgabe für eine bestimmte Zeit an, geben Sie den Prozessor frei. Nucleus RTOS und Nucleus SE bieten vier grundlegende API-Aufrufe, um diese Operationen auszuführen, die ich unten beschreiben werde.

Unterbrechen Sie eine Aufgabe


Nucleus PLUS bietet einen einfachen API-Aufruf, mit dem Sie eine bestimmte Aufgabe auf unbestimmte Zeit anhalten können. Nucleus SE hat einen Büroanruf mit ähnlicher Funktionalität.

Unterbrechen Sie eine Aufgabe in Nucleus RTOS
Prototyp eines Serviceabrufs:
STATUS NU_Suspend_Task (NU_TASK * -Aufgabe);

Parameter:
task - Ein Zeiger auf die Steuereinheit der angehaltenen Task (die möglicherweise aktuell ist und deren ID mit NU_Current_Task_Pointer () abgerufen werden kann , mehr im nächsten Artikel).

Rückgabewert:
NU_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NU_INVALID_TASK - ungültiger Zeiger auf die Aufgabe;
NU_INVALID_SUSPEND - Die angegebene Aufgabe hat den Status NU_FINISHED oder NU_TERMINATED .

Pause der Herausforderungsaufgabe in Nucleus SE
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus PLUS-API.

Prototyp eines Serviceabrufs:
STATUS NUSE_Task_Suspend (NUSE_TASK-Task);

Parameter:
task - Der Index (ID) der angehaltenen Task (der aktuell sein kann und dessen ID mit NUSE_Task_Current () abgerufen werden kann - mehr im nächsten Artikel).

Rückgabewert:
NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_TASK - ungültiger Aufgabenindex.

Implementieren Sie die Unterbrechung einer Aufgabe in Nucleus SE
Die Hauptfunktionalität der API-Funktion ist recht einfach:



Tatsächlich wird in dieser Implementierung die Scheduler-Funktion NUSE_Suspend_Task () mit dem Parameter "Unbedingter Stopp" ( NUSE_PURE_SUSPEND ) aufgerufen . Diese Funktion ruft den Scheduler auf, wenn die angehaltene Aufgabe ausgeführt wird.

Aufgabe fortsetzen


Nucleus RTOS bietet einen einfachen API-Aufruf, mit dem Sie eine Aufgabe fortsetzen können, die zuvor auf unbestimmte Zeit angehalten wurde. Nucleus SE hat einen Büroanruf mit ähnlicher Funktionalität.

Herausforderung Wiederaufnahme Aufgabe in Nucleus RTOS
Prototyp eines Serviceabrufs:
STATUS NU_Resume_Task (NU_TASK * Aufgabe);

Parameter:
task - ein Zeiger auf die Steuereinheit der erneuerten Task.

Rückgabewert:
NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_TASK - ungültiger Zeiger auf die Aufgabe;
NUSE_INVALID_RESUME - Die Aufgabe wurde nicht unbedingt angehalten.

Fordern Sie die Aufgaben in Nucleus SE wieder auf
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.

Prototyp eines Serviceabrufs:
STATUS NUSE_Task_Resume (NUSE_TASK-Task);

Parameter:
Task - Index (ID) der erneuerten Task.

Rückgabewert:
NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_TASK - ungültiger Aufgabenindex;
NUSE_INVALID_RESUME - Die Aufgabe wurde nicht unbedingt angehalten.

Implementieren von Lebenslaufaufgaben in Nucleus SE
Die Hauptfunktionalität der API-Funktion ist recht einfach:



Tatsächlich wird in dieser Implementierung die Scheduler-Funktion NUSE_Wake_Task () aufgerufen. Diese Funktion ruft den Scheduler auf, wenn der Prioritätsplaner verwendet wird und die erneuerte Aufgabe eine höhere Priorität als die aktuelle Aufgabe hat.

Anhalten einer Aufgabe für einen bestimmten Zeitraum


Nucleus RTOS bietet einen einfachen API-Aufruf, um die aktuelle Aufgabe für einen bestimmten Zeitraum anzuhalten. Nucleus SE hat einen Büroanruf mit ähnlicher Funktionalität.

Rufen Sie Suspend-Tasks für einen bestimmten Zeitraum auf. Nucleus RTOS
Prototyp eines Serviceabrufs:
VOID NU_Sleep (UNSIGNED Ticks);

Parameter:
Ticks - Zeitraum, für den die Aufgabe angehalten werden soll (in Echtzeit- Ticks ).

Rückgabewert:
Nein.

Fordern Sie eine Aufgabenpause für einen bestimmten Zeitraum heraus. Nucleus SE
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.

Prototyp eines Serviceabrufs:
void NUSE_Task_Sleep (U16-Ticks);

Parameter:
Ticks - Zeitraum, für den die Aufgabe angehalten werden soll (in Echtzeit- Ticks ).

Rückgabewert:
Nein.

Implementieren einer Unterbrechung einer Aufgabe für einen bestimmten Zeitraum in Nucleus SE
Die Hauptfunktionalität der API-Funktion ist recht einfach:



Dieser Code lädt den Verzögerungswert in den aktuellen Taskparameter in NUSE_Task_Timeout_Counter [] . Danach wird die Aufgabe mit NUSE_Suspend_Task () mit dem Suspendierungszeitraum ( NUSE_SLEEP_SUSPEND ) angehalten .

Der Timeout-Wert wird vom Echtzeit-Clock-Interrupt-Handler verwendet. Der Code wird unten gezeigt und in einem zukünftigen Artikel ausführlicher behandelt.



CPU-Freigabe


Nucleus PLUS bietet einen einfachen API-Aufruf, mit dem die Prozessorsteuerung auf alle ausführbaren Aufgaben mit derselben Priorität basierend auf dem Round Robin-Algorithmus übertragen werden kann. Nucleus SE hat einen Büroanruf mit sehr ähnlichen Funktionen. Es kann jedoch nicht mit dem Prioritätsplaner verwendet werden, da mehrere Aufgaben mit derselben Priorität nicht unterstützt werden. Der Versuch, diesen API-Aufruf mit dem Prioritätsplaner zu verwenden, führt zu einem Fehler. Ein Dienstprogrammaufruf funktioniert mit den Schedulern Round Robin und Time Slice. Mit dem Scheduler Run To Completion ist dieser API-Aufruf ineffizient.

Aufruf zur Freigabe des Nucleus RTOS-Prozessors
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus PLUS-API.

Prototyp eines Serviceabrufs:
VOID NU_Relinquish (VOID);

Parameter:
Sind abwesend.

Rückgabewert:
Nein.

Aufruf zur Freigabe des Nucleus SE-Prozessors
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus PLUS-API.

Prototyp eines Serviceabrufs:
void NUSE_Task_Relinquish (void);

Parameter:
Sind abwesend.

Rückgabewert:
Nein.

Implementierung der Nucleus SE-Prozessorfreigabe
Die Hauptfunktionalität der API-Funktion:



Im Wesentlichen ruft diese Implementierung die Scheduler-Funktion NUSE_Reschedule () auf . Diese Funktion weist den Scheduler einfach an, die nächste Aufgabe abzuschließen.

In den nächsten beiden Artikeln werden weiterhin aufgabenbezogene RTOS-Dienstprogrammaufrufe anhand der Beispiele für Nucleus RTOS und Nucleus SE behandelt.

Über den Autor: Colin Walls ist seit über dreißig Jahren in der Elektronikindustrie tätig und widmet sich die meiste Zeit der Firmware. Heute ist er Firmware-Ingenieur bei Mentor Embedded (einer Abteilung von Mentor Graphics). Colin Walls spricht häufig auf Konferenzen und Seminaren, Autor zahlreicher technischer Artikel und zweier Bücher über Firmware. Lebt in Großbritannien. Colins professioneller Blog , E-Mail: colin_walls@mentor.com.

Über die Übersetzung: Diese Artikelserie schien insofern interessant zu sein, als der Autor trotz der an einigen Stellen veralteten beschriebenen Ansätze den schlecht ausgebildeten Leser in die Funktionen des Echtzeit-Betriebssystems einführt. Ich selbst gehöre zu dem Team von Entwicklern des russischen RTOS , das wir kostenlos machen wollen , und ich hoffe, dass der Zyklus für unerfahrene Entwickler nützlich sein wird.

Source: https://habr.com/ru/post/de424481/


All Articles