»Co-Design« bezeichnet die parallele Entwicklung von Software und Hardware. Sie kann ein Traum für jeden Manager sein, der Projekte hypereffizient planen möchte. Für Softwareentwickler dagegen kann sie zum Albtraum werden, da sich die Hardware kurzfristig ändern kann und der Entwickler gezwungen ist, zu reagieren. Wie lässt sich dieses Problem entschärfen?
Um dem Problem, dass sich das Hardware-Design während der Entwicklung der Software ändert, zu begegnen, müssen Hardware-Tools besser in Software-IDEs eingebunden werden, um damit unter anderem auch die Time-to-Market zu verkürzen. Hierzu benötigen Entwickler mehr Tools und Methoden, um die Anwendung von Hardware-Änderungen zu isolieren. Damit ist nicht gemeint, dass dem Design größere Kommunikationsblöcke hinzugefügt beziehungsweise diese aus dem Design entfernt werden, sondern dass stattdessen zu einem späten Zeitpunkt in der Designphase kleinere Änderungen an definierten Funktionsblöcken vorgenommen werden. Diese »kleineren« Änderungen wirken sich auf die Software aus, was zu Produktfehlern und letztendlich zu Mehrarbeit führen kann.
Nachfolgend werden drei Ideen besprochen, wie sich Anwendungen für sich verändernde Zielsysteme anders entwickeln lassen:
Die erste erforderliche Änderung ist, dass das Hardware-Entwicklungstool eine Softwareschnittstelle - oft als Hardwareabstraktionsschicht (HAL) bezeichnet - generiert. Die HAL sollte Boot-Code enthalten, der die programmierbare Hardware zuverlässig initialisiert und APIs bereitstellt, um die Software des Systems zu steuern (Bild 1). Die HAL vereinfacht nicht nur die Entwicklung von Firmware, sondern abstrahiert auch die Implementierung von der Schnittstelle weg. Hierdurch lassen sich kleinere Änderungen an der Hardware implementieren, ohne die Firmware zu beeinflussen.
Neu ist das Konzept einer HAL nicht. Viele erfahrene Entwickler haben über die Notwendigkeit einheitlicher und intuitiver Namenskonventionen für Konstanten, Funktionen und Variablen geschrieben. Für programmierbare Bausteine wie FPGAs, CPLDs und PSoCs sollten diese Anforderungen jedoch um die Notwendigkeit erweitert werden, dass das Hardware-Designwerkzeug die HAL generiert, damit Softwareentwickler eine garantiert zuverlässige Schnittstelle erhalten.
In einer statischen oder sich nur langsam verändernden Umgebung, wie zum Beispiel bei einem Mikrocontroller mit fester Funktion oder ei-nem großen ASIC-Projekt, ließe sich die HAL auch als eine unabhängige API-Suite betrachten und im Rahmen einer Hardware-Designänderung modifizieren. Bei modernen programmierbaren Bausteinen kann sich die Hardware jedoch mehrere Male pro Tag ändern. Eine manuelle HAL-Pflege ist daher mit dieser Methodik inkompatibel und würde garantiert zu Fehlern in der Implementierung führen. Stattdessen sollte die automatische Generierung der HAL eine grundsätzliche Anforderung für jede programmierbare Plattform sein.
Einbinden in die IDE
Programmierbare Bausteine bieten Gelegenheiten für Innovation, aber die für die Entwicklung der Hardware benötigten Werkzeuge wirken sich oftmals störend auf die Entwicklungspraktiken für die Software aus. So müssen Entwickler Tools verwenden, die stark vereinfacht sind, nicht genügend Funktionen haben und sich nicht gut in bestehende Abläufe einbinden lassen. Meist haben sich Co-Entwicklungsumgebungen aus den Hardware-Designwerkzeugen entwickelt, die seit Jahren ASIC-, FPGA- und CPLD-Abläufe unterstützen.
Da eingebettete CPUs heute weit verbreitet sind, ist der Bedarf offensichtlich, Softwareentwicklung zum Tool-Portfolio hinzuzufügen. Das Ergebnis ist ein Werkzeug, das zwar zwei Disziplinen unterstützt, aber für keine ideal ist. Entwickler verlieren hierdurch nicht nur Funktionen, sondern werden auch in ihrer Auswahl eingeschränkt. Der richtige Ansatz ist daher, Debugger, Editoren beziehungsweise komplette IDEs (Integrated Development Environment) NICHT zu integrieren. Stattdessen ist es am besten, von Beginn des Projekts an einfach eine Entwicklung in traditionellen IDEs zu ermöglichen.
Hardwareentwickler benötigen zwar vielleicht noch Softwarefunktionen in ihrem Tool, um kleine Testprogramme zu erstellen und auszuführen, aber die echte Anwendungsentwicklung sollte immer in der vom Entwickler gewählten IDE möglich sein. Eine mögliche Lösung für dieses Szenario ist, ein Projekt von einem Werkzeug in ein anderes zu exportieren. Der »PSoC Creator« von Cypress kann beispielsweise PSoC-Designs direkt in das Tool »Keil µVision« exportieren (Bild 2).
In vielen programmierbaren Systemen wird die »Hardware« als ein Datenblock bereitgestellt, der zur Boot-Zeit in das Gerät programmiert wird, um das konfigurierte Gerät zu erstellen. Für Software sind das nur Daten; für den Export des Designs muss das Hardware-Tool folglich nur eine Projektdatei für das Zielprodukt generieren und sie mit den HAL-Quelldateien und Initialisierungscode bestücken.
Die Anwendung lässt sich dann auf der Hardware aufbauen, ohne die a
Bei IDEs, die Bibliotheken unterstützen, ist der Aktualisierungsprozess einfach, da sich das Design in ein Anwendungsprojekt und in eine Konfigurationsbibliothek unterteilen lässt (Bild 3). Hierdurch wird die Anwendung komplett isoliert, und die Hardwarebibliothek, welche die Konfigurationsdaten und die HAL enthält, lässt sich jederzeit aktualisieren, wenn sich das Design ändert.
Mehr als nur die Software debuggen
Die dritte Funktion, die Entwickler brauchen, ist ein verbessertes Debugging. CPU-Chips enthalten alle möglichen zusätzlichen Funktionen, zum Beispiel Kommunikationsblöcke, Standardschnittstellen, allgemeine Timer und Zähler, analoge Funktionen mit digitalen Schnittstellen für Software und manchmal benutzerdefinierte Logik und schaltbares Routing. Diese Anpassung (customization) ist in der Regel der Hauptgrund für ein Co-Design, und ein Debugger, der nur die CPU unterstützt, nützt dem Softwareentwickler nicht viel. Es muss möglich sein, die Hardware testen zu können, um Fragen zu beantworten wie: Bootet sie?
Startet die CPU-Clock und schwingt sie sich ein? Funktionieren Peripheriegeräte und generieren die Kommunikationsblöcke Interrupts? Senden und empfangen sie Daten und funktionieren sie richtig auf internen Bussen? Letztendlich ist also nur ein symbolbasierter Zugang zu peripherer Hardware gefordert, um Statusänderungen, die sich auf eine Anwendung auswirken, überwachen und steuern zu können. Die symbolischen Informationen muss wie bei der HAL das Hardware-Tool generieren. Durch diese einfache Zusatzfunktion vereinfacht sich der Debugging-Prozess, da keine konstante Dokumentation beziehungsweise keine Kontrollen zur Überprüfung von Adressen wichtiger Register notwendig sind, um sie im Debugger anzuzeigen.
Auch der Prozess wird leistungsfähiger, weil er ein ausgefeilteres Debugging ermöglicht. Zudem ist es nicht nur möglich, schnell eine Momentaufnahme vom Status von Peripherieblöcken zu erhalten, sondern der Debugger kann manchmal auch den Block steuern, wodurch sich Szenarien durchspielen lassen, ohne Code zu schreiben, um die Situation per Software nachzubilden. Die typische Methode für den Austausch dieser Informationen ist eine XML-Datei, die vom Hardware-Tool generiert und von der IDE verarbeitet wird.
Ein sehr gutes Beispiel hierfür ist der »ARM CMSIS-SVD«-Standard (Software Interface Standard - System View Description), eine XML-basierte Hardwarebeschreibung, die ein Debugging hoch integrierter Mi-krocontroller ermöglicht. CMSIS ist eine Standarddefinition einer HAL für »Cortex«-basierte Mikrocontrol-ler, die von vielen Anbietern angenommen wurde. Die Erweiterung SVD konzentriert sich auf die Hardwarebeschreibung, beispielsweise Register, Speicher, und Peripherie-geräte (Bild 4).