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

Ursprünglicher Autor: Colin Walls
  • Übersetzung


Warteschlangen wurden in einem früheren Artikel erwähnt (Nr. 5). Sie bieten eine flexiblere Möglichkeit, einfache Nachrichten zwischen Aufgaben im Vergleich zu Postfächern zu übertragen.

Vorherige Artikel in der Serie:
Artikel # 22. Mailboxen: Nebendienstleistungen und Datenstrukturen
Artikel # 21. Postfächer: Einführung und Grunddienste
Artikel 20. Semaphoren: Hilfsdienste und Datenstrukturen
Artikel # 19. Semaphore: eine Einführung und grundlegende Dienstleistungen
Artikel # 18. Ereignis-Flag-Gruppen: Nebendienstleistungen und Datenstrukturen
Artikel # 17. Event-Flag-Gruppen: Einführung und Basisdienste
Artikel # 16. Signalisiert
Artikel 15. Speicherbereiche: Dienste und Datenstrukturen
Artikel # 14. Speicherabschnitte: Einführung und Grunddienste
Artikel # 13. Aufgabendatenstrukturen und nicht unterstützte API-Aufrufe
Artikel 12. Aufgabendienste
Artikel 11. Aufgaben: Konfiguration und Einführung in die API
Artikel # 10. Scheduler: Zusätzliche Funktionen und Speichern des Kontext-
Artikels 9. Scheduler: Implementierungsartikel
Nr. 8. Nucleus SE: Internes Design und Bereitstellung
Artikel 7. Nucleus SE: Einführungsartikel
Nr. 6. Andere RTOS-Dienste
Artikel 5. Interaktion zwischen Aufgaben und Synchronisation
Artikel 4. Aufgaben, Kontextwechsel und Interrupts
Artikel 3. Aufgaben und Planung
Artikel 2. RTOS: Struktur und Echtzeitmodus
Artikel 1. RTOS: Einführung.


Verwenden von Warteschlangen


Im Nucleus SE werden die Warteschlangen beim Zusammenbau bestimmt. Die Anwendung kann bis zu 16 Warteschlangen haben. Wenn sich in der Anwendung keine Warteschlangen befinden, werden weder die Datenstrukturen noch der mit den Warteschlangen verknüpfte Service-Code in die Anwendung aufgenommen.

Eine Warteschlange ist eine Gruppe von Speicherbereichen, deren Größe für ein Element des Typs ADDR ausreichtund sicherer Zugriff auf den gesteuert wird, so dass mehrere Aufgaben es verwenden können. Aufgaben können Daten in eine Warteschlange schreiben, bis alle Bereiche gefüllt sind. Tasks können Daten aus einer Warteschlange lesen, und Daten werden normalerweise auf FIFO-Basis (First-in-First-Out) empfangen. Der Versuch, Daten in eine überlaufende Warteschlange zu schreiben oder Daten aus einer leeren Warteschlange zu lesen, kann je nach den ausgewählten API-Aufrufparametern und der Konfiguration des Nucleus SE zu einem Fehler oder einer Unterbrechung der Task führen.

Warteschlangen und Datenkanäle


Nucleus SE unterstützt Datenkanäle, die auch in einem der vorigen Artikel (# 5) erwähnt wurden und auf die in einem der folgenden Punkte näher eingegangen wird. Der Hauptunterschied zwischen Warteschlangen und Kanälen ist die Größe der Nachricht. Warteschlangen enthalten Nachrichten, die aus einer Variablen vom Typ ADDR bestehen (normalerweise sind dies Zeiger). Der Kanal enthält Nachrichten beliebiger Größe, die für jeden Kanal in der Anwendung individuell sind und während der Parametereinstellung zugewiesen werden.

Warteschlangen einrichten


Anzahl der Warteschlangen


Wie bei den meisten Nucleus SE-Objekten wird das Setzen der Warteschlangen hauptsächlich durch die Direktiven #define in der Datei nuse_config.h gesteuert . Der Hauptparameter ist NUSE_QUEUE_NUMBER , der die Anzahl der konfigurierten Warteschlangen in der Anwendung bestimmt. Der Standardwert ist Null ( dh es befinden sich keine Warteschlangen in der Anwendung) und kann Werte bis zu 16 annehmen. Ein falscher Wert führt zu einem Fehler bei der Kompilierung, der beim Einchecken der Datei nuse_config_check.h (in der Datei nuse_config.c) enthalten ist und kompiliert wird () und damit die # Fehler- Direktive auslösen .

Die Wahl eines Werts ungleich Null dient als Hauptaktivator für die Warteschlangen. Dieser Parameter wird bei der Definition von Datenstrukturen verwendet. Ihre Größe hängt von ihrem Wert ab (weitere Informationen hierzu finden Sie im nächsten Artikel). Darüber hinaus aktiviert ein Wert ungleich Null die API-Einstellungen.

Aktivieren Sie API-Aufrufe


Jede Funktion API (Service - Aufruf) im Nucleus SE weist eine aktivierende Richtlinie #define in nuse_config.h . Für Warteschlangen lauten diese Richtlinien:

NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT

Standardmäßig wird ihnen der Wert FALSE zugewiesen . Dadurch werden alle Dienstaufrufe deaktiviert und die Einbeziehung des Codes, der sie implementiert, blockiert. Um die Warteschlangen in der Anwendung zu konfigurieren, müssen Sie die erforderlichen API-Aufrufe auswählen und auf TRUE setzen .

Nachfolgend finden Sie einen 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 Warteschlangen-API-Funktionen aktiviert sind, sich aber keine Warteschlangen in der Anwendung befinden (außer NUSE_Queue_Count () , die immer aktiviert ist), wird ein Kompilierungsfehler angezeigt . Wenn Ihr Code einen API-Aufruf verwendet, der nicht aktiviert wurde, führt dies zu einem Build-Fehler, da der Implementierungscode nicht in der Anwendung enthalten war.

Warteschleifendienstanrufe


Nucleus RTOS unterstützt zehn warteschlangenbezogene Serviceaufrufe, die die folgenden Funktionen bieten:

  • Eine Nachricht in die Warteschlange stellen Der Nucleus SE ist als NUSE_Queue_Send () - Funktion implementiert .
  • Empfangen Sie eine Nachricht aus der Warteschlange. Nucleus SE wird als NUSE_Queue_Receive () - Funktion implementiert .
  • Eine Nachricht in die Warteschlange stellen. Nucleus SE ist in NUSE_Queue_Jam () implementiert .
  • Stellen Sie die Warteschlange mit der Freigabe aller angehaltenen Aufgaben in einen unbenutzten Zustand zurück (Zurücksetzen). Nucleus SE ist in NUSE_Queue_Reset () implementiert .
  • Informationen zu einer bestimmten Warteschlange bereitstellen. Nucleus SE ist in NUSE_Queue_Information () implementiert .
  • Gibt die Anzahl der aktuell konfigurierten Warteschlangen in der Anwendung zurück. Nucleus SE ist in NUSE_Queue_Count () implementiert .
  • Hinzufügen einer neuen Warteschlange zur Anwendung (Erstellen einer Warteschlange) Nucleus SE ist nicht implementiert.
  • Warteschlange aus der Anwendung entfernen Nucleus SE ist nicht implementiert.
  • Rückgabe von Zeigern auf alle Warteschlangen in der Anwendung. Nucleus SE ist nicht implementiert.
  • Senden einer Nachricht an alle in einer Warteschlange angehaltenen Aufgaben (Broadcast). Nucleus SE ist nicht implementiert.

Die Implementierung jedes dieser Serviceaufrufe wird unten ausführlich beschrieben.

Service fordert zum Schreiben und Lesen aus Warteschlangen auf


Die grundlegenden Vorgänge, die für Warteschlangen ausgeführt werden, sind Schreiben (was manchmal als Warteschlangenmeldungen bezeichnet wird) und Lesen (auch als Empfangen von Nachrichten bezeichnet). Es ist auch möglich, am Anfang der Warteschlange aufzunehmen (Jamming). Nucleus RTOS und Nucleus SE bieten drei grundlegende API-Aufrufe für diese Vorgänge, die im Folgenden beschrieben werden.

Schreiben Sie in die Warteschlange


Der Aufruf des Nucleus RTOS API-Dienstes zum Schreiben in die Warteschlange ist sehr flexibel und ermöglicht es Ihnen, die Task implizit oder mit einem bestimmten Timeout auszusetzen, wenn der Vorgang nicht sofort abgeschlossen werden kann (z. B. wenn Sie versuchen, in die gefüllte Warteschlange zu schreiben). Nucleus SE bietet die gleichen Funktionen, die Suspendierung von Aufgaben ist jedoch optional und es wird kein Timeout implementiert.

Aufruf zum Einreihen einer Nachricht in einen Nucleus RTOS

Service Call Prototyp:

STATUS NU_Send_To_Queue (Warteschlange NU_QUEUE *, VOID * -Meldung, Größe UNSIGNED, UNSIGNED suspend);

Parameter:

queue - Zeiger auf den vom Benutzer bereitgestellten Warteschlangenverwaltungsblock;
message - ein Zeiger auf die zu sendende Nachricht;
size - die Anzahl der Datenelemente vom Typ UNSIGNEDin der Nachricht. Wenn die Warteschlange Nachrichten mit variabler Länge unterstützt, muss dieser Parameter der Größe der Nachricht entsprechen oder kleiner sein als die Größe der Nachricht, die von der Warteschlange unterstützt wird. Wenn die Warteschlange Nachrichten fester Größe unterstützt, muss dieser Parameter genau mit der Größe der von der Warteschlange unterstützten Nachricht übereinstimmen.
Suspend - Task-Suspendierungsspezifikation kann NU_NO_SUSPEND oder NU_SUSPEND oder Timeout-Wert sein.

Rückgabewert:

NU_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Zeiger auf die Warteschlange;
NU_INVALID_POINTER - Nullzeiger auf die Nachricht ( NULL );
NU_INVALID_SIZE- Die Nachrichtengröße ist mit der von der Warteschlange unterstützten Nachrichtengröße nicht kompatibel.
NU_INVALID_SUSPEND - Die Aussetzung wurde von einem Thread aus vorgenommen, der nicht mit der Aufgabe verknüpft ist.
NU_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NU_TIMEOUT - Die Warteschlange ist voll, auch nachdem die Task für das angegebene Timeout angehalten wurde.
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während der Task angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während der Task angehalten wurde.

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

Serviceanruf-Prototyp:

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

Parameter:

Warteschlange - der Index (ID) der Warteschlange;
Nachrichtenzeiger auf die zu sendende Nachricht ist eine einzelne Variable vom Typ ADDR ;
Suspend - Spezifikation für das Unterbrechen von Tasks, kann NUSE_NO_SUSPEND oder NUSE_SUSPEND sein .

Rückgabewert:

NUSE_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf die Nachricht ( NULL );
NUSE_INVALID_SUSPEND- Versuch, eine Task von einem Thread aus anzuhalten, der nicht mit der Task verbunden ist, oder wenn API-Aufrufe zum Blockieren von Tasks deaktiviert sind;
NUSE_QUEUE_FULL - Die Warteschlange ist voll und die Aussetzung wurde nicht angegeben.
NUSE_QUEUE_WAS_RESET - Die Warteschlange wurde zurückgesetzt, während der Task angehalten wurde.

Implementieren von Message Queuing in Nucleus SE
Die Codeoption für die API-Funktion NUSE_Queue_Send () (nach Überprüfung der Parameter) wird mithilfe der bedingten Kompilierung ausgewählt, abhängig davon, ob die Unterstützung für das Blockieren von Aufgaben aktiviert ist oder nicht. Wir werden beide Möglichkeiten prüfen.

Wenn die Aufgabensperre nicht aktiviert ist, ist der Code für diesen Serviceaufruf recht 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 lediglich, ob in der Warteschlange freier Speicherplatz vorhanden ist, und verwendet den Index NUSE_Queue_Head [] , um die Nachricht im Warteschlangendatenbereich zu speichern.

Wenn die Aufgabensperre 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 Erklärungen können hilfreich sein.

Der Code ist in einer do ... while-Schleife eingeschlossen , die ausgeführt wird, bis der Parameter für den Suspend-Task NUSE_SUSPEND ist .

Wenn die Warteschlange voll ist und die Parameter suspendieren Materie NUSE_NO_SUSPEND wird API - Aufruf mit dem Wert beendet NUSE_QUEUE_FULL . Wenn der Suspend-Parameter auf NUSE_SUSPEND gesetzt ist , wird die Task angehalten. Wenn der Rückgabewert NUSE_SUCCESS lautet , das heißt, die Task wurde fortgesetzt, weil die Nachricht gelesen wurde (und nicht weil die Warteschlange zurückgesetzt wurde), kehrt der Code an den Anfang des Zyklus zurück.
Wenn die Warteschlange nicht voll ist, wird die bereitgestellte Nachricht mit dem Index NUSE_Queue_Head [] im Warteschlangendatenbereich gespeichert. Überprüft, ob sich in der Warteschlange ausstehende Aufgaben befinden (auf Nachrichten warten). Wenn es solche Aufgaben gibt, wird die erste fortgesetzt. Der Variablen suspend wird der Wert NUSE_NO_SUSPEND zugewiesen , und der API-Aufruf endet mit dem Wert NUSE_SUCCESS .

Lesen aus der Warteschlange


Der Aufruf des Nucleus RTOS API-Dienstes zum Lesen aus einer Warteschlange ist sehr flexibel und ermöglicht das implizite Anhalten von Aufgaben oder ein bestimmtes Zeitlimit, 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, die Suspendierung von Aufgaben ist jedoch optional, und es wird kein Timeout implementiert.

Aufruf zum Empfang von Nachrichten aus einer Warteschlange im Nucleus RTOS
Service Call Prototyp:

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

Parameter:

queue - Zeiger auf den vom Benutzer bereitgestellten Warteschlangenverwaltungsblock;
Nachrichtenzeiger auf das Repository für empfangene Nachrichten;
Größe- die Anzahl der Datenelemente des Typs UNSIGNED in der Nachricht. Diese Nummer muss mit der Größe der Nachricht übereinstimmen, die beim Erstellen der Warteschlange angegeben wurde.
Suspend - Task-Suspendierungsspezifikation kann NU_NO_SUSPEND oder NU_SUSPEND oder Timeout-Wert sein.

Rückgabewert:

NU_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Zeiger auf die Warteschlange;
NU_INVALID_POINTER - Nullzeiger auf die Nachricht ( NULL );
NU_INVALID_SUSPEND - ein Versuch, eine Aufgabe aus einem Thread heraus anzuhalten, der sich nicht auf eine Aufgabe bezieht ;
NU_QUEUE_EMPTY- Die Warteschlange ist leer und die Aussetzung wurde nicht angegeben.
NU_TIMEOUT - Gibt an , dass die Warteschlange noch leer ist, auch nachdem die Task für einen bestimmten Zeitraum angehalten wurde.
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während der Task angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während der Task angehalten wurde.

Aufruf zum Empfang von Nachrichten aus der Nucleus SE-Warteschlange
Dieser API-Aufruf unterstützt die Kernfunktionen der Nucleus RTOS-API.

Dienstaufruf-Prototyp:

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

Parameter:

Warteschlange - der Index (ID) der Warteschlange;
Nachricht- Zeiger auf das Repository für empfangene Nachrichten, ist eine einzige Variable vom Typ ADDR .
Suspend - Task-Suspendierungsspezifikation, kann NUSE_NO_SUSPEND oder NUSE_SUSPEND sein .

Rückgabewert:

NUSE_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf die Nachricht ( NULL );
NUSE_INVALID_SUSPEND - Ein Versuch, eine Task aus einem Thread anzuhalten, der nicht mit der Task verbunden ist oder wenn die Unterstützung für die Tasksperre 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 der Task angehalten wurde.

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

Wenn die Sperrunterstützung aktiviert ist, ist der Code für diesen API-Aufruf recht 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 lediglich, ob sich eine Nachricht in der Warteschlange befindet, und verwendet den Index NUSE_Queue_Tail [] , um die Nachricht aus der Warteschlange abzurufen und die Daten mit einem Zeiger auf die Nachricht zurückzugeben.

Wenn die Aufgabensperre 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 Erklärungen werden hilfreich sein.

Der Code ist in einer do ... while-Schleife eingeschlossen , die ausgeführt wird, bis der Parameter für den Suspend-Task NUSE_SUSPEND ist .

Wenn die Warteschlange leer ist und der Suspend-Parameter NUSE_NO_SUSPEND ist , wird der API-Aufruf mit dem Wert NUSE_QUEUE_EMPTY beendet . Wenn der Suspend- Parameter auf NUSE_SUSPEND gesetzt ist , wird die Task angehalten. Wenn der Rückgabewert NUSE_SUCCESS lautet ( dh , wenn die Task wieder aufgenommen wird), dh die Task wurde fortgesetzt, weil die Nachricht gesendet wurde (und nicht weil die Warteschlange zurückgesetzt wurde), kehrt der Code zum Anfang des Zyklus zurück.

Wenn die Warteschlange Nachrichten enthält, wird die gespeicherte Nachricht mit dem NUSE_Queue_Tail [] - Index zurückgegeben . Überprüft, ob in dieser Warteschlange angehaltene (ausstehende) Aufgaben vorhanden sind. Wenn es solche Aufgaben gibt, wird die erste fortgesetzt. Der Variablen suspend wird der Wert NUSE_NO_SUSPEND zugewiesen , und der API-Aufruf endet mit dem Code NUSE_SUCCESS .

In die Warteschlange schreiben


Der Aufruf des Nucleus RTOS API-Dienstes zum Schreiben einer Nachricht an den Kopf der Warteschlange ist sehr flexibel. Sie können die Aufgabe implizit oder mit einem bestimmten Zeitlimit aussetzen, 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, die Suspendierung von Aufgaben ist jedoch optional, und es wird kein Timeout implementiert.

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

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

Parameter:

queue - Zeiger auf den vom Benutzer bereitgestellten Warteschlangenverwaltungsblock;
message - ein Zeiger auf die zu sendende Nachricht;
Größe- die Anzahl der Datenelemente des Typs UNSIGNED in der Nachricht. Wenn die Warteschlange Nachrichten mit variabler Länge unterstützt, muss dieser Parameter der Größe der Nachricht entsprechen oder kleiner sein als die Größe der Nachricht, die von der Warteschlange unterstützt wird. Wenn die Warteschlange Nachrichten mit fester Länge unterstützt, muss dieser Parameter genau der Größe der Nachricht entsprechen, die von der Warteschlange unterstützt wird.
Suspend - Task-Suspendierungsspezifikation kann NU_NO_SUSPEND oder NU_SUSPEND oder Timeout-Wert sein.

Rückgabewert:

NU_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NU_INVALID_QUEUE - ungültiger Zeiger auf die Warteschlange;
NU_INVALID_POINTER- Nullzeiger auf die Nachricht ( NULL );
NU_INVALID_SIZE - Die Nachrichtengröße ist mit der Größe der von der Warteschlange unterstützten Nachricht nicht kompatibel.
NU_INVALID_SUSPEND - Suspendierungsversuch aus nicht aufgabenbezogenem Stream
NU_QUEUE_FULL - Die Warteschlange ist voll und die Suspendierung wurde nicht angegeben.
NU_TIMEOUT - Die Warteschlange ist voll, auch nachdem die Task für ein bestimmtes Zeitlimit angehalten wurde .
NU_QUEUE_DELETED - Die Warteschlange wurde gelöscht, während der Task angehalten wurde.
NU_QUEUE_RESET - Die Warteschlange wurde zurückgesetzt, während der Task angehalten wurde.

Aufruf zum Schreiben einer Nachricht in die Hauptwarteschlange in Nucleus SE
Dieser API-Aufruf unterstützt die Kernfunktionen der Nucleus RTOS-API.

Dienstaufruf-Prototyp:

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

Parameter:

Warteschlange - der Index (ID) der Warteschlange;
message - Ein Zeiger auf die Nachricht ist eine einzelne Variable vom Typ ADDR .
Suspend - Task-Suspendierungsspezifikation kann NUSE_NO_SUSPEND oder NUSE_SUSPEND sein .

Rückgabewert:

NUSE_SUCCESS - Der Aufruf wurde erfolgreich abgeschlossen.
NUSE_INVALID_QUEUE - ungültiger Warteschlangenindex;
NUSE_INVALID_POINTER - Nullzeiger auf die Nachricht ( NULL );
NUSE_INVALID_SUSPEND- einen Versuch, eine Aufgabe von einem Thread aus anzuhalten, der keiner Aufgabe zugeordnet ist, oder wenn die 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 der Task angehalten wurde.

Die Umsetzung Aufzeichnung Nachrichten in der Warteschlange in der Nucleus SE
Code Option Funktion der API NUSE_Queue_Jam () sind sehr ähnlich zu NUSE_Queue_Send () , nur die Daten des Index gespeichert ist NUSE_Queue_Tail [] , wie folgt:

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;
}

Im nächsten Artikel werden zusätzliche API-Aufrufe in Bezug auf Warteschlangen sowie Datenstrukturen beschrieben.

Über den Autor: Colin Walls ist seit über dreißig Jahren in der Elektronikbranche tätig und verbrachte viel Zeit mit eingebetteter Software. Er ist jetzt ein Embedded Software Engineer in Mentor Embedded (einer Abteilung von Mentor Graphics). Colin Walls spricht häufig auf Konferenzen und Seminaren, Autor zahlreicher Fachartikel und zwei Bücher über eingebettete Software. Lebt in Großbritannien. Colins professioneller Blog , E-Mail: colin_walls@mentor.com.

Jetzt auch beliebt: