Code-Analyse, Scheduling, Security Werkzeuge für smarte IoT-Entwickler

Code-Analyse im Live-System

Sowohl die resultierende Komplexität als auch die zunehmende Cyber-Kriminalität macht es unabdinglich, die Test- und Verifikationsverfahren der ver­wendeten Firmware zu überdenken. Traditionell sind Code-Analysen wie Code Coverage und Code Profiling wichtige Bestandteile der Qualitätsanalyse (Bild 1). Allerdings werden diese überwiegend in simulierten Umgebungen durchgeführt. Spätestens bei der Verwendung von IP-Protokollen, USB- und Sicherheitsprotokollen stößt die Simulation an Grenzen.

Die Code-Analyse für IoT-Geräte muss daher am Live-System durchgeführt werden können. Moderne Trace Probes wie der J-Trace Pro von Segger können dies leisten. Der J-Trace Pro kann beliebig lange Aufnahmen der Code-Ausführung bei voller Systemgeschwindigkeit erstellen, sodass eine Code-Analyse im Live-System möglich wird. Die Streaming-Trace-Daten werden live entweder über USB oder Gigabit-Ethernet an den Host-PC übertragen und lokal gespeichert. In Echtzeit wird die Analyse des Codes dargestellt. Schwachpunkte werden unmittelbar erkannt: Code, der nie oder nur teilweise ausgeführt wurde, wird direkt optisch sichtbar, genauso auch Schleifenzweige, die nie erreicht wurden. Der Code Profile Counter zählt, wie oft jede Programmzeile ausgeführt wurde. Dieser Zähler wird während der Programmausführung in Echtzeit aktualisiert.

Ein wichtiges Werkzeug zur Systemüberprüfung komplexer Systeme sind Event Tracing Tools wie SystemView Pro. Das Aufzeichnen von Events gibt dem Entwickler einen abstrakten aber sehr übersichtlichen Blick auf das, was in seinem System vor sich geht, und wie die verschiedenen Komponenten zusammenarbeiten (Bild 2). Insbesondere das Taskwechsel- und Interrupt-Verhalten sowie die API-Nutzung der eingesetzten Middleware lassen Rückschlüsse darauf zu, ob das System effizient und korrekt abläuft.

Eine nicht zu unterschätzende Herausforderung ist das Zusammenspiel der verschiedenen Komponenten. Oft wird aus verschiedenen Baukästen gemischt, um ein vollständiges System zu bauen. So werden Echtzeit-Betriebssystem, Security Stack, Middleware usw. von verschiedenen Herstellern oder aus dem Open-Source-Bereich übernommen oder sogar zum Teil selbst geschrieben. Das resultierende Risiko der Interoperabilität erhöht sich mit jeder neuen Quelle, die eine Komponente zum Gesamtsystem beisteuert. Dieses Risiko lässt sich dadurch minimieren, dass man bei der Beschaffung darauf achtet, möglichst mit einem Hersteller zusammenzuarbeiten, der die erforderlichen Komponenten aus einer Hand anbietet.

IoT Baukasten – Komplexität reduzieren

Während man selbstgeschriebene Programmteile vermeintlich unter voller Kontrolle hat, unterschätzen viele Entwickler den internen Support-Aufwand und die entstehende Abhängigkeit von einzelnen Mitarbeitern. Durch die Eigenentwicklung entsteht Code, der zwar für die Anwendung benötigt wird, nur eben nicht zur eigenen Kernkompetenz gehört. Die Mannjahre an Entwicklungsaufwendungen, die Hersteller von Standardsoftware-Komponenten bereits in solche Produkte gesteckt haben, lassen sich im eigenen Haus weder investieren noch kompensieren. Dennoch bleibt die Frage, welche Komponenten denn überhaupt als Standardsoftware erworben werden sollten? Die Antwort ist dabei recht einfach: Idealerweise alles, was verfügbar ist, denn damit lässt sich Entwicklungszeit produktiver einsetzen. Fachfremde Software zu schreiben, dauert immer länger, als sich in der eigenen Kernkompetenz zu bewegen. Zudem muss zu jedem Stück Software auch immer ein Test­verfahren entwickelt werden. Für die Standardsoftware-Komponenten hat dies der jeweilige Hersteller schon er­ledigt und durch die hohe Anzahl an Installationen ist die Software entsprechend Feld-erprobt.

Für komplexe Systeme wie IoT-Geräte benötigt man Scheduler, die die Vielzahl der Aufgaben verwalten können. Moderne Scheduler wie etwa embOS-MPU unterstützen dabei auch Mechanismen, die die einzelnen Tasks (privilegierte und nicht-privilegierte, Bild 3) voneinander abtrennen und schützen, so dass evtl. auftretende Fehler keine Auswirkungen auf das Gesamtsystem haben. Wichtig ist vor allem, dass die fehlerhaften Tasks isoliert gestoppt und neu gestartet werden können. Denkbar wäre, dass durch unvorhergesehene Bedienvorgänge, die durch die finalen Produkttests nicht abgedeckt waren, das Bedien-Interface einfriert. Die verbliebenen Systemfunktionen dürfen damit nicht außer Tritt geraten. Das betrifft die Kommunika­tion zur Außenwelt, die Messdatenerfassung oder vorhandene Steuerungsaufgaben. Das Benutzerinterface wird einfach zurückgesetzt und neu gestartet, mit dem Ergebnis, dass das Gesamtsystem seinen Dienst ohne Beeinträchtigung weiter ausführen kann.