Suchen

Software-Tipp: Weitere Programmiertechniken zu C++ mit einem RTOS

| Autor / Redakteur: Colin Walls * / Sebastian Gerstl

Im letzten C++ Tipp haben wir eine interessante Technik für Embedded-Anwendungen geschildert, die einen Embedded-Block mit einem lokalen Objekt verwendete, in dem der zugehörige Konstruktor und Destruktor auf neuartige Weise eingesetzt wurde. Dies kann sich aber auch drastisch auf das Verhalten eines Echtzeitsystems auswirken. Hier einige nähere Details.

Firmen zum Thema

Die möglichkeit zur Klassenerstellung in C++ eröffnet eine Reihe von potentiellen Anwendungsmöglichkeiten in Echtzeitsystemen - wenn dabei einige wichtige Aspekte im Auge behalten werden.
Die möglichkeit zur Klassenerstellung in C++ eröffnet eine Reihe von potentiellen Anwendungsmöglichkeiten in Echtzeitsystemen - wenn dabei einige wichtige Aspekte im Auge behalten werden.
(Bild: gemeinfrei / CC0 )

Wie im letzten Software-Tipp beschrieben eröffnet C++ eine neue Möglichkeit zur Interaktion mit einem RTOS, die auf komplexe API-Aufrufe verzichten kann. Der zuvor beschriebene Ansatz, Interrupts aus- und wieder einzuschalten, sollte allerdings sparsam und mit großer Sorgfalt angewendet werden. Denn er kann sich drastisch auf das Verhalten und die Performance eines Echtzeitsystems auswirken.

In einem Multi-Threaded-(Multitasking-)System hat man üblicherweise eine Ressource – meist eine Hardwarekomponente –, die zu einem bestimmten Zeitpunkt nur von einer Task sinnvoll genutzt werden kann. Wenn es zum Beispiel eine textuelle Darstellung gibt, kann es sein, dass eine Task ausschließlich für die Ausgabe von Informationen verwendet wird. Versuchen zwei Tasks gleichzeitig auf die Hardwarekomponente zuzugreifen, würde deren Text durcheinandergeraten. Das übliche RTOS-Objekt, das zur Steuerung des Zugriffs auf eine Hardwarekomponente verwendet wird, ist eine binäre Semaphore. Wir könnten eine Klasse wie diese erstellen:

class Grab_Console
{
private:
   static Semaphore console_lock;
public:
   Grab_Console()
   {
      console_lock.obtain();
   };
   ~Grab_Console()
   {
      console_lock.release();
   };
};

Ein paar Dinge gilt es dabei zu beachten:

  • Es wird davon ausgegangen, dass eine Klasse Semaphore verfügbar ist. Diese verwendet die API des RTOS zum Erstellen und Verwalten einer binären Semaphore.
  • Diese Klasse hat als obtain() und release() bezeichnete Member-Funktionen (Methoden), die die Funktionalität bereitstellen.
  • Das Semaphore-Objekt console_lock wird als statisch deklariert, so dass eine einzige Instanz, die von Grab_Console instanziiert wurde, gemeinsam von allen Objekten genutzt wird.

Eine Task mit „Hello World“ könnte nun folgendermaßen kodiert werden:

...

{
   Grab_Console now;

   printf("Hello World!\n");
}

...

Offensichtlich gibt es für diesen Ansatz zahlreiche Anwendungsmöglichkeiten.

Nach meinem letzten Beitrag wurde mir mitgeteilt, dass dieser Ansatz besonders gut mit der Ausnahmebehandlung von C++ kompatibel ist. Obwohl die Ausnahmebehandlung aufgrund des zusätzlichen Overheads selten in Embedded-Anwendungen zum Einsatz kommt, können Sie sicher sein, dass der Destruktor trotzdem ausgeführt wird, wenn der „geschützte“ Code eine Ausnahme auslöst. Man könnte es auch als „EHS-sicher“ bezeichnen.

Der Autor

* Colin Walls verfügt über fast 40 Jahre Erfahrung in der Elektronikindustrie, hauptsächlich im Bereich Embedded Software. Er ist Embedded-Software-Technologist bei Mentor, a Siemens business, mit Sitz in Großbritannien. Walls hält regelmäßig Vorträge auf Konferenzen und Seminaren. Zudem ist er Autor zahlreicher Fachartikel sowie zweier Bücher über Embedded Software und betreibt ein Blog auf http://blogs.mentor.com/colinwalls.

(ID:45197453)