EDA-Tools

Software-Entwicklung aus der Vogelperspektive

31. Mai 2011, 17:21 Uhr | Von Ulrich Kloidt
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

Der Software-Platform-Builder

Die Software beinhaltet verschiedene IP-Peripherie-Cores, die in einer Embedded-Applikation eingesetzt werden können. Für eine möglichst bedienfreundliche Konfiguration und Bedienung dieser Peripherie steht ein Software-Framework namens Software-Platform-Builder zur Verfügung.

Der Nutzen für den Anwender besteht darin, dass er die Low-Level-Treiber für die Periphere nicht mehr selber schreiben muss, sondern auf fertige Bibliotheksfunktionen zugreifen kann, die im C-Quellcode vorliegen. Das erspart ihm, sich zeitaufwendig mit der internen Arbeitsweise der Peripherie, deren SFR-Registern, einem Kommunikationsprotokoll sowie der Interrupt-Nutzung zu befassen. Die Peripherie selbst wird über entsprechende Parameter-Einträge in dem Software-Platform-Builder-Dokument bzw. über den Aufruf der dazu vorhanden C-Bibliotheksfunktionen konfiguriert.

Da die Peripheriecontroller über „memory mapped I/O“ angesprochen werden, ist ein automatischer Import der Konfiguration aus dem FPGA-Projekt heraus möglich; und zwar mit der Absicht, die Software-Platform-Builder-Konfiguration jederzeit per Knopfdruck aktualisieren zu können. Das ist erforderlich, wenn sich z.B. das Speicher-Mapping geändert hat oder die Anzahl der Steuerleitungen angepasst werden muss. Letzteres ist dann vonnöten, wenn anstatt eines I/O-Ports nun vier I/O-Ports adressiert werden müssen und somit zwei zusätzliche Adressleitungen erforderlich sind.

Automatisch erzeugte C-Makros
Listing 1. Automatisch erzeugte C-Makros
© Altium

Der Software-Platform-Builder besteht aus drei Ebenen: Die unterste Ebene, die so genannte Hardware-Wrapper-Ebene, bietet Zugriff auf Basisfunktionen wie die Startadresse der Peripherie im „memory mapped“-Speicher oder die Interrupt-Zuweisung. Diese Ebene wird normalerweise nur von den übergeordneten Treibern angesprochen, nicht jedoch direkt aus der Applikation. Bei einem einfachen Zugriff auf einen I/O-Port kann jedoch auch diese Funktion genutzt werden. Hier stellt der Hardware-Wrapper dann automatisch erzeugte C-Makros zur Verfügung (Listing 1).

Die nächste Ebene ist die Treiber-Ebene: Ein Treiber benutzt die Hardware-Wrapper oder andere Treiber beim Zugriff auf die Peripherie. Der Unterschied zwischen dem Hardware-Wrapper und dem Treiber ist, dass der Hardware-Wrapper lediglich Basisinformationen zu der Peripherie liefert, aber keine weiteren Funktionen. Diese Informationen können dann vom übergeordneten Treiber benutzt werden.

Jeder Treiber hat seinen zugehörigen Hardware-Wrapper. Wird von einer Applikation heraus direkt über das API auf die Treiber zugegriffen, bleibt diese allerdings hardware-abhängig, da beim Wechsel der Peripherie auch die Treiber gewechselt werden müssen.

Die nächste Ebene ist die Treiber-Ebene: Ein Treiber benutzt die Hardware-Wrapper oder andere Treiber beim Zugriff auf die Peripherie. Der Unterschied zwischen dem Hardware-Wrapper und dem Treiber ist, dass der Hardware-Wrapper lediglich Basisinformationen zu der Peripherie liefert, aber keine weiteren Funktionen. Diese Informationen können dann vom übergeordneten Treiber benutzt werden.

 PS/2- oder USB-Maus-Anschluss?
Bild 3. PS/2- oder USB-Maus-Anschluss, das ist hier die Frage.
© Altium

Jeder Treiber hat seinen zugehörigen Hardware-Wrapper. Wird von einer Applikation heraus direkt über das API auf die Treiber zugegriffen, bleibt diese allerdings hardware-abhängig, da beim Wechsel der Peripherie auch die Treiber gewechselt werden müssen.

Die oberste Ebene ist die Context-Ebene: Diese Ebene bietet einen standardisierten, hardware-unabhängigen Zugriff auf die Peripherie. Werden Funktionen der Context-Ebene benutzt, so bleibt die Applikation portabel. Wird beispielsweise ein generischer Maustreiber benutzt, so ändert  sich der Applikations-Code nicht, wenn z.B. von einer PS/2- auf eine USB-Maus gewechselt wird. Hier werden dann einfach die untergeordneten Treiber durch die Software-Plattform ausgetauscht (Bild 3).

Zu den in der Entwurfsumgebung „Altium Designer“ unterstützten Treiber-Diensten gehören unter anderem:

  • Treiber für SD-Card, IDE, Compact-Flash- und Flash-Speicher,
  • Treiber für die Ethernet-Nutzung,
  • Kernel-Dienste für ein POSIX-kompatibles Multithreading,
  • GUI-Dienste zur Erstellung gra-fischer Schnittstellen,
  • Multimedia-Dienste für Audio- und Video-Funktionen.

Zusätzlich zu den drei Ebenen gibt es noch die Software-Services, die z.B. Funktionen, C-Präprozessor-Makros und C-Strukturen liefern, die nicht unmittelbar mit der Peripherie zu tun haben. Es stehen POSIX-Device-I/O-Dienste zur Verfügung, die einen Zugriff auf die nicht standardisierte I/O-Peripherie über standardisierte POSIX-I/O-Befehle ermöglichen.

Funktion der PS/2-Keyboard-Treiber

Was bei der vorhin gezeigten I/O-Port-Ansteuerung noch trivial ist, ändert sich schlagartig, wenn z.B. die Tastatureingaben eines PS/2-Keyboards eingelesen werden sollen. Hier werden auf der Hardware-Wrapper-Ebene wiederum die Basisadresse der Peripherie sowie die Adressen zum Zugriff auf die Takt- und Datenleitung definiert. Auf der ersten Treiber-Ebene wird der Keyboard-Interrupt bedient, welcher anzeigt, wann neue Daten anliegen, und diese Daten werden dann über die Datenleitung eingelesen. Zu den C-Bibliotheksfunktionen des Software-Platform-Builders, die auf dieser Ebene verfügbar sind, gehören z.B.

  • „ps2_putchar“, „ps2_getchar“, um ein einzelnes Byte an den PS/2-Puffer zu senden bzw. daraus auszulesen, oder auch
  • „ps2_available_bytes“ und „ps2_check_buffer_full“, um die Anzahl der verfügbaren Bytes im Puffer zu prüfen bzw. festzustellen, ob der PS/2-Puffer voll ist.
Elemente des PS/2-Keyboard-Stacks
Bild 4. Elemente des PS/2-Keyboard-Stacks.
© Altium

Das Keyboard sendet die Daten über einen Scancode, der aus 11 bit breiten Daten-Frames besteht, womit jeweils ein Byte übermittelt wird. Diese Daten werden auf der zweiten Treiber-Ebene ausgewertet. Wird z.B. ein 0xC1 empfangen, so bedeutet dies, dass die „A“-Taste gedrückt wurde. Zu den Funktionen der zweiten Treiber-Ebene gehören unter anderem „ps2kb_get_scancode“ oder „ps2kb_setleds“, um den kompletten Scancode statt der einzelnen Bytes einzulesen oder den Status der Keyboard-LEDs zu ändern.

Die Context-Ebene interpretiert und puffert diese Daten und zeigt dann direkt den empfangenen Buchstaben „A“ an. Hier sind dann die standardisierten POSIX-I/O-Befehle nutzbar (Bild 4).


  1. Software-Entwicklung aus der Vogelperspektive
  2. Der Software-Platform-Builder
  3. Praktische Umsetzung des Embedded-Projekts

Lesen Sie mehr zum Thema


Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu ALTIUM EUROPE GmbH