Die ganze Wahrheit über RTOS. Artikel 23. Warteschlangen: Einführung und Grundversorgung



Warteschlangen wurden in einem der vorherigen Artikel (Nr. 5) erwähnt. Sie bieten eine flexiblere Möglichkeit, einfache Nachrichten zwischen Aufgaben zu übertragen als Postfächer.

Frühere Artikel in der Reihe:
Artikel 22. Postfächer: Nebendienstleistungen und Datenstrukturen
Artikel 21. Postfächer: Einführung und Basisdienste
Artikel Nr. 20. Semaphoren: Nebendienstleistungen und Datenstrukturen
Artikel Nr. 19. Semaphoren: Einführung und Grundversorgung
Artikel Nr. 18. Ereignisflag-Gruppen: Hilfsdienste und Datenstrukturen
Artikel Nr. 17. Ereignisflag-Gruppen: Einführung und Basisdienste
Artikel 16. Signale
Artikel Nr. 15. Speicherpartitionen: Dienste und Datenstrukturen
Artikel # 14. Speicherbereiche: Einführung und Grundversorgung
Artikel Nr. 13. Aufgabendatenstrukturen und nicht unterstützte API-Aufrufe
Artikel 12. Dienstleistungen für die Arbeit mit Aufgaben
Artikel 11. Aufgaben: Konfiguration und Einführung in die API
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.

Warteschlangen verwenden


In Nucleus SE werden Warteschlangen während der Erstellungsphase definiert. Eine Anwendung kann bis zu 16 Warteschlangen haben. Wenn die Anwendung keine Warteschlangen enthält, sind weder Datenstrukturen noch Dienstcode in Bezug auf Warteschlangen in der Anwendung enthalten.

Eine Warteschlange ist eine Reihe von Bereichen im Speicher, die groß genug für ein Element vom Typ ADDR sind und auf die sicher zugegriffen werden kann, damit mehrere Aufgaben sie verwenden können. Aufgaben können Daten in die Warteschlange schreiben, bis alle Bereiche voll sind. Aufgaben können Daten aus der Warteschlange lesen, wobei Daten normalerweise auf FIFO-Basis (First-in-First-Out) eingehen. Der Versuch, Daten in eine überfüllte Warteschlange zu schreiben oder Daten aus einer leeren Warteschlange zu lesen, kann abhängig von den ausgewählten API-Aufrufparametern und der Nucleus SE-Konfiguration zu einem Fehler oder einer Aufgabenpause führen.

Warteschlangen und Datenverbindungen


Nucleus SE unterstützt Datenkanäle, die ebenfalls in einem früheren Artikel (Nr. 5) erwähnt wurden und in einem der folgenden Punkte ausführlich erläutert werden. Der Hauptunterschied zwischen Warteschlangen und Kanälen ist die Größe der Nachricht. Warteschlangen enthalten Nachrichten, die aus einer einzelnen Variablen vom Typ ADDR bestehen (normalerweise Zeiger). Der Kanal enthält Nachrichten beliebiger Größe, die für jeden Kanal in der Anwendung individuell sind und bei den Parametereinstellungen zugewiesen werden.

Warteschlangeneinstellung


Anzahl der Warteschlangen


Wie bei den meisten Nucleus SE-Objekten wird die Warteschlangenkonfiguration hauptsächlich durch die Direktiven #define in der Datei nuse_config.h gesteuert. Der Hauptparameter ist NUSE_QUEUE_NUMBER , der die Anzahl der in der Anwendung konfigurierten Warteschlangen bestimmt. Der Standardwert ist Null ( dh es gibt keine Warteschlangen in der Anwendung) und kann Werte bis 16 annehmen. Ein falscher Wert führt zu einem Fehler beim Kompilieren, der während der Überprüfung in der Datei nuse_config_check.h generiert wird (er ist in der Datei nuse_config.c enthalten und kompiliert zusammen mit ihm), wodurch die Direktive #error ausgelöst wird .

Die Auswahl eines Werts ungleich Null dient als Hauptaktivator für die Warteschlangen. Dieser Parameter wird beim Definieren von Datenstrukturen verwendet und ihre Größe hängt von ihrem Wert ab (mehr dazu im nächsten Artikel). Darüber hinaus aktiviert ein Wert ungleich Null die API-Einstellungen.

API-Aufrufe aktivieren


Jede API-Funktion (Dienstprogrammaufruf) in Nucleus SE verfügt über die Direktive #define enable in nuse_config.h . Für Warteschlangen sind diese Anweisungen:

NUSE_QUEUE_SEND NUSE_QUEUE_RECEIVE NUSE_QUEUE_JAM NUSE_QUEUE_RESET NUSE_QUEUE_INFORMATION NUSE_QUEUE_COUNT 

Standardmäßig sind sie auf FALSE gesetzt , wodurch alle Serviceaufrufe deaktiviert und die Aufnahme von Code blockiert werden, der sie implementiert. Um die Warteschlangen in der Anwendung zu konfigurieren, müssen Sie die erforderlichen API-Aufrufe auswählen und auf TRUE setzen .

Das Folgende ist ein Codeausschnitt aus der Datei nuse_config.h :

 #define NUSE_QUEUE_NUMBER 0 /* Number of queues in the system - 0-16 */ /* Service call enablers */ #define NUSE_QUEUE_SEND FALSE #define NUSE_QUEUE_RECEIVE FALSE #define NUSE_QUEUE_JAM FALSE #define NUSE_QUEUE_RESET FALSE #define NUSE_QUEUE_INFORMATION FALSE #define NUSE_QUEUE_COUNT FALSE 

Wenn die Funktionen der Warteschlangen-API aktiviert sind, die Anwendung jedoch keine Warteschlangen enthält (mit Ausnahme von NUSE_Queue_Count () , das immer aktiviert ist), wird ein Kompilierungsfehler angezeigt . Wenn Ihr Code einen API-Aufruf verwendet, der nicht aktiviert wurde, führt dies zu einem Layoutfehler, da der Implementierungscode nicht in der Anwendung enthalten war.

Anrufwarteschlange


Nucleus RTOS unterstützt zehn Warteschlangendienstaufrufe mit den folgenden Funktionen:

  • Eine Nachricht in die Warteschlange stellen. Nucleus SE ist in der Funktion NUSE_Queue_Send () implementiert.
  • Akzeptieren einer Nachricht aus der Warteschlange. Nucleus SE implementiert die Funktion NUSE_Queue_Receive () .
  • Posting an den Kopf der Warteschlange. In Nucleus SE, implementiert in NUSE_Queue_Jam () .
  • Wiederherstellen eines nicht verwendeten Status der Warteschlange mit Freigabe aller angehaltenen Aufgaben (Zurücksetzen). Nucleus SE ist in NUSE_Queue_Reset () implementiert.
  • Bereitstellung von Informationen zu einer bestimmten Warteschlange. Nucleus SE in NUSE_Queue_Information () implementiert.
  • Gibt die Anzahl der aktuell in der Anwendung konfigurierten Warteschlangen zurück. In Nucleus SE, implementiert in NUSE_Queue_Count () .
  • Hinzufügen einer neuen Warteschlange zur Anwendung (Erstellen einer Warteschlange). Nucleus SE ist nicht implementiert.
  • Entfernen einer Warteschlange aus einer Anwendung. Nucleus SE ist nicht implementiert.
  • Geben Sie Zeiger auf alle Warteschlangen in der Anwendung zurück. Nucleus SE ist nicht implementiert.
  • Senden einer Nachricht an alle in der Warteschlange angehaltenen Aufgaben (Broadcast). Nucleus SE ist nicht implementiert.

Die Implementierung jedes dieser Overhead-Aufrufe wird nachstehend ausführlich beschrieben.

Service ruft zum Schreiben und Lesen aus Warteschlangen auf


Die grundlegenden Operationen, die an den Warteschlangen ausgeführt werden, sind Schreiben (was manchmal als Warteschlangennachrichten bezeichnet wird) und Lesen (auch als Empfangen von Nachrichten bezeichnet). Es ist auch möglich, an den Anfang der Warteschlange zu schreiben (Jamming). Nucleus RTOS und Nucleus SE bieten drei grundlegende API-Aufrufe für diese Operationen, die nachfolgend erläutert werden.

Anstehen


Der Aufruf des Nucleus RTOS API-Dienstprogramms zum Schreiben in die Warteschlange ist sehr flexibel und ermöglicht es Ihnen, die Aufgabe implizit oder mit einem bestimmten Zeitlimit anzuhalten, wenn der Vorgang nicht sofort abgeschlossen werden kann (z. B. beim Versuch, in eine vollständige Warteschlange zu schreiben). Nucleus SE bietet dieselben Funktionen, die Unterbrechung der Aufgabe ist jedoch optional und eine Zeitüberschreitung ist nicht implementiert.

Anrufwarteschlange in Nucleus RTOS

Prototyp eines Serviceabrufs:

STATUS NU_Send_To_Queue (NU_QUEUE * Warteschlange, VOID * Nachricht, UNSIGNED Größe, UNSIGNED Suspend);

Parameter:

Warteschlange - ein Zeiger auf den vom Benutzer bereitgestellten Warteschlangensteuerblock;
message - Zeiger auf die zu sendende Nachricht;
Größe - Die Anzahl der nicht signierten Datenelemente in der Nachricht. Wenn die Warteschlange Nachrichten mit variabler Länge unterstützt, muss dieser Parameter der Größe der Nachricht entsprechen oder kleiner als die von der Warteschlange unterstützte Nachrichtengröße sein. Wenn die Warteschlange Nachrichten mit fester Größe unterstützt, muss dieser Parameter genau mit der von der Warteschlange unterstützten Nachrichtengröße übereinstimmen.
suspend - Die Angabe der Suspendierung der Aufgabe kann die Werte NU_NO_SUSPEND oder NU_SUSPEND oder einen Timeout-Wert annehmen .

Rückgabewert:

NU_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Warteschlangenzeiger;
NU_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NU_INVALID_SIZE - Die Nachrichtengröße ist nicht mit der von der Warteschlange unterstützten Nachrichtengröße kompatibel.
NU_INVALID_SUSPEND - Die Suspendierung wurde von einem nicht aufgabenbezogenen Thread durchgeführt.
NU_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NU_TIMEOUT - Die Warteschlange ist auch dann voll, wenn die Aufgabe für das angegebene Zeitlimit angehalten wurde.
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während die Aufgabe angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Einreihen einer Nachricht in Nucleus SE
Dieser API-Serviceaufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.

Prototyp eines Serviceabrufs:

STATUS NUSE_Queue_Send (NUSE_QUEUE-Warteschlange, ADDR * -Nachricht, U8-Suspend);

Parameter:

Warteschlange - Warteschlangenindex (ID);
message - ein Zeiger auf die zu sendende Nachricht; es ist eine Variable vom Typ ADDR ;
suspend - Spezifikation zum Anhalten von Aufgaben, kann die Werte NUSE_NO_SUSPEND oder NUSE_SUSPEND annehmen .

Rückgabewert:

NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NUSE_INVALID_SUSPEND - Versuch, eine Aufgabe von einem Thread anzuhalten, der nicht mit der Aufgabe verknüpft ist, oder wenn API-Dienstaufrufe deaktiviert sind, um Aufgaben zu blockieren.
NUSE_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NUSE_QUEUE_WAS_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Implementieren Sie Queuing in Nucleus SE
Die API-Funktionscodevariante NUSE_Queue_Send () (nach Überprüfung der Parameter) wird mithilfe der bedingten Kompilierung ausgewählt, je nachdem, ob die Unterstützung für das Sperren von Aufgaben aktiviert ist oder nicht. Wir werden beide Optionen prüfen.

Wenn die Task-Sperre nicht aktiviert ist, ist der Code für diesen Serviceabruf ziemlich einfach:

 if (NUSE_Queue_Items[queue] == NUSE_Queue_Size[queue]) /* queue full */ { return_value = NUSE_QUEUE_FULL; } else /* queue element available */ { NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] = *message; if (NUSE_Queue_Head[queue] == NUSE_Queue_Size[queue]) { NUSE_Queue_Head[queue] = 0; } NUSE_Queue_Items[queue]++; return_value = NUSE_SUCCESS; } 

Die Funktion prüft einfach, ob in der Warteschlange freier Speicherplatz vorhanden ist, und speichert die Nachricht mithilfe des NUSE_Queue_Head [] -Index im Datenbereich der Warteschlange.

Wenn die Task-Sperre aktiviert ist, wird der Code komplexer:

 do { if (NUSE_Queue_Items[queue] == NUSE_Queue_Size[queue]) /* queue full */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_QUEUE_FULL; } else { /* block task */ NUSE_Queue_Blocking_Count[queue]++; NUSE_Suspend_Task(NUSE_Task_Active, (queue << 4) | NUSE_QUEUE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else { /* queue element available */ NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] = *message; if (NUSE_Queue_Head[queue] == NUSE_Queue_Size[queue]) { NUSE_Queue_Head[queue] = 0; } NUSE_Queue_Items[queue]++; if (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; /* check whether a task is blocked on this queue */ NUSE_Queue_Blocking_Count[queue]--; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } } while (suspend == NUSE_SUSPEND); 

Einige Erläuterungen können hilfreich sein.

Der Code ist in einer do ... while-Schleife eingeschlossen , die ausgeführt wird, während der Parameter für die Taskpause NUSE_SUSPEND lautet .

Wenn die Warteschlange voll ist und suspend NUSE_NO_SUSPEND ist , endet der API-Aufruf mit NUSE_QUEUE_FULL . Wenn der Suspend-Parameter NUSE_SUSPEND lautet , wird die Task angehalten . Nach Abschluss ( dh wenn die Aufgabe fortgesetzt wird), wenn der Rückgabewert NUSE_SUCCESS lautet, dh die Aufgabe wurde fortgesetzt, weil die Nachricht gelesen wurde (und nicht, weil die Warteschlange zurückgesetzt wurde), kehrt der Code zum Anfang der Schleife zurück.
Wenn die Warteschlange nicht voll ist, wird die bereitgestellte Nachricht mithilfe des Index NUSE_Queue_Head [] im Datenbereich der Warteschlange gespeichert. Es wird überprüft, ob sich angehaltene Aufgaben (wartende Nachrichten) in der Warteschlange befinden. Wenn es solche Aufgaben gibt, wird die erste von ihnen fortgesetzt. Die Suspend-Variable wird auf NUSE_NO_SUSPEND gesetzt , und der API-Aufruf wird mit dem Wert NUSE_SUCCESS abgeschlossen .

Lesen aus der Warteschlange


Der Aufruf des Nucleus RTOS API-Dienstprogramms zum Lesen aus der Warteschlange ist sehr flexibel und ermöglicht es Ihnen, Aufgaben implizit oder mit einem bestimmten Zeitlimit anzuhalten, wenn der Vorgang nicht sofort abgeschlossen werden kann (z. B. beim Versuch, aus einer leeren Warteschlange zu lesen). Nucleus SE bietet die gleiche Funktionalität, aber die Unterbrechung der Aufgabe ist optional und eine Zeitüberschreitung ist nicht implementiert.

Rufen Sie an, um Nachrichten aus der Warteschlange in Nucleus RTOS zu empfangen
Prototyp eines Serviceabrufs:

STATUS NU_Receive_From_Queue (NU_QUEUE * Warteschlange, VOID * -Nachricht, UNSIGNED-Größe, UNSIGNED * actual_size, UNSIGNED suspend);

Parameter:

Warteschlange - ein Zeiger auf den vom Benutzer bereitgestellten Warteschlangensteuerblock;
Nachricht - ein Zeiger auf den Speicher für empfangene Nachrichten;
Größe - Die Anzahl der nicht signierten Datenelemente in der Nachricht. Diese Nummer sollte mit der Nachrichtengröße übereinstimmen, die beim Erstellen der Warteschlange definiert wurde.
suspend - Die Angabe der Suspendierung der Aufgabe kann die Werte NU_NO_SUSPEND oder NU_SUSPEND oder einen Timeout-Wert annehmen .

Rückgabewert:

NU_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Warteschlangenzeiger;
NU_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NU_INVALID_SUSPEND - Versuch, eine Aufgabe von einem Thread anzuhalten , der nicht mit der Aufgabe zusammenhängt;
NU_QUEUE_EMPTY - Die Warteschlange ist leer und die Aussetzung wurde nicht angegeben.
NU_TIMEOUT - Gibt an, dass die Warteschlange auch nach dem Anhalten der Aufgabe für einen bestimmten Zeitraum noch leer ist.
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während die Aufgabe angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Rufen Sie an, um Nachrichten von der Nucleus SE-Warteschlange zu empfangen
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.

Prototyp eines Serviceabrufs:

STATUS NUSE_Queue_Receive (NUSE_QUEUE-Warteschlange, ADDR * -Nachricht, U8-Suspend);

Parameter:

Warteschlange - Warteschlangenindex (ID);
message - ein Zeiger auf das Repository für empfangene Nachrichten; es ist eine Variable vom Typ ADDR ;
suspend - Die Angabe der Suspendierung der Aufgabe kann die Werte NUSE_NO_SUSPEND oder NUSE_SUSPEND annehmen .

Rückgabewert:

NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NUSE_INVALID_SUSPEND - ein Versuch, eine Aufgabe in einem Thread anzuhalten, der nicht mit der Aufgabe verknüpft ist oder dessen Unterstützung für das Blockieren von Aufgaben deaktiviert ist;
NUSE_QUEUE_EMPTY - Die Warteschlange ist leer und die Aussetzung wurde nicht angegeben.
NUSE_QUEUE_WAS_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Implementierung des Empfangs von Nachrichten aus Warteschlangen in Nucleus SE
Die API-Funktionscodevariante NUSE_Queue_Receive () (nach Überprüfung der Parameter) wird mithilfe der bedingten Kompilierung ausgewählt, je nachdem, ob die Unterstützung für das Sperren von Aufgaben aktiviert ist oder nicht. Betrachten Sie beide Optionen.

Wenn die Sperrunterstützung aktiviert ist, ist der Code für diesen API-Aufruf ziemlich einfach:

 if (NUSE_Queue_Items[queue] == 0) /* queue empty */ { return_value = NUSE_QUEUE_EMPTY; } else { /* message available */ *message = NUSE_Queue_Data[queue][NUSE_Queue_Tail[queue]++]; if (NUSE_Queue_Tail[queue] == NUSE_Queue_Size[queue]) { NUSE_Queue_Tail[queue] = 0; } NUSE_Queue_Items[queue]--; return_value = NUSE_SUCCESS; } 

Die Funktion prüft einfach, ob sich eine Nachricht in der Warteschlange befindet, und verwendet den Index NUSE_Queue_Tail [] , um die Nachricht aus der Warteschlange abzurufen und Daten mithilfe eines Zeigers auf die Nachricht zurückzugeben.

Wenn die Task-Sperre aktiviert ist, wird der Code komplexer:

 do { if (NUSE_Queue_Items[queue] == 0) /* queue empty */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_QUEUE_EMPTY; } else { /* block task */ NUSE_Queue_Blocking_Count[queue]++; NUSE_Suspend_Task(NUSE_Task_Active, (queue << 4) | NUSE_QUEUE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else { /* message available */ *message = NUSE_Queue_Data[queue][NUSE_Queue_Tail[queue]++]; if (NUSE_Queue_Tail[queue] == NUSE_Queue_Size[queue]) { NUSE_Queue_Tail[queue] = 0; } NUSE_Queue_Items[queue]--; if (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; /* check whether a task is blocked */ /* on this queue */ NUSE_Queue_Blocking_Count[queue]--; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } } while (suspend == NUSE_SUSPEND); 

Einige Erläuterungen sind hilfreich.

Der Code ist in einer do ... while-Schleife eingeschlossen , die ausgeführt wird, während der Parameter für die Taskpause NUSE_SUSPEND lautet .

Wenn die Warteschlange leer ist und suspend NUSE_NO_SUSPEND ist , endet der API-Aufruf mit NUSE_QUEUE_EMPTY . Wenn der Suspend- Parameter NUSE_SUSPEND lautet , wird die Task angehalten . Nach Abschluss ( dh wenn die Aufgabe fortgesetzt wird), wenn der Rückgabewert NUSE_SUCCESS ist, dh die Aufgabe wurde fortgesetzt, weil die Nachricht gesendet wurde (und nicht, weil die Warteschlange zurückgesetzt wurde), kehrt der Code zum Anfang der Schleife zurück.

Wenn die Warteschlange Nachrichten enthält, wird die gespeicherte Nachricht mithilfe des Index NUSE_Queue_Tail [] zurückgegeben . Es wird überprüft, ob in dieser Warteschlange angehaltene (ausstehende) Aufgaben vorhanden sind. Wenn es solche Aufgaben gibt, wird die erste von ihnen fortgesetzt. Die Suspend-Variable wird auf NUSE_NO_SUSPEND gesetzt , und der API-Aufruf wird mit dem Code NUSE_SUCCESS beendet.

Schreiben Sie an den Kopf der Warteschlange


Der Aufruf des Nucleus RTOS API-Dienstprogramms zum Schreiben einer Nachricht in den Warteschlangenkopf ist sehr flexibel und ermöglicht es Ihnen, die Aufgabe implizit oder mit einem bestimmten Zeitlimit anzuhalten, wenn der Vorgang nicht sofort abgeschlossen werden kann (z. B. beim Versuch, in eine überfüllte Warteschlange zu schreiben). Nucleus SE bietet die gleiche Funktionalität, aber die Unterbrechung der Aufgabe ist optional und ein Timeout ist nicht implementiert.

Rufen Sie an, um eine Nachricht an den Kopf der Nucleus RTOS-Warteschlange zu schreiben
Prototyp eines Serviceabrufs:

STATUS NU_Send_To_Front_Of_Queue (NU_QUEUE * Warteschlange, VOID * Nachricht, UNSIGNED Größe, UNSIGNED Suspend);

Parameter:

Warteschlange - ein Zeiger auf den vom Benutzer bereitgestellten Warteschlangensteuerblock;
message - Zeiger auf die zu sendende Nachricht;
Größe - Die Anzahl der nicht signierten Datenelemente in der Nachricht. Wenn die Warteschlange Nachrichten mit variabler Länge unterstützt, muss dieser Parameter der Nachrichtengröße entsprechen oder kleiner als die von der Warteschlange unterstützte Nachrichtengröße sein. Wenn die Warteschlange Nachrichten fester Länge unterstützt, muss dieser Parameter genau mit der Größe der von der Warteschlange unterstützten Nachricht übereinstimmen.
suspend - Die Angabe der Suspendierung der Aufgabe kann die Werte NU_NO_SUSPEND oder NU_SUSPEND oder einen Timeout-Wert annehmen .

Rückgabewert:

NU_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Warteschlangenzeiger;
NU_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NU_INVALID_SIZE - Die Nachrichtengröße ist nicht mit der Größe der von der Warteschlange unterstützten Nachricht kompatibel.
NU_INVALID_SUSPEND - Versuch, eine Pause von einem Nicht-Task-Flow einzulegen
NU_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NU_TIMEOUT - Die Warteschlange ist voll, auch nachdem die Aufgabe für eine bestimmte Zeit unterbrochen wurde.
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während die Aufgabe angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Ein Aufruf zum Schreiben einer Nachricht an den Kopf einer Warteschlange in Nucleus SE
Dieser API-Aufruf unterstützt die Kernfunktionalität der Nucleus RTOS-API.

Prototyp eines Serviceabrufs:

STATUS NUSE_Queue_Jam (NUSE_QUEUE-Warteschlange, ADDR * -Nachricht, U8-Suspend);

Parameter:

Warteschlange - Warteschlangenindex (ID);
Nachricht - Ein Zeiger auf eine Nachricht ist eine Variable vom Typ ADDR .
suspend - Die Angabe für die Suspendierung der Aufgabe kann NUSE_NO_SUSPEND oder NUSE_SUSPEND sein

Rückgabewert:

NUSE_SUCCESS - Der Anruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf eine Nachricht ( NULL );
NUSE_INVALID_SUSPEND - ein Versuch, eine Aufgabe in einem Thread anzuhalten, der nicht mit der Aufgabe verknüpft ist oder dessen Unterstützung für das Blockieren von Aufgaben deaktiviert ist;
NUSE_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NUSE_QUEUE_WAS_RESET - Die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde.

Implementieren eines Warteschlangen-Top-Datensatzes in Nucleus SE
Die API-Funktionscodevariante NUSE_Queue_Jam () ist NUSE_Queue_Send () sehr ähnlich. Nur die Daten werden mithilfe des NUSE_Queue_Tail [] -Index gespeichert.

 if (NUSE_Queue_Items[queue] == NUSE_Queue_Size[queue]) /* queue full */ { return_value = NUSE_QUEUE_FULL; } else /* queue element available */ { if (NUSE_Queue_Tail[queue] == 0) { NUSE_Queue_Tail[queue] = NUSE_Queue_Size[queue] - 1; } else { NUSE_Queue_Tail[queue]--; } NUSE_Queue_Data[queue][NUSE_Queue_Tail[queue]] = *message; NUSE_Queue_Items[queue]++; return_value = NUSE_SUCCESS; } 

Der nächste Artikel befasst sich mit zusätzlichen API-Aufrufen, die Warteschlangen zugeordnet sind, sowie mit Datenstrukturen.

Ü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.

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


All Articles