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

Postfächer:Einführung und grundlegende Dienste


RTOS Revealed-Serie anzeigen

Mailboxen wurden in einem früheren Artikel vorgestellt. Sie sind vielleicht die zweiteinfachste Methode der Inter-Task-Kommunikation – nach Signalen – die von Nucleus SE unterstützt wird. Sie bieten eine kostengünstige, aber flexible Möglichkeit, einfache Nachrichten zwischen Aufgaben zu übertragen.

Verwendung von Postfächern

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

Ein Postfach ist einfach ein Speicherort, der groß genug ist, um eine einzelne Variable vom Typ ADDR aufzunehmen , deren Zugriff kontrolliert wird, damit er von mehreren Aufgaben sicher genutzt werden kann. Eine Aufgabe kann in ein Postfach schreiben. Es ist dann voll und keine Aufgabe kann an sie gesendet werden, bis eine Aufgabe das Postfach liest oder das Postfach zurückgesetzt wird. Der Versuch, an eine volle Mailbox zu senden oder von einer leeren Mailbox 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.

Postfächer und Warteschlangen

In einigen Betriebssystemimplementierungen sind keine Mailboxen implementiert, und die Verwendung einer Warteschlange mit einem einzigen Eintrag wird als Alternative empfohlen. Das klingt vernünftig, da eine solche Warteschlange die gleiche Funktionalität wie ein Postfach bieten würde. Eine Warteschlange ist jedoch eine etwas komplexere Datenstruktur als eine Mailbox und bringt erheblich mehr Overhead an Daten (Kopf- und Endzeiger usw.), Code und Ausführungszeit mit sich.

Bei Nucleus SE haben Sie wie Nucleus RTOS die Wahl zwischen beiden Objekttypen und können die Entscheidung selbst treffen.

Es lohnt sich, den alternativen Ansatz in Betracht zu ziehen, wenn Ihre Anwendung mehrere Warteschlangen enthält, aber möglicherweise ein einzelnes Postfach. Das Ersetzen dieses Postfachs durch eine Warteschlange verursacht einen geringen Daten-Overhead, eliminiert jedoch den gesamten postfachbezogenen API-Code. Es wäre sehr einfach, die Anwendung in beide Richtungen zu konfigurieren und den Speicherbedarf und die Leistung zu vergleichen.

Warteschlangen werden in zukünftigen Artikeln besprochen.

Postfächer konfigurieren

Anzahl der Postfächer

Wie bei den meisten Aspekten von Nucleus SE wird die Konfiguration von Postfächern hauptsächlich von #define . gesteuert Anweisungen in nuse_config.h . Die Schlüsseleinstellung ist NUSE_MAILBOX_NUMBER , die bestimmt, wie viele Postfächer für die Anwendung konfiguriert sind. Die Standardeinstellung ist 0 (dh es werden keine Mailboxen 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 Mailboxen. 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 Postfächer sind dies:

NUSE_MAILBOX_SEND
NUSE_MAILBOX_RECEIVE
NUSE_MAILBOX_RESET
NUSE_MAILBOX_INFORMATION
NUSE_MAILBOX_COUNT

Standardmäßig sind diese alle auf FALSCH eingestellt , wodurch jeder Dienstaufruf deaktiviert und die Aufnahme jeglichen Implementierungscodes verhindert wird. Um Postfächer 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 standardmäßigen nuse_config.h Datei.

/* Anzahl der Postfächer im  System - 0-16 */ #define NUSE_MAILBOX_NUMBER 0  /* Service Call Enabler:*/ #define NUSE_MAILBOX_SEND FALSE  #define NUSE_MAILBOX_RECEIVE FALSE  #define NUSE_MAILBOX_RESET FALSE  #define NUSE_MAILBOX_INFORMATION FALSE  #define NUSE_MAILBOX_COUNT FALSE  

Ein Kompilierzeitfehler tritt auf, wenn eine Postfach-API-Funktion aktiviert ist und keine Postfächer konfiguriert sind (außer NUSE_Mailbox_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.

Mailbox-Dienstaufrufe

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

  • Nachricht an eine Mailbox senden. Implementiert von NUSE_Mailbox_Send() in Nucleus SE.

  • Empfang eine Nachricht aus einer Mailbox. Implementiert von NUSE_Mailbox_Receive() in Nucleus SE.

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

  • Geben Sie Informationen zu einem angegebenen Postfach an. Implementiert von NUSE_Mailbox_Information() in Nucleus SE.

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

  • Fügen Sie der Anwendung ein neues Postfach hinzu (erstellen). Nicht in Nucleus SE implementiert.

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

  • Geben Sie Zeiger auf alle Postfächer (derzeit) in der Anwendung zurück. Nicht in Nucleus SE implementiert.

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

Die Implementierung jedes dieser Service Calls wird im Detail untersucht.

Mailbox-Schreib- und Lesedienste

Die grundlegenden Operationen, die an einer Mailbox ausgeführt werden können, sind das Schreiben von Daten in sie – was manchmal als Senden bezeichnet wird oder posten – und das Auslesen von Daten daraus – was auch als Empfangen bezeichnet wird . Nucleus RTOS und Nucleus SE bieten jeweils zwei grundlegende API-Aufrufe für diese Operationen, die hier besprochen werden.

In eine Mailbox schreiben

Der Nucleus RTOS API-Aufruf zum Schreiben in eine Mailbox 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 ein volles Postfach 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 Mailbox zu senden, dies wird jedoch von Nucleus SE nicht unterstützt. Es wird unter Nicht implementierte APIs beschrieben im nächsten Artikel.

Nucleus RTOS API-Aufruf zum Senden an eine Mailbox

Prototyp für Serviceruf:

STATUS NU_Send_To_Mailbox(NU_MAILBOX *Mailbox, VOID *Nachricht,  UNSIGNED sperren);

Parameter:

Postfach – Zeiger auf die zu verwendende Mailbox

Nachricht – ein Zeiger auf die zu sendende Nachricht, der vier unsigniert ist Elemente

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_MAILBOX – der Postfachzeiger ist ungültig

NU_INVALID_POINTER – der Nachrichtenzeiger ist NULL

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

NU_MAILBOX_FULL – die Mailbox ist voll und Suspend wurde nicht angegeben

NU_TIMEOUT – die Mailbox ist auch nach der Sperrung für den angegebenen Zeitraum noch voll

NU_MAILBOX_DELETED – das Postfach wurde gelöscht, während die Aufgabe angehalten wurde

NU_MAILBOX_WAS_RESET – die Mailbox wurde zurückgesetzt, während die Aufgabe angehalten wurde

Nucleus SE API-Aufruf zum Senden an eine Mailbox

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

Prototyp für Serviceruf:

STATUS NUSE_Mailbox_Send(NUSE_MAILBOX-Postfach, ADDR *Nachricht,  U8-Aussetzung);

Parameter:

Postfach – der Index (ID) der zu verwendenden Mailbox

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_MAILBOX – der Postfachindex 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_MAILBOX_FULL – das Postfach ist voll und Suspend wurde nicht angegeben

NUSE_MAILBOX_WAS_RESET – die Mailbox wurde zurückgesetzt, während die Aufgabe angehalten wurde

Nucleus SE-Implementierung von Mailbox Send

Der Großteil des Codes von NUSE_Mailbox_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 die Logik für diesen API-Aufruf recht einfach und der Code erfordert wenig Erklärung:

if (NUSE_Mailbox_Status[Mailbox]) /* Mailbox voll */{ return_value =NUSE_MAILBOX_FULL;}else /* Mailbox leer */{ NUSE_Mailbox_Data[Mailbox] =*Nachricht; NUSE_Mailbox_Status[Mailbox] =TRUE; return_value =NUSE_SUCCESS;}

Die Nachricht wird im entsprechenden Element von NUSE_Mailbox_Data[] gespeichert und die Mailbox als in Gebrauch markiert.

Wenn die Blockierung aktiviert ist, wird der Code komplexer:

do{ if (!NUSE_Mailbox_Status[Mailbox]) /* Mailbox leer */ { NUSE_Mailbox_Data[Mailbox] =*Nachricht; NUSE_Mailbox_Status[Mailbox] =TRUE; if (NUSE_Mailbox_Blocking_Count[Mailbox] !=0) { U8-Index; /* prüfen, ob eine Aufgabe blockiert ist */ /* auf dieser Mailbox */ NUSE_Mailbox_Blocking_Count[Mailbox]--; for (index=0; index 

Einige Erklärungen können nützlich sein:

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

Wenn die Mailbox leer ist, wird die bereitgestellte Nachricht gespeichert und der Mailboxstatus geändert, um anzuzeigen, dass sie voll ist. Es wird geprüft, ob Aufgaben in der Mailbox 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 .

Wenn das Postfach voll ist und sperren ist auf NUSE_NO_SUSPEND eingestellt , der API-Aufruf endet mit NUSE_MAILBOX_FULL . Wenn Aussetzen wurde auf NUSE_SUSPEND eingestellt , 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 Mailbox), der Code kehrt nach oben zurück.


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. COVID 19 und Cloud; COVID 19 und seine Auswirkungen auf das Geschäft
  6. C# Grundlegende Ein- und Ausgabe
  7. Semaphoren:Versorgungsdienste und Datenstrukturen
  8. Semaphoren:Einführung und grundlegende Dienste
  9. Ereigniskennzeichengruppen:Versorgungsdienste und Datenstrukturen
  10. Ereignisflaggengruppen:Einführung und grundlegende Dienste