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

Semaphoren:Einführung und grundlegende Dienste


RTOS Revealed-Serie anzeigen

Semaphoren wurden in einem früheren Artikel eingeführt. Ihre primäre Verwendung ist die Kontrolle des Zugriffs auf Ressourcen.

Verwendung von Semaphoren

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

Ein Semaphor ist einfach ein Zähler vom Typ U8 , deren Zugriff kontrolliert wird, damit er von mehreren Aufgaben sicher genutzt werden kann. Eine Task kann ein Semaphor dekrementieren (erhalten) und inkrementieren (freigeben). Der Versuch, ein Semaphor mit dem Wert Null abzurufen, 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.

Semaphoren konfigurieren

Anzahl Semaphoren

Wie bei den meisten Aspekten von Nucleus SE wird die Konfiguration von Semaphoren hauptsächlich durch #define . gesteuert Anweisungen in nuse_config.h . Die Schlüsseleinstellung ist NUSE_SEMAPHORE_NUMBER , die bestimmt, wie viele Semaphoren für die Anwendung konfiguriert sind. Die Standardeinstellung ist 0 (dh es werden keine Semaphoren 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 #Fehler führt Anweisung wird zusammengestellt.

Die Wahl eines Werts ungleich Null ist die „Masterfreigabe“ für Semaphoren. Dies führt dazu, dass einige Datenstrukturen entsprechend definiert und dimensioniert werden, von denen später in diesem Artikel mehr. Es aktiviert auch die API-Aktivierungseinstellungen.

API aktiviert

Jede API-Funktion (Dienstaufruf) in Nucleus SE hat ein aktivierendes #define Symbol in nuse_config.h . Bei Semaphoren sind dies:

NUSE_SEMAPHORE_OBTAIN
NUSE_SEMAPHORE_RELEASE
NUSE_SEMAPHORE_RESET
NUSE_SEMAPHORE_INFORMATION
NUSE_SEMAPHORE_COUNT

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

#define NUSE_SEMAPHORE_NUMBER 0 /* Anzahl der Semaphoren im System - 0-16 */#define NUSE_SEMAPHORE_OBTAIN FALSE /* Service Call Enabler */#define NUSE_SEMAPHORE_RELEASE FALSE /* Service Call Enabler */#define NUSE_SEMAPHORE /* Service RESET FALS Call Enabler */#define NUSE_SEMAPHORE_INFORMATION FALSE /* Service Call Enabler */#define NUSE_SEMAPHORE_COUNT FALSE /* Service Call Enabler */

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

Semaphore Service Calls

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

  • Besorgen Sie sich einen Semaphor. Implementiert von NUSE_Semaphore_Obtain() in Nucleus SE.

  • Geben Sie ein Semaphor frei. Implementiert von NUSE_Semaphore_Release() in Nucleus SE.

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

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

  • Gibt einen Zähler zurück, wie viele Semaphoren (derzeit) für die Anwendung konfiguriert sind. Implementiert von NUSE_Semaphore_Count() in Nucleus SE.

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

  • Entferne einen Semaphor aus der Anwendung (delete). Nicht in Nucleus SE implementiert.

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

Die Implementierung jedes dieser Service Calls wird im Detail untersucht.

Semaphore Abrufen und Freigeben von Diensten

Die grundlegenden Operationen, die an einem Semaphor ausgeführt werden können, sind das Erhalten (Dekrementieren) und Freigeben (Inkrementieren). Nucleus RTOS und Nucleus SE bieten jeweils zwei grundlegende API-Aufrufe für diese Operationen, die hier besprochen werden.

Anfordern eines Semaphors

Der Nucleus RTOS API-Aufruf zum Abrufen eines Semaphors 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, ein Semaphor zu erhalten, das aktuell den Wert Null hat. Nucleus SE bietet den gleichen Service, außer dass das Aussetzen von Aufgaben optional ist und das Timeout nicht implementiert ist.

Nucleus RTOS API-Aufruf zum Abrufen eines Semaphors

Prototyp für Serviceruf:

STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *Semaphore,
                           UNSIGNED suspend);

Parameter:

Semaphor – Zeiger auf den vom Benutzer bereitgestellten Semaphor-Steuerblock

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_NICHT VERFÜGBAR – der Semaphor hatte den Wert Null

NU_INVALID_SEMAPHORE – der Semaphorzeiger ist ungültig

NU_INVALID_SUSPEND – Aussetzen wurde von einer Nicht-Aufgabe versucht

NU_SEMAPHORE_WAS_RESET – der Semaphor wurde zurückgesetzt, während die Aufgabe angehalten wurde

Nucleus SE API-Aufruf zum Abrufen eines Semaphors

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

Prototyp für Serviceruf:

STATUS NUSE_Semaphore_Obtain(NUSE_SEMAPHORE Semaphor,
                             U8 suspendieren);

Parameter:

Semaphor – der Index (ID) des zu verwendenden Semaphors

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

Rückgabe:

NUSE_SUCCESS – der Anruf wurde erfolgreich abgeschlossen

NUSE_UNVERFÜGBAR – der Semaphor hatte den Wert Null

NUSE_INVALID_SEMAPHORE – der Semaphor-Index ist ungültig

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

NUSE_SEMAPHORE_WAS_RESET – der Semaphor wurde zurückgesetzt, während die Aufgabe angehalten wurde

Nucleus SE-Implementierung von Obtain Semaphore

Der Großteil des Codes von NUSE_Semaphore_Obtain() 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:

if (NUSE_Semaphore_Counter[Semaphore] !=0) /* Semaphore verfügbar */{ NUSE_Semaphore_Counter[Semaphore]--; return_value =NUSE_SUCCESS;}else /* Semaphor nicht verfügbar */{ return_value =NUSE_UNAVAILABLE;}

Der Semaphorwert wird getestet und, wenn er nicht null ist, dekrementiert.

Wenn die Blockierung aktiviert ist, wird die Logik komplexer:

do{ if (NUSE_Semaphore_Counter[Semaphore] !=0) /* Semaphore verfügbar */ { NUSE_Semaphore_Counter[Semaphore]--; Rückgabewert =NUSE_SUCCESS; aussetzen =NUSE_NO_SUSPEND; } else /* Semaphor nicht verfügbar */ { if (suspend ==NUSE_NO_SUSPEND) { return_value =NUSE_UNAVAILABLE; } else { /* Aufgabe blockieren */ NUSE_Semaphore_Blocking_Count[Semaphore]++; NUSE_Suspend_Task(NUSE_Task_Active, Semaphor <<4) | NUSE_SEMAPHORE_SUSPEND); return_value =NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value !=NUSE_SUCCESS) { suspend =NUSE_NO_SUSPEND; } } }} while (suspend ==NUSE_SUSPEND);

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 hat den Wert NUSE_SUSPEND .

Wenn der Semaphor nicht null ist, wird er dekrementiert. Die Aussetzung Variable ist auf NUSE_NO_SUSPEND eingestellt und der API-Aufruf wird mit NUSE_SUCCESS beendet .

Wenn der Semaphor null ist und aussetzen ist auf NUSE_NO_SUSPEND eingestellt , der API-Aufruf endet mit NUSE_UNAVAILBLE . 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 anzeigt, dass die Aufgabe aufgeweckt wurde, weil der Semaphor freigegeben wurde (im Gegensatz zum Zurücksetzen des Semaphors), wird der Code zurück nach oben gedreht.

Freigeben eines Semaphors

Der Aufruf der Nucleus RTOS API zum Freigeben eines Semaphors ist recht einfach; das Semaphor wird inkrementiert und der Erfolg wird gemeldet. Nucleus SE bietet denselben Service, außer dass eine Überlaufprüfung durchgeführt wird.

Nucleus RTOS API-Aufruf zur Freigabe eines Semaphors

Prototyp für Serviceruf:

STATUS NU_Release_Semaphore(NU_SEMAPHORE *Semaphore);

Parameter:

Semaphor – Zeiger auf den vom Benutzer bereitgestellten Semaphor-Steuerblock

Rückgabe:

NU_SUCCESS – der Anruf wurde erfolgreich abgeschlossen

NU_INVALID_SEMAPHORE – der Semaphorzeiger ist ungültig

Nucleus SE API-Aufruf zur Freigabe eines Semaphors

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

Prototyp für Serviceruf:

STATUS NUSE_Semaphore_Release(NUSE_SEMAPHORE-Semaphor);

Parameter:

Semaphor – der Index (ID) des freizugebenden Semaphors

Rückgabe:

NUSE_SUCCESS – der Anruf wurde erfolgreich abgeschlossen

NUSE_INVALID_SEMAPHORE – der Semaphor-Index ist ungültig

NUSE_UNVERFÜGBAR – das Semaphor hat den Wert 255 und kann nicht erhöht werden

Nucleus SE-Implementierung von Release Semaphore

Der Anfangscode von NUSE_Semaphore_Release() API-Funktion – nach Parameterprüfung – ist üblich, unabhängig davon, ob die Aufgabenblockierung aktiviert ist oder nicht. Der Wert des Semaphors wird überprüft und, wenn er kleiner als 255 ist, dekrementiert.

Weiterer Code wird durch bedingte Kompilierung ausgewählt, wenn die Unterstützung für das Blockieren (Task Suspend) API-Aufrufe aktiviert ist:

NUSE_CS_Enter(); wenn (NUSE_Semaphore_Counter[Semaphore] <255){ NUSE_Semaphore_Counter[Semaphore]++; Rückgabewert =NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count[Semaphore] !=0) { U8 index; /* prüfen, ob eine Aufgabe blockiert ist */ /* auf diesem Semaphor */ NUSE_Semaphore_Blocking_Count[Semaphore]--; for (index=0; index 

Wenn Aufgaben an diesem Semaphor angehalten werden, wird der erste geweckt.

Im nächsten Artikel werden einige zusätzliche API-Aufrufe im Zusammenhang mit Ereignis-Flag-Gruppen zusammen mit den relevanten Datenstrukturen behandelt.


Colin Walls hat über dreißig Jahre Erfahrung in der Elektronikindustrie und widmet sich hauptsächlich eingebetteter Software. Als regelmäßiger Referent auf Konferenzen und Seminaren und Autor zahlreicher technischer Artikel und zweier Bücher über eingebettete Software ist Colin ein Embedded-Software-Technologe bei Mentor Embedded [der Mentor Graphics Embedded Software Division] mit Sitz in Großbritannien. Sein regelmäßiger Blog befindet sich unter:http://blogs.mentor.com/colinwalls. Er kann per E-Mail unter [email protected] erreicht werden


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 Edelstahl und seine Herstellung
  4. C# Grundlegende Ein- und Ausgabe
  5. Was ist ein Autoservice-Autor und was macht er?
  6. Postfächer:Einführung und grundlegende Dienste
  7. Semaphoren:Versorgungsdienste und Datenstrukturen
  8. Ereigniskennzeichengruppen:Versorgungsdienste und Datenstrukturen
  9. Ereignisflaggengruppen:Einführung und grundlegende Dienste
  10. Warteschlangen:Einführung und grundlegende Dienste