Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial Internet of Things >> Eingebettet

Warteschlangen:Einführung und grundlegende Dienste


RTOS Revealed-Serie anzeigen

Warteschlangen wurden in einem früheren Artikel eingeführt. Sie bieten eine flexiblere Möglichkeit, einfache Nachrichten zwischen Aufgaben zu übertragen, als Mailboxen.

Verwenden von Warteschlangen

In Nucleus SE werden Warteschlangen zur Build-Zeit konfiguriert. Es können maximal 16 Warteschlangen für eine Anwendung konfiguriert sein. Wenn keine Warteschlangen konfiguriert sind, werden keine zu Warteschlangen gehörenden Datenstrukturen oder Dienstaufrufcodes in die Anwendung aufgenommen.

Eine Warteschlange ist einfach eine Reihe von Speicherorten, von denen jeder groß genug ist, um ein einzelnes Datenelement vom Typ ADDR aufzunehmen , deren Zugriff kontrolliert wird, damit er von mehreren Aufgaben sicher genutzt werden kann. Aufgaben können wiederholt in eine Warteschlange schreiben, bis alle Speicherorte voll sind. Tasks können aus einer Warteschlange lesen und Daten werden normalerweise nach dem First-In-First-Out-Prinzip (FIFO) empfangen. Der Versuch, an eine volle Warteschlange zu senden oder von einer leeren zu lesen, kann je nach den im API-Aufruf und der Nucleus SE-Konfiguration ausgewählten Optionen zu einem Fehler oder einer Unterbrechung der Aufgabe führen.

Warteschlangen und Pipes

Nucleus SE unterstützt auch Rohre, die ebenfalls in einem früheren Artikel vorgestellt wurden und in einem zukünftigen Artikel ausführlich behandelt werden. Der Hauptunterschied zwischen Warteschlangen und Pipes ist die Nachrichtengröße. Warteschlangen enthalten Nachrichten mit einer einzelnen ADDR – dies wären normalerweise Hinweise. Eine Pipe trägt Nachrichten, die eine beliebige Anzahl von Bytes lang sind; die Größe wird für jedes Rohr in der Anwendung festgelegt und bei der Konfiguration eingestellt.

Warteschlangen konfigurieren

Anzahl der Warteschlangen

Wie bei den meisten Aspekten von Nucleus SE wird die Konfiguration von Warteschlangen hauptsächlich durch #define . gesteuert Anweisungen in nuse_config.h . Die Schlüsseleinstellung ist NUSE_QUEUE_NUMBER , die bestimmt, wie viele Warteschlangen für die Anwendung konfiguriert sind. Die Standardeinstellung ist 0 (dh es werden keine Warteschlangen verwendet) und Sie können sie auf einen beliebigen Wert bis 16 setzen. Ein falscher Wert führt zu einem Kompilierzeitfehler, der durch einen Test in nuse_config_check.h<. generiert wird /strong> (dies ist in nuse_config.c enthalten und daher mit diesem Modul kompiliert), was zu einem #error führt Anweisung wird zusammengestellt.

Die Wahl eines Werts ungleich Null ist die „Masterfreigabe“ für Warteschlangen. Dies führt dazu, dass einige Datenstrukturen entsprechend definiert und dimensioniert werden, davon mehr im nächsten Artikel. Es aktiviert auch die API-Aktivierungseinstellungen.

API aktiviert

Jede API-Funktion (Dienstaufruf) in Nucleus SE hat eine aktivierende #define Symbol in nuse_config.h . Für Warteschlangen sind dies:

NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT

Standardmäßig sind diese alle auf FALSCH eingestellt , wodurch jeder Dienstaufruf deaktiviert und die Aufnahme jeglichen Implementierungscodes verhindert wird. Um Warteschlangen für eine Anwendung zu konfigurieren, müssen Sie die API-Aufrufe auswählen, die Sie verwenden möchten, und ihre Aktivierungssymbole auf TRUE setzen .

Hier ist ein Auszug aus der Standarddatei nuse_config.h.

#define NUSE_QUEUE_NUMBER    0  /* Anzahl der Warteschlangen in der
- 0-16 * /
/ * Service Anruf Enabler * /
#define NUSE_QUEUE_SEND FALSCH
#define NUSE_QUEUE_RECEIVE FALSCH
#define NUSE_QUEUE_JAM FALSCH
#define NUSE_QUEUE_RESET        FALSE
#define NUSE_QUEUE_INFORMATION  FALSE
#define NUSE_QUEUE_COUNT        FALSE

Ein Kompilierzeitfehler tritt auf, wenn eine Warteschlangen-API-Funktion aktiviert ist und keine Warteschlangen konfiguriert sind (außer NUSE_Queue_Count() was immer erlaubt ist). Wenn Ihr Code einen API-Aufruf verwendet, der nicht aktiviert wurde, kommt es zu einem Linkzeitfehler, da kein Implementierungscode in die Anwendung eingefügt wurde.

Warteschlangendienstaufrufe

Nucleus RTOS unterstützt zehn Serviceaufrufe, die sich auf Warteschlangen beziehen und die folgende Funktionalität bieten:

  • Eine Nachricht an eine Warteschlange senden. Implementiert von NUSE_Queue_Send() in Nucleus SE.

  • Empfang eine Nachricht aus einer Warteschlange. Implementiert von NUSE_Queue_Receive() in Nucleus SE.

  • Sende eine Nachricht an den Anfang einer Warteschlange. Implementiert von NUSE_Queue_Jam() in Nucleus SE.

  • Stellen Sie eine Warteschlange in den unbenutzten Zustand zurück, ohne dass Aufgaben angehalten (zurückgesetzt) ​​werden. Implementiert von NUSE_Queue_Reset() in Nucleus SE.

  • Geben Sie Informationen zu einer angegebenen Warteschlange an. Implementiert von NUSE_Queue_Information() in Nucleus SE.

  • Geben Sie die Anzahl der Warteschlangen zurück, die (derzeit) für die Anwendung konfiguriert sind. Implementiert von NUSE_Queue_Count() in Nucleus SE.

  • Fügen Sie der Anwendung eine neue Warteschlange hinzu (erstellen). Nicht in Nucleus SE implementiert.

  • Entfernen Sie eine Warteschlange aus der Anwendung (löschen). Nicht in Nucleus SE implementiert.

  • Gibt Zeiger auf alle Warteschlangen (derzeit) in der Anwendung zurück. Nicht in Nucleus SE implementiert.

  • Sende eine Nachricht an alle Aufgaben, die in einer Warteschlange angehalten sind (Broadcast). Nicht in Nucleus SE implementiert.

Die Implementierung jedes dieser Service Calls wird im Detail untersucht.

Queue Write and Read Services

Die grundlegenden Operationen, die an einer Warteschlange ausgeführt werden können, sind das Schreiben von Daten in diese – was manchmal als Senden bezeichnet wird – und das Auslesen von Daten daraus – was auch als Empfangen bezeichnet wird . Es ist auch möglich, Daten an den Anfang einer Warteschlange zu schreiben – was auch als Jamming bezeichnet wird . Nucleus RTOS und Nucleus SE bieten jeweils drei grundlegende API-Aufrufe für diese Operationen, die hier besprochen werden.

In eine Warteschlange schreiben

Der Nucleus RTOS API-Aufruf zum Schreiben in eine Warteschlange ist sehr flexibel, sodass Sie auf unbestimmte Zeit oder mit einer Zeitüberschreitung anhalten können, wenn der Vorgang nicht sofort abgeschlossen werden kann; d.h. Sie versuchen, in eine volle Warteschlange zu schreiben. Nucleus SE bietet den gleichen Service, außer dass das Aussetzen von Aufgaben optional ist und das Timeout nicht implementiert ist.

Nucleus RTOS bietet auch die Möglichkeit, an eine Warteschlange zu senden, dies wird jedoch von Nucleus SE nicht unterstützt. Es wird im nächsten Artikel unter Nicht implementierte APIs beschrieben.

Nucleus RTOS API-Aufruf zum Senden an eine Warteschlange

Prototyp für Serviceruf:

STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID  *message,
                        UNSIGNED size, UNSIGNED suspend);

Parameter:

Warteschlange – Zeiger auf den vom Benutzer bereitgestellten Warteschlangenkontrollblock

Nachricht – ein Zeiger auf die zu sendende Nachricht

Größe – die Anzahl der UNSIGNIERTEN Datenelemente in der Nachricht. Wenn die Warteschlange Nachrichten variabler Länge unterstützt, muss dieser Parameter kleiner oder gleich der von der Warteschlange unterstützten Nachrichtengröße sein. Wenn die Warteschlange Nachrichten mit fester Größe unterstützt, muss dieser Parameter genau der Nachrichtengröße entsprechen, die von der Warteschlange unterstützt wird.

Aussetzen – Spezifikation für Task-Aussetzung; kann NU_NO_SUSPEND sein oder NU_SUSPEND oder ein Timeout-Wert

Rückgabe:

NU_SUCCESS – der Anruf wurde erfolgreich abgeschlossen

NU_INVALID_QUEUE – der Warteschlangenzeiger ist ungültig

NU_INVALID_POINTER – der Nachrichtenzeiger ist NULL

NU_INVALID_SIZE – die Nachrichtengröße ist nicht mit der von der Warteschlange unterstützten Nachrichtengröße kompatibel

NU_INVALID_SUSPEND – Suspend wurde von einem Nicht-Task-Thread versucht

NU_QUEUE_FULL – die Warteschlange ist voll und Suspend wurde nicht angegeben

NU_TIMEOUT – die Warteschlange ist auch nach dem Suspendieren für den angegebenen Timeout-Wert noch voll

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

Nucleus SE API-Aufruf zum Senden an eine Warteschlange

Dieser API-Aufruf unterstützt die Schlüsselfunktionalität der Nucleus RTOS API.

Prototyp für Serviceruf:

STATUS NUSE_Queue_Send(NUSE_QUEUE queue, ADDR *message,
                       U8 suspend);

Parameter:

Warteschlange – der Index (ID) der zu verwendenden Warteschlange

Nachricht – ein Zeiger auf die zu sendende Nachricht, die eine einzelne Variable vom Typ ADDR ist

Aussetzen – Spezifikation für Task-Aussetzung; kann NUSE_NO_SUSPEND sein oder NUSE_SUSPEND

Rückgabe:

NUSE_SUCCESS – der Anruf wurde erfolgreich abgeschlossen

NUSE_INVALID_QUEUE – der Warteschlangenindex ist ungültig

NUSE_INVALID_POINTER – der Nachrichtenzeiger ist NULL

NUSE_INVALID_SUSPEND – Suspend wurde von einem Nicht-Task-Thread versucht oder wenn das Blockieren von API-Aufrufen nicht aktiviert war

NUSE_QUEUE_FULL – die Warteschlange ist voll und Suspend wurde nicht angegeben

NUSE_QUEUE_WAS_RESET – die Warteschlange wurde zurückgesetzt, während die Aufgabe angehalten wurde

Nucleus SE-Implementierung von Queue ASend

Der Großteil des Codes von NUSE_Queue_Send() API-Funktion – nach Parameterprüfung – wird durch bedingte Kompilierung ausgewählt, abhängig davon, ob die Unterstützung für das Blockieren (Task-Suspendieren) von API-Aufrufen aktiviert ist. Wir werden uns die beiden Varianten hier separat anschauen.

Wenn die Blockierung nicht aktiviert ist, ist der Code für diesen API-Aufruf recht einfach:

if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* Warteschlange voll */{ return_value =NUSE_QUEUE_FULL;}else /* Warteschlangenelement verfügbar */{ NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] =*Botschaft; if (NUSE_Queue_Head[Warteschlange] ==NUSE_Queue_Size[Warteschlange]) { NUSE_Queue_Head[Warteschlange] =0; } NUSE_Queue_Items[Warteschlange]++; return_value =NUSE_SUCCESS;}

Die Funktion prüft einfach, ob in der Warteschlange Platz ist und verwendet den NUSE_Queue_Head[] index, um die Nachricht im Datenbereich der Warteschlange zu speichern.

Wenn die Blockierung aktiviert ist, wird der Code komplexer:

do{ if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* Warteschlange voll */ { if (suspend ==NUSE_NO_SUSPEND) { return_value =NUSE_QUEUE_FULL; } else { /* Aufgabe blockieren */ NUSE_Queue_Blocking_Count[Warteschlange]++; NUSE_Suspend_Task(NUSE_Task_Active, (Warteschlange <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value !=NUSE_SUCCESS) { suspend =NUSE_NO_SUSPEND; } } } else { /* Warteschlangenelement verfügbar */ NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] =*message; if (NUSE_Queue_Head[Warteschlange] ==NUSE_Queue_Size[Warteschlange]) { NUSE_Queue_Head[Warteschlange] =0; } NUSE_Queue_Items[Warteschlange]++; if (NUSE_Queue_Blocking_Count[Warteschlange] !=0) { U8-Index; /* prüfen, ob eine Aufgabe in dieser Warteschlange blockiert ist */ NUSE_Queue_Blocking_Count[queue]--; for (index=0; index 

Eine Erklärung des Codes kann hilfreich sein:

Der Code ist in einem do…while eingeschlossen Schleife, die fortgesetzt wird, während der Parameter suspend den Wert NUSE_SUSPEND hat .

Wenn die Warteschlange voll ist und aussetzen ist auf NUSE_NO_SUSPEND eingestellt , wird der API-Aufruf mit NUSE_QUEUE_FULL beendet . Wenn die Sperre auf NUSE_SUSPEND festgelegt wurde , die Aufgabe wird ausgesetzt. Bei der Rückkehr (d. h. wenn die Aufgabe aufgeweckt wird), wenn der Rückgabewert NUSE_SUCCESS ist , was darauf hinweist, dass die Aufgabe aufgeweckt wurde, weil eine Nachricht gelesen wurde (im Gegensatz zum Zurücksetzen der Warteschlange), der Code kehrt nach oben zurück.

Wenn die Warteschlange nicht voll ist, wird die bereitgestellte Nachricht mit dem NUSE_Queue_Head[] stored gespeichert index, um die Nachricht im Datenbereich der Warteschlange zu speichern. Es wird geprüft, ob Aufgaben in der Warteschlange ausgesetzt sind (auf Empfang warten). Wenn Aufgaben warten, wird die erste geweckt. Die Aussetzung Variable ist auf NUSE_NO_SUSPEND eingestellt und der API-Aufruf wird mit NUSE_SUCCESS beendet .


Eingebettet

  1. Eine Einführung in Nockenschlösser und wie sie funktionieren
  2. Eine Einführung in Augenschrauben und ihre Funktionsweise
  3. Eine Einführung in Ösen und ihre Funktionsweise
  4. Eine Einführung in Edelstahl und seine Herstellung
  5. C# Grundlegende Ein- und Ausgabe
  6. Postfächer:Einführung und grundlegende Dienste
  7. Semaphoren:Versorgungsdienste und Datenstrukturen
  8. Semaphoren:Einführung und grundlegende Dienste
  9. Ereigniskennzeichengruppen:Versorgungsdienste und Datenstrukturen
  10. Ereignisflaggengruppen:Einführung und grundlegende Dienste